From a80fa4adbf2f52d81fc57547e280c84b0dcba377 Mon Sep 17 00:00:00 2001
From: Josh Creek <8179928+jcreek@users.noreply.github.com>
Date: Tue, 15 Apr 2025 20:04:37 +0100
Subject: [PATCH] feat(*): Add ports and lines
---
package.json | 5 +-
pnpm-lock.yaml | 9 +
src/app.html | 1 +
src/lib/components/DeviceCard.svelte | 29 ++-
src/lib/components/MachineCard.svelte | 28 ++-
src/lib/components/NetworkDiagram.svelte | 125 +++++++++++--
src/lib/types.ts | 18 +-
src/stores/networkStore.ts | 228 +++++++++++------------
8 files changed, 303 insertions(+), 140 deletions(-)
diff --git a/package.json b/package.json
index f7d53fa..610aa02 100644
--- a/package.json
+++ b/package.json
@@ -41,5 +41,8 @@
"esbuild"
]
},
- "packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
+ "packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0",
+ "dependencies": {
+ "leader-line": "^1.0.8"
+ }
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b30308e..8c8d3c5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,6 +7,10 @@ settings:
importers:
.:
+ dependencies:
+ leader-line:
+ specifier: ^1.0.8
+ version: 1.0.8
devDependencies:
'@eslint/compat':
specifier: ^1.2.5
@@ -925,6 +929,9 @@ packages:
known-css-properties@0.35.0:
resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==}
+ leader-line@1.0.8:
+ resolution: {integrity: sha512-3TOYtjjcYJCdtEs+bCuVSj6GvFiAzywtjifeeVcBYVwejHfI8a/NRxU4s6DjXB+H/ccNA/qtZEjrFVw9W97dCQ==}
+
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -2144,6 +2151,8 @@ snapshots:
known-css-properties@0.35.0: {}
+ leader-line@1.0.8: {}
+
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
diff --git a/src/app.html b/src/app.html
index 77a5ff5..2b8d838 100644
--- a/src/app.html
+++ b/src/app.html
@@ -5,6 +5,7 @@
%sveltekit.head%
+
{#if data}
-
{#each data.machines as machine}
{/each}
-
-
{#each data.devices as device}
{/each}
@@ -39,10 +142,10 @@
diff --git a/src/lib/types.ts b/src/lib/types.ts
index d04d8c9..09afe25 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -1,4 +1,10 @@
-interface Hardware {
+export interface Port {
+ portName: string;
+ speedGbps?: number; // default to 1 if not provided
+ connectedTo?: string; // e.g. "Router-LAN2"
+}
+
+export interface Hardware {
cpu: string;
ram: string;
networkPorts: number;
@@ -6,30 +12,32 @@ interface Hardware {
gpu?: string;
}
-interface VM {
+export interface VM {
name: string;
role: string;
ipAddress: string;
}
-interface Software {
+export interface Software {
vms: VM[];
}
-interface Machine {
+export interface Machine {
machineName: string;
ipAddress: string;
role: string;
operatingSystem: string;
software: Software;
hardware: Hardware;
+ ports?: Port[];
}
-interface NetworkDevice {
+export interface NetworkDevice {
name: string;
ipAddress: string;
type: string;
notes?: string;
+ ports?: Port[];
}
export interface NetworkData {
diff --git a/src/stores/networkStore.ts b/src/stores/networkStore.ts
index dec516f..2e3b361 100644
--- a/src/stores/networkStore.ts
+++ b/src/stores/networkStore.ts
@@ -1,43 +1,5 @@
import { writable } from 'svelte/store';
-
-export interface VMInfo {
- name: string;
- role: string;
- ipAddress: string;
-}
-
-export interface Software {
- vms: VMInfo[];
-}
-
-export interface Hardware {
- cpu: string;
- ram: string;
- networkPorts: number;
- networkPortSpeedGbps?: number;
- gpu?: string | null;
-}
-
-export interface Machine {
- machineName: string;
- ipAddress: string;
- role: string;
- operatingSystem: string;
- software: Software;
- hardware: Hardware;
-}
-
-export interface Device {
- name: string;
- ipAddress: string;
- type: string;
- notes?: string;
-}
-
-export interface NetworkData {
- machines: Machine[];
- devices: Device[];
-}
+import type { NetworkData } from '../lib/types';
// Create a writable store for the data
export const networkStore = writable({
@@ -52,7 +14,7 @@ export async function loadNetworkData(jsonPath: string) {
// const data = await response.json();
// networkStore.set(data);
- // For now, set a static example:
+ // For now, set a static example with 'ports' and sample connections:
const exampleData: NetworkData = {
machines: [
{
@@ -60,33 +22,26 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.3',
role: 'Hypervisor',
operatingSystem: 'Proxmox',
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 10,
+ // Connect to the router's LAN2
+ connectedTo: 'Router-LAN2'
+ },
+ {
+ portName: 'eth1',
+ speedGbps: 1
+ // Not connected
+ }
+ ],
software: {
vms: [
- {
- name: 'OpnSense',
- role: 'Router',
- ipAddress: '10.0.0.4'
- },
- {
- name: 'PiVPN',
- role: 'VPN Server',
- ipAddress: '10.0.0.5'
- },
- {
- name: 'PiHole',
- role: 'DNS Ad-blocker',
- ipAddress: '10.0.0.6'
- },
- {
- name: 'Dashy',
- role: 'Dashboard',
- ipAddress: '10.0.0.12'
- },
- {
- name: 'DockerHost',
- role: 'Docker/Reverse Proxy',
- ipAddress: '10.0.0.23'
- }
+ { name: 'OpnSense', role: 'Router', ipAddress: '10.0.0.4' },
+ { name: 'PiVPN', role: 'VPN Server', ipAddress: '10.0.0.5' },
+ { name: 'PiHole', role: 'DNS Ad-blocker', ipAddress: '10.0.0.6' },
+ { name: 'Dashy', role: 'Dashboard', ipAddress: '10.0.0.12' },
+ { name: 'DockerHost', role: 'Docker/Reverse Proxy', ipAddress: '10.0.0.23' }
]
},
hardware: {
@@ -102,9 +57,14 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.9',
role: 'NAS',
operatingSystem: 'Asustor ADM',
- software: {
- vms: []
- },
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1
+ // No connection
+ }
+ ],
+ software: { vms: [] },
hardware: {
cpu: 'Realtek RTD1296 Quad Core 1.4GHz',
ram: '2GB',
@@ -118,9 +78,14 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.13',
role: 'Smart Home Controller',
operatingSystem: 'Home Assistant OS',
- software: {
- vms: []
- },
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1
+ // Not connected
+ }
+ ],
+ software: { vms: [] },
hardware: {
cpu: 'Home Assistant Custom SoC',
ram: 'Unknown',
@@ -134,9 +99,14 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.11',
role: 'Media Server',
operatingSystem: 'Ubuntu Server',
- software: {
- vms: []
- },
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1
+ // Not connected
+ }
+ ],
+ software: { vms: [] },
hardware: {
cpu: 'Intel N100',
ram: 'Unknown',
@@ -150,9 +120,14 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.8',
role: 'Media Downloader',
operatingSystem: 'Windows 11',
- software: {
- vms: []
- },
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1
+ // Not connected
+ }
+ ],
+ software: { vms: [] },
hardware: {
cpu: 'Intel N100',
ram: 'Unknown',
@@ -166,33 +141,20 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.7',
role: 'Backup NAS + Hypervisor',
operatingSystem: 'TrueNAS Scale',
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1
+ // Not connected
+ }
+ ],
software: {
vms: [
- {
- name: 'Win11-Backblaze',
- role: 'Backblaze Backup',
- ipAddress: '10.0.0.24'
- },
- {
- name: 'UbuntuDockerHost',
- role: 'Docker Host',
- ipAddress: '10.0.0.14'
- },
- {
- name: 'MakeMKV',
- role: 'Blu-ray Ripper',
- ipAddress: '10.0.0.14'
- },
- {
- name: 'Handbrake',
- role: 'Video Transcoder',
- ipAddress: '10.0.0.15'
- },
- {
- name: 'NextCloud',
- role: 'Cloud Storage',
- ipAddress: 'TBD'
- }
+ { name: 'Win11-Backblaze', role: 'Backblaze Backup', ipAddress: '10.0.0.24' },
+ { name: 'UbuntuDockerHost', role: 'Docker Host', ipAddress: '10.0.0.14' },
+ { name: 'MakeMKV', role: 'Blu-ray Ripper', ipAddress: '10.0.0.14' },
+ { name: 'Handbrake', role: 'Video Transcoder', ipAddress: '10.0.0.15' },
+ { name: 'NextCloud', role: 'Cloud Storage', ipAddress: 'TBD' }
]
},
hardware: {
@@ -208,18 +170,17 @@ export async function loadNetworkData(jsonPath: string) {
ipAddress: '10.0.0.20',
role: 'AI Dev/Inference',
operatingSystem: 'Pop!_OS',
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 10
+ // Not connected
+ }
+ ],
software: {
vms: [
- {
- name: 'Ollama',
- role: 'LLM Inference',
- ipAddress: '10.0.0.21'
- },
- {
- name: 'Bot Training',
- role: 'AI Training',
- ipAddress: '10.0.0.22'
- }
+ { name: 'Ollama', role: 'LLM Inference', ipAddress: '10.0.0.21' },
+ { name: 'Bot Training', role: 'AI Training', ipAddress: '10.0.0.22' }
]
},
hardware: {
@@ -236,34 +197,71 @@ export async function loadNetworkData(jsonPath: string) {
name: 'Router',
ipAddress: '10.0.0.1',
type: 'Gateway',
- notes: 'Main internet-facing router'
+ notes: 'Main internet-facing router',
+ ports: [
+ {
+ portName: 'LAN1',
+ speedGbps: 1,
+ // Connect to Omada Controller
+ connectedTo: 'Omada Controller-eth0'
+ },
+ {
+ portName: 'LAN2',
+ speedGbps: 10,
+ // Connected to ProxRouter
+ connectedTo: 'ProxRouter-eth0'
+ },
+ {
+ portName: 'LAN3',
+ speedGbps: 1,
+ // Connect to HDHomeRun
+ connectedTo: 'HDHomeRun-eth0'
+ }
+ ]
},
{
name: 'HDHomeRun',
ipAddress: '10.0.0.2',
- type: 'TV Tuner'
+ type: 'TV Tuner',
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1,
+ connectedTo: 'Router-LAN3'
+ }
+ ]
},
{
name: 'Omada Controller',
ipAddress: '10.0.0.4',
type: 'Network Controller',
- notes: 'Access via port 8043'
+ notes: 'Access via port 8043',
+ ports: [
+ {
+ portName: 'eth0',
+ speedGbps: 1,
+ connectedTo: 'Router-LAN1'
+ }
+ ]
},
{
name: '3DS',
ipAddress: '10.0.0.17',
type: 'Handheld Console'
+ // No ports => Wi-Fi only
},
{
name: '2DS',
ipAddress: '10.0.0.18',
type: 'Handheld Console'
+ // No ports => Wi-Fi only
},
{
name: 'Nintendo Switch',
ipAddress: '10.0.0.19',
type: 'Gaming Console',
notes: 'IP to be confirmed'
+ // No ports => Wi-Fi only
}
]
};