134 lines
6.7 KiB
TypeScript
134 lines
6.7 KiB
TypeScript
type Cap = '✓' | '—'
|
|
|
|
interface Driver {
|
|
name: string
|
|
deviceType: string
|
|
facts: Cap
|
|
interfaces: Cap
|
|
lldp: Cap
|
|
vlans: Cap
|
|
ssids: Cap
|
|
health: Cap
|
|
docker: Cap
|
|
reboot: Cap
|
|
configPush: Cap
|
|
status: 'stable' | 'beta'
|
|
}
|
|
|
|
const DRIVERS: Driver[] = [
|
|
{ name: 'fritzbox', deviceType: 'AVM Fritz!Box routers', facts: '✓', interfaces: '✓', lldp: '—', vlans: '—', ssids: '✓', health: '—', docker: '—', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'procurve', deviceType: 'HP ProCurve / Aruba switches', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '✓', ssids: '—', health: '✓', docker: '—', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'linux', deviceType: 'Generic Linux servers', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '—', ssids: '—', health: '✓', docker: '✓', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'netgear', deviceType: 'Netgear switches', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '✓', ssids: '—', health: '—', docker: '—', reboot: '—', configPush: '—', status: 'beta' },
|
|
{ name: 'openmediavault', deviceType: 'OpenMediaVault NAS', facts: '✓', interfaces: '✓', lldp: '—', vlans: '—', ssids: '—', health: '✓', docker: '✓', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'openwrt', deviceType: 'OpenWRT access points', facts: '✓', interfaces: '✓', lldp: '—', vlans: '✓', ssids: '✓', health: '✓', docker: '—', reboot: '✓', configPush: '✓', status: 'stable' },
|
|
{ name: 'opnsense', deviceType: 'OPNsense firewalls', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '✓', ssids: '—', health: '✓', docker: '—', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'proxmox', deviceType: 'Proxmox VE hypervisors', facts: '✓', interfaces: '✓', lldp: '—', vlans: '—', ssids: '—', health: '✓', docker: '✓', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'sonos', deviceType: 'Sonos speakers', facts: '✓', interfaces: '—', lldp: '—', vlans: '—', ssids: '—', health: '—', docker: '—', reboot: '—', configPush: '—', status: 'beta' },
|
|
{ name: 'tplink_jetstream', deviceType: 'TP-Link Jetstream switches', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '✓', ssids: '—', health: '—', docker: '—', reboot: '✓', configPush: '—', status: 'stable' },
|
|
{ name: 'zyxel', deviceType: 'Zyxel switches', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '✓', ssids: '—', health: '—', docker: '—', reboot: '—', configPush: '—', status: 'beta' },
|
|
]
|
|
|
|
const NAPALM_BUILTIN = [
|
|
'Cisco IOS',
|
|
'Cisco IOS-XE',
|
|
'Cisco NX-OS',
|
|
'Arista EOS',
|
|
'Juniper JunOS',
|
|
]
|
|
|
|
const CAPS: { key: keyof Driver; label: string }[] = [
|
|
{ key: 'facts', label: 'Facts' },
|
|
{ key: 'interfaces', label: 'Ifaces' },
|
|
{ key: 'lldp', label: 'LLDP' },
|
|
{ key: 'vlans', label: 'VLANs' },
|
|
{ key: 'ssids', label: 'SSIDs' },
|
|
{ key: 'health', label: 'Health' },
|
|
{ key: 'docker', label: 'Docker' },
|
|
{ key: 'reboot', label: 'Reboot' },
|
|
{ key: 'configPush', label: 'Config push' },
|
|
]
|
|
|
|
function StatusBadge({ status }: { status: 'stable' | 'beta' }) {
|
|
return (
|
|
<span className={`text-xs font-medium px-2 py-0.5 rounded-full ${
|
|
status === 'stable'
|
|
? 'bg-green-500/20 text-green-400'
|
|
: 'bg-yellow-500/20 text-yellow-400'
|
|
}`}>
|
|
{status}
|
|
</span>
|
|
)
|
|
}
|
|
|
|
export default function Drivers() {
|
|
return (
|
|
<div className="py-16 md:py-24">
|
|
<div className="max-w-7xl mx-auto px-6">
|
|
<div className="mb-12">
|
|
<h1 className="text-4xl md:text-5xl font-bold text-slate-100 mb-4">Supported Devices</h1>
|
|
<p className="text-base text-slate-400 leading-relaxed max-w-xl">
|
|
netOrk ships with custom NAPALM drivers for 11 device types and supports all built-in NAPALM
|
|
drivers. Capability availability varies by driver.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Custom drivers table */}
|
|
<div className="mb-16 overflow-x-auto">
|
|
<h2 className="text-xl font-semibold text-slate-200 mb-4">Custom Drivers</h2>
|
|
<div className="rounded-xl border border-slate-800 overflow-hidden">
|
|
<table className="w-full text-sm">
|
|
<thead>
|
|
<tr className="border-b border-slate-800 bg-slate-900">
|
|
<th className="px-4 py-3 text-left font-medium text-slate-500">Driver</th>
|
|
<th className="px-4 py-3 text-left font-medium text-slate-500">Device type</th>
|
|
{CAPS.map((c) => (
|
|
<th key={c.key} className="px-3 py-3 text-center font-medium text-slate-500 whitespace-nowrap">
|
|
{c.label}
|
|
</th>
|
|
))}
|
|
<th className="px-4 py-3 text-left font-medium text-slate-500">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{DRIVERS.map((d) => (
|
|
<tr key={d.name} className="border-b border-slate-800 last:border-0 hover:bg-slate-800/40 transition-colors">
|
|
<td className="px-4 py-3 font-mono text-sky-400 whitespace-nowrap">{d.name}</td>
|
|
<td className="px-4 py-3 text-slate-300 whitespace-nowrap">{d.deviceType}</td>
|
|
{CAPS.map((c) => (
|
|
<td key={c.key} className="px-3 py-3 text-center">
|
|
<span className={d[c.key] === '✓' ? 'text-green-400' : 'text-slate-700'}>
|
|
{d[c.key]}
|
|
</span>
|
|
</td>
|
|
))}
|
|
<td className="px-4 py-3"><StatusBadge status={d.status} /></td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{/* NAPALM built-ins */}
|
|
<div>
|
|
<h2 className="text-xl font-semibold text-slate-200 mb-4">Built-in NAPALM Drivers</h2>
|
|
<p className="text-sm text-slate-400 mb-6">
|
|
All standard NAPALM drivers are supported. Capabilities depend on the upstream NAPALM implementation.
|
|
</p>
|
|
<div className="flex flex-wrap gap-3">
|
|
{NAPALM_BUILTIN.map((name) => (
|
|
<span
|
|
key={name}
|
|
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full border border-slate-700 bg-slate-900 text-xs font-medium text-slate-300"
|
|
>
|
|
{name}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|