Add NetBox-derived field switch topology (draw.io)
- export_topology.py: dumps switch + patch-panel cable graph from NetBox (Django shell, read-only) - generate_drawio.py: renders topo_full.json as a draw.io diagram with natively-glued connectors (source/target by shape id, no hand-rolled glue formulas) - topo_full.json + Field-Switch-Topology.drawio: current snapshot Replaces the earlier hand-built .vsdx approach: plain-text format diffs meaningfully in git, no Visio license needed to view/edit, and edges glue natively instead of needing point-to-point formula hacks. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NM3nivbufxEWiKKmatEtEe
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# Netbox
|
||||
|
||||
Generated documentation for the field-switch network, sourced from this
|
||||
utility's live [NetBox](https://netbox.dev/) 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) and dumps the resulting device graph as JSON. Read-only. |
|
||||
| `topo_full.json` | Latest exported snapshot: devices (id, name, role, site, status) + edges (physical links, 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](https://app.diagrams.net) (or the desktop app, or the VS Code draw.io extension) -- free, no license needed. |
|
||||
|
||||
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.
|
||||
|
||||
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. 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):
|
||||
|
||||
```sh
|
||||
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
|
||||
```
|
||||
|
||||
Commit both files together. The diff on `topo_full.json` is the real
|
||||
changelog -- it shows exactly which device or cable changed between two
|
||||
snapshots; the `.drawio` diff is mostly noise (coordinates) but is 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.
|
||||
Reference in New Issue
Block a user