Files
Netbox/README.md
T
dcstephenson b6151b7de5 Add port labels, modernize patch panels, add a real PNG preview
- export_topology.py: edges now carry the exact port name on both ends
  (pulled directly from Cable/CableTermination, not inferred from the
  trace chain), so the diagram can label each connector.
- generate_drawio.py: patch panels are now a small rack-unit shape
  (header strip + port ticks, parented to the panel body so they move
  together) instead of a plain box; connectors show 'porta <-> portb'
  and no longer carry a directional arrowhead (these are physical
  cables, not directed links); switches keep the network-switch icon.
- render_png.js + render_host.html: headless Puppeteer driver for
  embed.diagrams.net's postMessage export protocol -- an actual
  render of the .drawio file, not an approximation. Field-Switch-
  Topology.png is the committed output, for anyone who wants a look
  without opening draw.io.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NM3nivbufxEWiKKmatEtEe
2026-09-15 13:03:18 -05:00

4.6 KiB

Netbox

Generated documentation for the field-switch network, sourced from this utility's live NetBox instance. NetBox is the source of truth here, not this repo -- everything under topology/ is a build artifact, regenerated from NetBox and committed so history shows what the physical network changed, not just what someone drew.

topology/

file what it is
export_topology.py Run inside the NetBox Django shell. Walks every field/distribution switch's cable path (through patch panels and splice modules), then pulls every real Cable among the devices it found so each edge carries the exact port name on both ends. Read-only.
topo_full.json Latest exported snapshot: devices (id, name, role, site, status) + edges ({a, a_port, b, b_port}, one per cable).
generate_drawio.py Pure-Python renderer: topo_full.json → Field-Switch-Topology.drawio. No NetBox access needed.
Field-Switch-Topology.drawio The diagram. Open at app.diagrams.net (or the desktop app, or the VS Code draw.io extension) -- free, no license needed.
render_png.js + render_host.html Renders the .drawio through a real draw.io instance (embed.diagrams.net, driven headlessly with Puppeteer) to produce Field-Switch-Topology.png -- an actual render, not an approximation. Needs npm install puppeteer and network access.
Field-Switch-Topology.png Static preview of the diagram, for anyone who wants a quick look without opening draw.io (viewing it in the Gitea file browser, a PR diff, etc.).

Two distribution switches (fche-sw17a, dmo-lob-sw35a) anchor two fabrics; everything downstream is field switches daisy-chained through patch panels and fiber splice modules. A handful of switches sit outside both fabrics for a documented reason (spare/inventory, decommissioning, or planned/not-yet-installed) -- those are called out in their own box on the diagram rather than silently dropped.

Every connector is labeled with the port at each end (e.g. 9 ↔ 1), and switches/patch panels look the part: switches get draw.io's built-in network switch icon, patch panels get a small rack-unit look (header strip + port ticks) rather than a plain box.

Connectors in the .drawio file are glued by shape id (draw.io's native source/target reference on each edge) -- drag a switch or panel in the app and its links follow, port-tick decorations included since they're parented to their panel's body cell. That's different from this project's earlier Visio (.vsdx) attempt, where glue had to be hand-written as cell formulas because the format has no simpler mechanism; draw.io does this natively, which is a big part of why this repo uses it instead.

Regenerating

From the NetBox host (needs docker exec access to the NetBox container):

docker exec netbox-netbox-1 python3 /opt/netbox/netbox/manage.py shell \
    -c "$(cat topology/export_topology.py)" 2>/dev/null > topology/topo_full.json

python3 topology/generate_drawio.py topology/topo_full.json topology/Field-Switch-Topology.drawio

# optional -- refreshes the PNG preview to match; first run: npm install puppeteer
node topology/render_png.js topology/Field-Switch-Topology.drawio topology/Field-Switch-Topology.png

Commit all three (topo_full.json, .drawio, .png) together. The diff on topo_full.json is the real changelog -- it shows exactly which device or cable changed between two snapshots; the .drawio/.png diffs are mostly noise (coordinates, pixels) but are kept in sync so the rendered diagram never drifts from what NetBox actually says.

Gotchas learned the hard way

  • NetBox's cached cable path can go stale. If a switch's connected_endpoints comes back empty even though it's obviously cabled, try manage.py trace_paths --force before assuming the cable data itself is wrong -- it recomputes the path cache and doesn't touch any cable/termination records.
  • A patch panel's front↔rear pass-through has to be modeled explicitly (a PortMapping row). A splice module can have a perfectly good cable on both sides of a port and still fail to trace if that mapping is missing -- check FrontPort.objects.get(...).mappings.count() before assuming the far end really is disconnected.

Possible next step

export_topology.py talks to NetBox via the Django ORM (docker exec + manage.py shell), which only works run from the NetBox host itself. Swapping it for a NetBox REST API client (device/cable/interface endpoints + an API token) would let this regenerate from anywhere, including CI, without shell access to the container.