feat: redesign network topology diagram with accurate rack layout
Replace linear Internet→UDM→Agg→PoE→all-hosts chain with accurate topology: - USW-Aggregation and Pro 24 PoE switch shown side-by-side with horizontal 10G SFP+ link between them (not in series) - 5 compute/storage/monitor nodes fanned out under Agg Switch with 10G labels and rack unit positions (RU4–12, RU14–17) as sublabels - large1 shown separately under PoE switch, dashed border = off-rack (table) - Add device specs as subtitles on all nodes (Dream Machine Pro · RU24, etc.) - Shorter display names: csg-01 / cs-01 instead of full hostnames - Live status badges still updated by JS via data-host attributes - New CSS: .topo-node-sub, .topo-switch-tier, .topo-h-link, .topo-host-tier, .topo-host-table (dashed), .topo-badge-unknown Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -356,6 +356,66 @@ a:hover { text-decoration: underline; text-shadow: var(--glow-amber); }
|
||||
|
||||
.topo-status-dot { width:7px; height:7px; border:1px solid var(--text-muted); background:transparent; position:absolute; top:5px; right:5px; }
|
||||
|
||||
/* Topology subtitle text */
|
||||
.topo-node-sub {
|
||||
font-size: .58em;
|
||||
color: var(--text-muted);
|
||||
letter-spacing: .02em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.topo-badge-unknown { color:var(--text-muted); border-color:var(--border); }
|
||||
|
||||
/* Switch tier: two switches with horizontal connector */
|
||||
.topo-switch-tier {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.topo-h-link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.topo-h-link-line {
|
||||
width: 70px;
|
||||
height: 1px;
|
||||
background: var(--amber);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.topo-h-link-label {
|
||||
font-size: .52em;
|
||||
color: var(--amber);
|
||||
opacity: .7;
|
||||
margin-top: 3px;
|
||||
letter-spacing: .04em;
|
||||
}
|
||||
|
||||
/* Host tier: two groups side by side */
|
||||
.topo-host-tier {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
gap: 40px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.topo-host-group { flex-shrink: 0; }
|
||||
|
||||
/* PoE host group: offset right to sit below PoE switch */
|
||||
.topo-poe-hosts {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
/* Off-rack node (dashed border) */
|
||||
.topo-host-table {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
/* ── Host cards ───────────────────────────────────────────────────── */
|
||||
.host-grid {
|
||||
display: grid;
|
||||
|
||||
@@ -29,58 +29,105 @@
|
||||
</div>
|
||||
|
||||
<div class="topology" id="topology-diagram">
|
||||
<div class="topo-row topo-row-internet">
|
||||
|
||||
<!-- ── Tier 1: Internet ───────────────────────── -->
|
||||
<div class="topo-row">
|
||||
<div class="topo-node topo-internet">
|
||||
<span class="topo-icon">◈</span>
|
||||
<span class="topo-label">Internet</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topo-connectors single">
|
||||
<div class="topo-line"></div>
|
||||
<div class="topo-line topo-line-labeled" data-link-label="WAN 10G SFP+"></div>
|
||||
</div>
|
||||
|
||||
<!-- ── Tier 2: Router ─────────────────────────── -->
|
||||
<div class="topo-row">
|
||||
<div class="topo-node topo-unifi" id="topo-gateway">
|
||||
<div class="topo-node topo-unifi">
|
||||
<span class="topo-icon">⬡</span>
|
||||
<span class="topo-label">UDM-Pro</span>
|
||||
<span class="topo-status-dot" data-topo-target="gateway"></span>
|
||||
<span class="topo-node-sub">Dream Machine Pro · RU24</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topo-connectors single">
|
||||
<div class="topo-line topo-line-labeled" data-link-label="10G DAC"></div>
|
||||
</div>
|
||||
|
||||
<!-- ── Tier 3: Switches (Agg + PoE side by side) ─ -->
|
||||
<div class="topo-row">
|
||||
<div class="topo-switch-tier">
|
||||
<div class="topo-node topo-switch" id="topo-switch-agg">
|
||||
<span class="topo-icon">⬡</span>
|
||||
<span class="topo-label">Agg Switch</span>
|
||||
<span class="topo-status-dot" data-topo-target="switch-agg"></span>
|
||||
<span class="topo-label">USW-Agg</span>
|
||||
<span class="topo-node-sub">8×10G SFP+ · RU22</span>
|
||||
</div>
|
||||
<div class="topo-h-link">
|
||||
<div class="topo-h-link-line"></div>
|
||||
<span class="topo-h-link-label">10G SFP+</span>
|
||||
</div>
|
||||
<div class="topo-connectors single">
|
||||
<div class="topo-line topo-line-labeled" data-link-label="10G DAC"></div>
|
||||
</div>
|
||||
<div class="topo-row">
|
||||
<div class="topo-node topo-switch" id="topo-switch-poe">
|
||||
<span class="topo-icon">⬡</span>
|
||||
<span class="topo-label">PoE Switch</span>
|
||||
<span class="topo-status-dot" data-topo-target="switch-poe"></span>
|
||||
<span class="topo-label">Pro 24 PoE</span>
|
||||
<span class="topo-node-sub">24×1G PoE · RU23</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topo-connectors wide">
|
||||
{% for name in snapshot.hosts %}
|
||||
</div>
|
||||
|
||||
<!-- ── Tier 4: Hosts ──────────────────────────── -->
|
||||
<div class="topo-host-tier">
|
||||
|
||||
<!-- Agg-connected hosts (10G) -->
|
||||
<div class="topo-host-group">
|
||||
<div class="topo-connectors" style="gap:32px; justify-content:center">
|
||||
<div class="topo-line"></div>
|
||||
<div class="topo-line"></div>
|
||||
<div class="topo-line"></div>
|
||||
<div class="topo-line"></div>
|
||||
<div class="topo-line"></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="topo-row topo-hosts-row">
|
||||
{% for name, host in snapshot.hosts.items() %}
|
||||
<div class="topo-node topo-host topo-status-{{ host.status }}" data-host="{{ name }}">
|
||||
|
||||
{%- set topo_h = snapshot.hosts if snapshot.hosts else {} -%}
|
||||
{%- set agg_defs = [
|
||||
('compute-storage-gpu-01', 'csg-01', 'RU4–12 · 10G'),
|
||||
('compute-storage-01', 'cs-01', 'RU14–17 · 10G'),
|
||||
('storage-01', 'storage-01','10G SFP+'),
|
||||
('monitor-01', 'monitor-01','ZimaBoard · 10G'),
|
||||
('monitor-02', 'monitor-02','ZimaBoard · 10G'),
|
||||
] -%}
|
||||
{%- for hname, hlabel, hsub in agg_defs -%}
|
||||
{%- set st = topo_h[hname].status if hname in topo_h else 'unknown' -%}
|
||||
<div class="topo-node topo-host topo-status-{{ st }}" data-host="{{ hname }}">
|
||||
<span class="topo-icon">▣</span>
|
||||
<span class="topo-label">{{ name }}</span>
|
||||
<span class="topo-badge topo-badge-{{ host.status }}">{{ host.status }}</span>
|
||||
<span class="topo-label">{{ hlabel }}</span>
|
||||
<span class="topo-node-sub">{{ hsub }}</span>
|
||||
<span class="topo-badge topo-badge-{{ st }}">{{ st if st != 'unknown' else '–' }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{%- endfor -%}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PoE-connected hosts -->
|
||||
<div class="topo-host-group topo-poe-hosts">
|
||||
<div class="topo-connectors single">
|
||||
<div class="topo-line topo-line-labeled" data-link-label="1G PoE"></div>
|
||||
</div>
|
||||
<div class="topo-row">
|
||||
{%- set topo_h = snapshot.hosts if snapshot.hosts else {} -%}
|
||||
{%- set lst = topo_h['large1'].status if 'large1' in topo_h else 'unknown' -%}
|
||||
<div class="topo-node topo-host topo-host-table topo-status-{{ lst }}" data-host="large1">
|
||||
<span class="topo-icon">▣</span>
|
||||
<span class="topo-label">large1</span>
|
||||
<span class="topo-node-sub">on table · 1G</span>
|
||||
<span class="topo-badge topo-badge-{{ lst }}">{{ lst if lst != 'unknown' else '–' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /topo-host-tier -->
|
||||
</div>
|
||||
|
||||
<!-- Host cards -->
|
||||
<div class="host-grid" id="host-grid">
|
||||
{% for name, host in snapshot.hosts.items() %}
|
||||
|
||||
Reference in New Issue
Block a user