|
| 1 | +import React from 'react'; |
| 2 | +import { Card } from './ui/Card'; |
| 3 | +import { Database, Server, Globe, Shield, Layers, Workflow } from 'lucide-react'; |
| 4 | + |
| 5 | +export const Architecture: React.FC = () => { |
| 6 | + return ( |
| 7 | + <div className="space-y-6 animate-[fadeIn_0.5s_ease-out]"> |
| 8 | + <div className="mb-8"> |
| 9 | + <h2 className="text-2xl font-bold text-white">System Architecture</h2> |
| 10 | + <p className="text-slate-400">Visualizing the KubeBrowse internal Kubernetes flow and isolation layers.</p> |
| 11 | + </div> |
| 12 | + |
| 13 | + {/* Interactive-looking Diagram */} |
| 14 | + <div className="bg-slate-900 border border-slate-800 rounded-xl p-8 relative overflow-hidden"> |
| 15 | + <div className="absolute inset-0 bg-[linear-gradient(to_right,#1e293b_1px,transparent_1px),linear-gradient(to_bottom,#1e293b_1px,transparent_1px)] bg-[size:24px_24px] opacity-20"></div> |
| 16 | + |
| 17 | + <div className="relative z-10 flex flex-col items-center space-y-12"> |
| 18 | + |
| 19 | + {/* User Layer */} |
| 20 | + <div className="flex flex-col items-center"> |
| 21 | + <div className="p-4 bg-indigo-600 rounded-full shadow-lg shadow-indigo-500/30 mb-2"> |
| 22 | + <Globe size={32} className="text-white" /> |
| 23 | + </div> |
| 24 | + <span className="text-slate-300 font-medium">User (Client)</span> |
| 25 | + </div> |
| 26 | + |
| 27 | + {/* Ingress/Frontend Layer */} |
| 28 | + <div className="w-full max-w-4xl grid grid-cols-3 gap-8 relative"> |
| 29 | + {/* Connecting lines */} |
| 30 | + <div className="absolute top-[-48px] left-1/2 w-px h-12 bg-gradient-to-b from-indigo-600 to-slate-600 -translate-x-1/2"></div> |
| 31 | + |
| 32 | + <Node |
| 33 | + title="Frontend Service" |
| 34 | + icon={<Layers size={20} />} |
| 35 | + desc="React UI + WebSocket Handler" |
| 36 | + color="bg-blue-500" |
| 37 | + /> |
| 38 | + |
| 39 | + <Node |
| 40 | + title="API Gateway" |
| 41 | + icon={<Server size={20} />} |
| 42 | + desc="Go-based REST API" |
| 43 | + color="bg-purple-500" |
| 44 | + /> |
| 45 | + |
| 46 | + <Node |
| 47 | + title="Auth & Session" |
| 48 | + icon={<Database size={20} />} |
| 49 | + desc="Redis + Postgres" |
| 50 | + color="bg-cyan-500" |
| 51 | + /> |
| 52 | + </div> |
| 53 | + |
| 54 | + {/* Isolation Layer */} |
| 55 | + <div className="w-full max-w-5xl border-2 border-dashed border-slate-700 rounded-3xl p-8 bg-slate-900/80 relative"> |
| 56 | + <span className="absolute -top-3 left-8 bg-slate-900 px-2 text-slate-400 text-sm font-mono">KUBERNETES CLUSTER - WORKER NODES</span> |
| 57 | + |
| 58 | + <div className="grid grid-cols-2 gap-12"> |
| 59 | + <div className="space-y-4"> |
| 60 | + <div className="flex items-center justify-center mb-4"> |
| 61 | + <span className="px-3 py-1 rounded-full bg-slate-800 text-slate-300 text-xs border border-slate-700">Guacamole Protocol (RDP/VNC)</span> |
| 62 | + </div> |
| 63 | + <div className="p-6 bg-slate-800 border border-slate-700 rounded-xl"> |
| 64 | + <div className="flex items-center gap-3 mb-4"> |
| 65 | + <div className="p-2 bg-orange-500/20 text-orange-400 rounded-lg"><Workflow size={20} /></div> |
| 66 | + <h4 className="font-bold text-white">Guacd Pod</h4> |
| 67 | + </div> |
| 68 | + <p className="text-xs text-slate-400">Translates RDP traffic to HTML5 for the frontend. Handles TCP connections.</p> |
| 69 | + </div> |
| 70 | + </div> |
| 71 | + |
| 72 | + <div className="space-y-4"> |
| 73 | + <div className="grid grid-cols-2 gap-4"> |
| 74 | + <BrowserPod id="1" region="US-East" /> |
| 75 | + <BrowserPod id="2" region="EU-West" /> |
| 76 | + </div> |
| 77 | + <p className="text-center text-xs text-slate-500 mt-2">Ephemeral Browser Pods (Chromium)</p> |
| 78 | + </div> |
| 79 | + </div> |
| 80 | + </div> |
| 81 | + </div> |
| 82 | + </div> |
| 83 | + |
| 84 | + {/* Tech Stack Details */} |
| 85 | + <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8"> |
| 86 | + <Card title="Orchestration"> |
| 87 | + <ul className="space-y-2 text-sm text-slate-400"> |
| 88 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-blue-500 rounded-full"/>Kubernetes v1.29</li> |
| 89 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-blue-500 rounded-full"/>Calico CNI (Network Policies)</li> |
| 90 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-blue-500 rounded-full"/>Horizontal Pod Autoscaler</li> |
| 91 | + </ul> |
| 92 | + </Card> |
| 93 | + <Card title="Security Core"> |
| 94 | + <ul className="space-y-2 text-sm text-slate-400"> |
| 95 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-emerald-500 rounded-full"/>Firejail Sandbox</li> |
| 96 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-emerald-500 rounded-full"/>ClamAV + VirusTotal</li> |
| 97 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-emerald-500 rounded-full"/>Zero Trust Microsegmentation</li> |
| 98 | + </ul> |
| 99 | + </Card> |
| 100 | + <Card title="Data Layer"> |
| 101 | + <ul className="space-y-2 text-sm text-slate-400"> |
| 102 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-purple-500 rounded-full"/>MinIO (Object Storage)</li> |
| 103 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-purple-500 rounded-full"/>Redis (Session State)</li> |
| 104 | + <li className="flex items-center gap-2"><div className="w-1.5 h-1.5 bg-purple-500 rounded-full"/>PostgreSQL (Audit Logs)</li> |
| 105 | + </ul> |
| 106 | + </Card> |
| 107 | + </div> |
| 108 | + </div> |
| 109 | + ); |
| 110 | +}; |
| 111 | + |
| 112 | +const Node = ({title, icon, desc, color}: {title: string, icon: any, desc: string, color: string}) => ( |
| 113 | + <div className="bg-slate-800 p-4 rounded-xl border border-slate-700 relative group hover:border-slate-500 transition-colors"> |
| 114 | + <div className={`absolute -top-3 -left-3 p-2 ${color.replace('bg-', 'bg-')}/20 ${color.replace('bg-', 'text-')} rounded-lg shadow-lg`}> |
| 115 | + {icon} |
| 116 | + </div> |
| 117 | + <h4 className="font-bold text-white mt-2 ml-2">{title}</h4> |
| 118 | + <p className="text-xs text-slate-400 mt-2">{desc}</p> |
| 119 | + </div> |
| 120 | +); |
| 121 | + |
| 122 | +const BrowserPod = ({id, region}: {id: string, region: string}) => ( |
| 123 | + <div className="bg-slate-800 p-3 rounded-lg border border-slate-700 flex flex-col gap-2 relative overflow-hidden"> |
| 124 | + <div className="absolute top-0 right-0 p-1 bg-slate-700 rounded-bl-lg"> |
| 125 | + <div className="w-2 h-2 bg-emerald-500 rounded-full animate-pulse"></div> |
| 126 | + </div> |
| 127 | + <Globe size={16} className="text-slate-400" /> |
| 128 | + <div> |
| 129 | + <div className="text-xs font-bold text-slate-200">Browser Pod #{id}</div> |
| 130 | + <div className="text-[10px] text-slate-500">{region}</div> |
| 131 | + </div> |
| 132 | + </div> |
| 133 | +); |
0 commit comments