diff --git a/docs/changelog-20260724-stage5-committee-fork1.md b/docs/changelog-20260724-stage5-committee-fork1.md index 8125078..b1e8a29 100644 --- a/docs/changelog-20260724-stage5-committee-fork1.md +++ b/docs/changelog-20260724-stage5-committee-fork1.md @@ -130,6 +130,26 @@ **Revert:** `git checkout ~ -- scripts/provider-bundle-check.py` + `git rm docs/audit/stage5-expansion-review-20260724.md`. +## Item 9 -- office1-netbox RECORD dumper (source separation) + current snapshot + +**What:** new `netbox/office1-record-dump.py` -- a dedicated READ-ONLY dumper for the +**office1-netbox RECORD** (the VR1 working apex, `10.10.1.10:8000`, 4.6.4, v2 token), +separate from `netbox/prod-draft-dump.py` (which pulls the FROZEN v1 reference +`netbox.baldurkeep.com`). Operator-directed source separation ("one script per source" -- +each holds only its own credential/URL; the token never travels, read from env). Added a +source-clarity note to `prod-draft-dump.py`'s docstring. New offline harness +`tests/office1-record-dump/run-tests.sh` (5/5: slim / prefix-scope rewrite / range key / +source-target). Committed the current snapshot `netbox/draft/vr1-office1-current-20260725.json`. +**Why:** a Chat design session (NetBox->deploy coupling) has no live infra; the existing +`vr1-draft.json` is the FROZEN reference (dated 07-15), NOT the current in-cloud state. +This captures the live apex so Chat designs against current data. Discovery: the standard +dump targets baldurkeep, not office1-netbox -- corrected before committing wrong-source data. +**Validation:** dump succeeded READ-ONLY (139 prefixes / 11 sites incl. vr1-dc0/dc1/off1; +dc1 bands 10.12.64/68/72.0/22 present -- confirms current buildout; differs from the 90-prefix +frozen reference). Harness 5/5; nothing written to NetBox. +**Revert:** `git rm netbox/office1-record-dump.py netbox/draft/vr1-office1-current-20260725.json +tests/office1-record-dump/run-tests.sh` + restore `prod-draft-dump.py` docstring. + ## Next (not done this session; gated) Commit+push this batch (GA-R5: rulings land before dependent work). Then, each diff --git a/netbox/draft/vr1-office1-current-20260725.json b/netbox/draft/vr1-office1-current-20260725.json new file mode 100644 index 0000000..486ff50 --- /dev/null +++ b/netbox/draft/vr1-office1-current-20260725.json @@ -0,0 +1,1762 @@ +{ + "_note": "READ-ONLY snapshot of the office1-netbox RECORD (VR1 working apex, DOCFIX-195). IDs discarded; refs by slug/prefix.", + "_source": "http://10.10.1.10:8000", + "dcim/regions": [ + { + "description": "Top-level region for US West metros. Holds Eugene (and future West Coast metros).", + "name": "US West", + "parent": null, + "slug": "us-west" + }, + { + "description": "Region0 \u2014 Eugene, OR metro. Nested under US West. Assigned 10.16.0.0/16 IPv4.", + "name": "Eugene", + "parent": "us-west", + "slug": "eugene" + }, + { + "description": "Virtual Regions for testing", + "name": "Virtual Regions", + "parent": null, + "slug": "virtual-region" + }, + { + "description": "Virtual Region for testing", + "name": "VR0", + "parent": "virtual-region", + "slug": "vr0" + }, + { + "description": "Virtual Region for testing", + "name": "VR1", + "parent": "virtual-region", + "slug": "vr1" + } + ], + "dcim/sites": [ + { + "description": "Primary office \u2014 Office0 at 10.16.4.0/24", + "name": "Charnelton", + "region": "eugene", + "slug": "charnelton", + "status": "active" + }, + { + "description": "Future manufacturing/OT \u2014 Cloud3 at 10.16.64.0/20 (reserved)", + "name": "Cleveland", + "region": "eugene", + "slug": "cleveland", + "status": "planned" + }, + { + "description": "Primary DC and current Internet edge \u2014 Cloud0 at 10.16.16.0/20", + "name": "Roosevelt", + "region": "eugene", + "slug": "roosevelt", + "status": "active" + }, + { + "description": "Future tertiary DC \u2014 Cloud2 at 10.16.48.0/20 (reserved)", + "name": "Stevenson", + "region": "eugene", + "slug": "stevenson", + "status": "planned" + }, + { + "description": "Virtual Site for testing", + "name": "VR0 DC0", + "region": "vr0", + "slug": "vr0-dc0", + "status": "active" + }, + { + "description": "Virtual Site for testing", + "name": "VR0 DC1", + "region": "vr0", + "slug": "vr0-dc1", + "status": "active" + }, + { + "description": "Virtual Site for testing", + "name": "VR0 Off0", + "region": "vr0", + "slug": "vr0-off0", + "status": "active" + }, + { + "description": "Virtual Site for testing", + "name": "VR1 DC0", + "region": "vr1", + "slug": "vr1-dc0", + "status": "active" + }, + { + "description": "Virtual Site for testing", + "name": "VR1 DC1", + "region": "vr1", + "slug": "vr1-dc1", + "status": "active" + }, + { + "description": "", + "name": "VR1 Off1", + "region": "vr1", + "slug": "vr1-off1", + "status": "active" + }, + { + "description": "Secondary DC \u2014 Cloud1 at 10.16.32.0/20. Future Internet edge once ARIN allocation and transit contracts move.", + "name": "Willamette", + "region": "eugene", + "slug": "willamette", + "status": "active" + } + ], + "ipam/aggregates": [ + { + "description": "RFC1918 private IPv4.", + "prefix": "10.0.0.0/8", + "rir": "rfc-1918" + }, + { + "description": "ARIN IPv4 allocation.", + "prefix": "23.157.124.0/24", + "rir": "arin" + }, + { + "description": "RFC1918 private IPv4 (OOB space).", + "prefix": "172.16.0.0/12", + "rir": "rfc-1918" + }, + { + "description": "ARIN IPv6 allocation: the HELD /36 = region-0 of the planned /32 (D-101). Update to /32 after the expand completes.", + "prefix": "2602:f3e2::/36", + "rir": "arin" + }, + { + "description": "Org ULA /48 (internal-only; D-101 literal).", + "prefix": "fd50:840e:74e2::/48", + "rir": "rfc-4193-ula" + } + ], + "ipam/ip-addresses": [ + { + "address": "10.10.1.10/24", + "description": "office1-netbox service (D-120 static band; re-IP from .201)", + "dns_name": "office1-netbox", + "role": null, + "status": "active" + }, + { + "address": "10.10.1.11/24", + "description": "office1-tailscale subnet router (D-120 static band; re-IP from .202)", + "dns_name": "office1-tailscale", + "role": null, + "status": "active" + }, + { + "address": "10.12.8.2/22", + "description": "vr1-dc0 MAAS rack controller (vvr1-dc0) metal-admin static IP (D-124; D-120 static band)", + "dns_name": "vvr1-dc0", + "role": null, + "status": "active" + }, + { + "address": "10.12.68.2/22", + "description": "vr1-dc1 MAAS rack controller (vvr1-dc1) metal-admin static IP (D-124 amendment 2026-07-21; D-120 static band)", + "dns_name": "vvr1-dc1", + "role": null, + "status": "active" + } + ], + "ipam/ip-ranges": [ + { + "description": "D-120 static site-services band (.2-.49) -- MAAS static-assign, outside the dynamic range", + "end_address": "10.10.1.49/24", + "range": "10.10.1.2/24-10.10.1.49/24", + "role": null, + "start_address": "10.10.1.2/24", + "status": "active" + }, + { + "description": "D-120 MAAS dynamic band (.100-.200) -- enlistment/commissioning/PXE/DHCP", + "end_address": "10.10.1.200/24", + "range": "10.10.1.100/24-10.10.1.200/24", + "role": null, + "start_address": "10.10.1.100/24", + "status": "active" + }, + { + "description": "D-120 deployed-node band (.201-.254) -- MAAS auto-assign for compute/OpenStack nodes", + "end_address": "10.10.1.254/24", + "range": "10.10.1.201/24-10.10.1.254/24", + "role": null, + "start_address": "10.10.1.201/24", + "status": "active" + } + ], + "ipam/prefixes": [ + { + "description": "Local Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "0.0.0.0/8", + "role": "localnet", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Corp Private", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.0.0.0/8", + "role": "private", + "scope_type": null, + "status": "container" + }, + { + "description": "Office (v4) -- /22 per office (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.10.0.0/16", + "role": "office", + "scope_type": null, + "status": "container" + }, + { + "description": "VR1 Off1 -- office /22 (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.10.0.0/22", + "role": "office", + "scope_site": "vr1-off1", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR1 Off1 office1-local LAN -- Kea DHCP on the OPNsense edge (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.10.0.0/24", + "role": "office", + "scope_site": "vr1-off1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 Off1 LXD compose net (lxdbr0) -- MAAS DHCP (D-114/D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.10.1.0/24", + "role": "office", + "scope_site": "vr1-off1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Virtual Cloud IPs", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.0.0/16", + "role": "cloud", + "scope_type": null, + "status": "active" + }, + { + "description": "VR1 DC0 provider-public (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.4.0/22", + "role": "provider-public", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 metal-admin (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.8.0/22", + "role": "metal-admin", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 metal-internal (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.12.0/22", + "role": "metal-internal", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 data-tenant (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.16.0/22", + "role": "data-tenant", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 storage (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.32.0/22", + "role": "storage", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 replication (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.36.0/22", + "role": "replication", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 provider-public (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.64.0/22", + "role": "provider-public", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 metal-admin (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.68.0/22", + "role": "metal-admin", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 metal-internal (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.72.0/22", + "role": "metal-internal", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 data-tenant (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.76.0/22", + "role": "data-tenant", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 storage (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.80.0/22", + "role": "storage", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 replication (v4; D-101)", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.12.84.0/22", + "role": "replication", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Current assignment to Willamette dev cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.16.0.0/16", + "role": "dc", + "scope_type": null, + "status": "deprecated" + }, + { + "description": "Current assignment to Roosevelt dev cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "10.17.0.0/16", + "role": "dc", + "scope_type": null, + "status": "deprecated" + }, + { + "description": "Public ARIN assignment to Abysius Inc", + "is_pool": false, + "mark_utilized": false, + "prefix": "23.157.124.0/24", + "role": "public", + "scope_type": null, + "status": "container" + }, + { + "description": "CGNAT Reserved", + "is_pool": false, + "mark_utilized": false, + "prefix": "100.64.0.0/10", + "role": "cgnat", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Localhost", + "is_pool": false, + "mark_utilized": false, + "prefix": "127.0.0.0/8", + "role": "localhost", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Link-Local", + "is_pool": false, + "mark_utilized": false, + "prefix": "169.254.0.0/16", + "role": "link-local", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Corp OOB Private", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.16.0.0/12", + "role": "private", + "scope_type": null, + "status": "container" + }, + { + "description": "Edge (v4) -- simulated ISP/WAN segments; mirrors v6 2602:f3e2:fe::/48 (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.30.0.0/16", + "role": "edge", + "scope_type": null, + "status": "container" + }, + { + "description": "VR1 Off1 office1-wan -- simulated ISP uplink (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.30.1.0/24", + "role": "edge", + "scope_site": "vr1-off1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "vr1-dc0 simulated-ISP edge WAN (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.30.2.0/24", + "role": "edge", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "vr1-dc1 simulated-ISP edge WAN (D-115)", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.30.3.0/24", + "role": "edge", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Transit (v4) -- dedicated per-DC point-to-point transit supernet (D-124, operator-pinned 2026-07-16); UNSCOPED container, each DC's link scoped to its site. Precondition for dc-rack-mgmt-import.", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.31.0.0/24", + "role": "transit", + "scope_type": null, + "status": "container" + }, + { + "description": "office1<->dc0 management transit -- region<->rack MAAS control path (D-124 Scheme A)", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.31.0.0/30", + "role": "transit", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "office1<->dc1 management transit -- region<->rack MAAS control path (D-124 Scheme A)", + "is_pool": false, + "mark_utilized": false, + "prefix": "172.31.0.4/30", + "role": "transit", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Residential Private", + "is_pool": false, + "mark_utilized": false, + "prefix": "192.168.0.0/16", + "role": "private", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Public Multicast", + "is_pool": false, + "mark_utilized": false, + "prefix": "224.0.0.0/4", + "role": "multicast", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Public Reserved - Enterprise Private", + "is_pool": false, + "mark_utilized": false, + "prefix": "240.0.0.0/4", + "role": "private", + "scope_type": null, + "status": "container" + }, + { + "description": "Localhost", + "is_pool": false, + "mark_utilized": false, + "prefix": "::1/128", + "role": "localhost", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Discard Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "100::/64", + "role": "discard", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Public ARIN assignment to Abysius Inc", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2::/36", + "role": "public", + "scope_type": null, + "status": "container" + }, + { + "description": "Inter-Regional Infrastructure", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2::/40", + "role": "infra", + "scope_type": null, + "status": "container" + }, + { + "description": "Inter-Regional Site to Site Links", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2::/48", + "role": "infra", + "scope_type": null, + "status": "container" + }, + { + "description": "Edge Networks", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:fe::/48", + "role": null, + "scope_type": null, + "status": "container" + }, + { + "description": "Private cloud tenant reservation", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:ff::/48", + "role": "openstack-tenant", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Eugene Region; Sites receive /24 allocations starting at fc01:0100::/24", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:100::/40", + "role": "region", + "scope_region": "eugene", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Eugene Regional Infrastructure", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:100::/48", + "role": "infra", + "scope_region": "eugene", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Eugene Site to Site Links", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:100::/56", + "role": "infra", + "scope_region": "eugene", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Eugene Regional Offices; Offices are allocated /32 subnets", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:101::/48", + "role": "office", + "scope_region": "eugene", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Reserved for fun and profit", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:101::/56", + "role": "office", + "scope_region": "eugene", + "scope_type": "dcim.region", + "status": "reserved" + }, + { + "description": "Charnelton", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:101:100::/56", + "role": "office", + "scope_site": "charnelton", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Willamette Site", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102::/48", + "role": "dc", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Omega Cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102::/56", + "role": "cloud", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:10::/60", + "role": "provider", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:10::/64", + "role": "provider", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Willamette Omega Cloud \u2014 Provider API VIPs (charm-managed via hacluster; excluded from Neutron pools)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:11::/64", + "role": "provider", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:20::/60", + "role": "metal", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:20::/64", + "role": "metal", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:30::/60", + "role": "data", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:30::/64", + "role": "data", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:40::/60", + "role": "storage", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:40::/64", + "role": "storage", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:50::/60", + "role": "repl", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:50::/64", + "role": "repl", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:80::/60", + "role": "lbaas-mgmt", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:80::/64", + "role": "lbaas-mgmt", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:e0::/60", + "role": "vpn", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:f0::/60", + "role": "oob", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:f0::/64", + "role": "oob", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Psi Cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:100::/56", + "role": "cloud", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Beta Cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:1600::/56", + "role": "cloud", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Alpha Cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:102:1700::/56", + "role": "cloud", + "scope_site": "willamette", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Roosevelt Site", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:103::/48", + "role": "dc", + "scope_site": "roosevelt", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Second Region", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:200::/40", + "role": "region", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Third Region", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:300::/40", + "role": "region", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Virtual Region 0 (VR0)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e00::/40", + "role": "region", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Virtual Region 0 (VR0) Infrastructure", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e00::/48", + "role": "infra", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "VR0 Site to Site Links", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e00::/56", + "role": "infra", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "active" + }, + { + "description": "VR0 DC1 to DC0 Site to Site Link", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e00:1::/127", + "role": "infra", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "active" + }, + { + "description": "VR0 Off0 to DC0 Site to Site Link", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e00:2::/127", + "role": "infra", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "active" + }, + { + "description": "Virtual Region 0 (VR0) Offices", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e01::/48", + "role": "office", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Virtual Region 0 (VR0) Offices; Reserved for fun and profit", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e01::/56", + "role": "office", + "scope_region": "vr0", + "scope_type": "dcim.region", + "status": "reserved" + }, + { + "description": "Virtual Region 0 (VR0) Office 0 (Off0)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e01:100::/56", + "role": "office", + "scope_site": "vr0-off0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 Off0 Office Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e01:100::/64", + "role": "office", + "scope_site": "vr0-off0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Virtual Region 0 (VR0) Datacenter 0 (DC0)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02::/48", + "role": "dc", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02::/56", + "role": "cloud", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud Provider Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:10::/60", + "role": "provider", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud Provider Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:10::/64", + "role": "provider", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud \u2014 Provider API VIPs (charm-managed via hacluster; excluded from Neutron pools)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:11::/64", + "role": "provider", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud Metal Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:20::/60", + "role": "metal", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud Metal Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:20::/64", + "role": "metal", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud Data Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:30::/60", + "role": "data", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud Data Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:30::/64", + "role": "data", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud Storage Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:40::/60", + "role": "storage", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud Storage Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:40::/64", + "role": "storage", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud Replication Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:50::/60", + "role": "repl", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud Replication Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:50::/64", + "role": "repl", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud LBaaS Management Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:80::/60", + "role": "lbaas-mgmt", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud LBaaS Management Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:80::/64", + "role": "lbaas-mgmt", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR0 DC0 Omega Cloud VPN Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:e0::/60", + "role": "vpn", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud OOB Prefix", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:f0::/60", + "role": "oob", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR0 DC0 Omega Cloud OOB Subnet", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e02:f0::/64", + "role": "oob", + "scope_site": "vr0-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Virtual Region 0 (VR0) Datacenter 1 (DC1)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:e03::/48", + "role": "dc", + "scope_site": "vr0-dc1", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "Virtual Region 1 (VR1)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f00::/40", + "role": "region", + "scope_region": "vr1", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Virtual Region 1 (VR1) Infrastructure", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f00::/48", + "role": "infra", + "scope_region": "vr1", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "VR1 Site to Site Links", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f00::/56", + "role": "infra", + "scope_region": "vr1", + "scope_type": "dcim.region", + "status": "active" + }, + { + "description": "Virtual Region 1 (VR1) Offices", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f01::/48", + "role": "office", + "scope_region": "vr1", + "scope_type": "dcim.region", + "status": "container" + }, + { + "description": "Virtual Region 1 (VR1) Offices; Reserved for fun and profit", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f01::/56", + "role": "office", + "scope_region": "vr1", + "scope_type": "dcim.region", + "status": "reserved" + }, + { + "description": "VR1 Off1 (D-115) -- mirrors VR0 Off0 e01:100::/56", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f01:100::/56", + "role": "office", + "scope_site": "vr1-off1", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR1 Off1 office subnet -- NOT YET DEPLOYED (v6 does not egress the lab)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f01:100::/64", + "role": "office", + "scope_site": "vr1-off1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Virtual Region 1 (VR1) Datacenter 0 (DC0)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f02::/48", + "role": "dc", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR1 DC0 provider-public (GUA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f02:10::/60", + "role": "provider-public", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 provider-public (GUA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f02:10::/64", + "role": "provider-public", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 provider-public (GUA VIP /64; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f02:11::/64", + "role": "provider-public", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Virtual Region 1 (VR1) Datacenter 1 (DC1)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f03::/48", + "role": "dc", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "container" + }, + { + "description": "VR1 DC1 provider-public (GUA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f03:10::/60", + "role": "provider-public", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 provider-public (GUA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f03:10::/64", + "role": "provider-public", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 provider-public (GUA VIP /64; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "2602:f3e2:f03:11::/64", + "role": "provider-public", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Centrally assigned ULA (Not Active)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fc00::/8", + "role": "private", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Unique Local Addresses (ULA)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd00::/8", + "role": "private", + "scope_type": null, + "status": "container" + }, + { + "description": "VR1 DC0 metal-admin (ULA metal /60 (admin+internal); D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:220::/60", + "role": "metal-admin", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 metal-admin (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:220::/64", + "role": "metal-admin", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 metal-internal (ULA /64 active (in metal /60); D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:221::/64", + "role": "metal-internal", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 data-tenant (ULA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:230::/60", + "role": "data-tenant", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 data-tenant (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:230::/64", + "role": "data-tenant", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 storage (ULA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:240::/60", + "role": "storage", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 storage (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:240::/64", + "role": "storage", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 replication (ULA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:250::/60", + "role": "replication", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC0 replication (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:250::/64", + "role": "replication", + "scope_site": "vr1-dc0", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 metal-admin (ULA metal /60 (admin+internal); D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:320::/60", + "role": "metal-admin", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 metal-admin (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:320::/64", + "role": "metal-admin", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 metal-internal (ULA /64 active (in metal /60); D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:321::/64", + "role": "metal-internal", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 data-tenant (ULA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:330::/60", + "role": "data-tenant", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 data-tenant (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:330::/64", + "role": "data-tenant", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 storage (ULA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:340::/60", + "role": "storage", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 storage (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:340::/64", + "role": "storage", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 replication (ULA /60; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:350::/60", + "role": "replication", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "VR1 DC1 replication (ULA /64 active; D-101/D-111)", + "is_pool": false, + "mark_utilized": false, + "prefix": "fd50:840e:74e2:350::/64", + "role": "replication", + "scope_site": "vr1-dc1", + "scope_type": "dcim.site", + "status": "active" + }, + { + "description": "Tailscale Addresses", + "is_pool": false, + "mark_utilized": true, + "prefix": "fd7a:115c:a1e0::/48", + "role": "vpn", + "scope_type": null, + "status": "active" + }, + { + "description": "Link-Local", + "is_pool": false, + "mark_utilized": false, + "prefix": "fe80::/10", + "role": "link-local", + "scope_type": null, + "status": "reserved" + }, + { + "description": "Public Multicast", + "is_pool": false, + "mark_utilized": false, + "prefix": "ff00::/8", + "role": "multicast", + "scope_type": null, + "status": "reserved" + } + ], + "ipam/rirs": [ + { + "description": "", + "is_private": false, + "name": "ARIN", + "slug": "arin" + }, + { + "description": "", + "is_private": true, + "name": "RFC 1918", + "slug": "rfc-1918" + }, + { + "description": "", + "is_private": true, + "name": "RFC 4193 ULA", + "slug": "rfc-4193-ula" + } + ], + "ipam/roles": [ + { + "description": "Six-plane: provider public API VIPs + FIP/ext_net (GUA). D-052/D-101.", + "name": "Provider Public", + "slug": "provider-public", + "weight": 100 + }, + { + "description": "Six-plane: metal admin API, dual-stack v4+ULA (2026-07-09 amendment). D-052/D-101.", + "name": "Metal Admin", + "slug": "metal-admin", + "weight": 110 + }, + { + "description": "Six-plane: metal internal API endpoints, dual-stack v4+ULA. D-052/D-101.", + "name": "Metal Internal", + "slug": "metal-internal", + "weight": 120 + }, + { + "description": "Six-plane: geneve overlay, ULA-only; tenant GUA delegated separately. D-052/D-101.", + "name": "Data Tenant", + "slug": "data-tenant", + "weight": 130 + }, + { + "description": "Six-plane: Ceph cluster incl. cross-DC leg, ULA-only. D-052/D-101/D-108.", + "name": "Replication Plane", + "slug": "replication", + "weight": 150 + }, + { + "description": "", + "name": "CGNAT", + "slug": "cgnat", + "weight": 1000 + }, + { + "description": "Cloud container", + "name": "Cloud", + "slug": "cloud", + "weight": 1000 + }, + { + "description": "Openstack data plane - shared across datacenters", + "name": "Data", + "slug": "data", + "weight": 1000 + }, + { + "description": "Datacenter container", + "name": "Datacenter", + "slug": "dc", + "weight": 1000 + }, + { + "description": "", + "name": "Discard", + "slug": "discard", + "weight": 1000 + }, + { + "description": "", + "name": "Edge", + "slug": "edge", + "weight": 1000 + }, + { + "description": "Shared infrastructure \u2014 ptp transit, device loopbacks, RR loopbacks, anycast.", + "name": "Infrastructure", + "slug": "infra", + "weight": 1000 + }, + { + "description": "Load-balancer management (Octavia control plane, not dataplane).", + "name": "LBaaS Management", + "slug": "lbaas-mgmt", + "weight": 1000 + }, + { + "description": "", + "name": "Link-Local", + "slug": "link-local", + "weight": 1000 + }, + { + "description": "", + "name": "Localhost", + "slug": "localhost", + "weight": 1000 + }, + { + "description": "", + "name": "Localnet", + "slug": "localnet", + "weight": 1000 + }, + { + "description": "Bare-metal server NICs + bundled infra: OpenStack control plane, in-band switch mgmt (VLAN 50), Edge-eBGP/DDoS sub-ranges (Roosevelt), RR loopback references. Sized as 2x physical server count.", + "name": "Metal", + "slug": "metal", + "weight": 1000 + }, + { + "description": "", + "name": "Multicast", + "slug": "multicast", + "weight": 1000 + }, + { + "description": "Out of band management network", + "name": "OOB", + "slug": "oob", + "weight": 1000 + }, + { + "description": "Office site allocation (/24 within Region0 /20 reserved block).", + "name": "Office", + "slug": "office", + "weight": 1000 + }, + { + "description": "OpenStack tenant pool \u2014 shared across tenants", + "name": "Openstack Tenant", + "slug": "openstack-tenant", + "weight": 1000 + }, + { + "description": "Reserved addresses for private networks", + "name": "Private", + "slug": "private", + "weight": 1000 + }, + { + "description": "Tenant-reachable. Carries ext_net (FIPs, SNAT egress) and OpenStack public API VIPs. Within each /60: first /64 Neutron FIP pool; next /64 charm API VIPs. Neutron allocation_pools must exclude VIPs.", + "name": "Provider", + "slug": "provider", + "weight": 1000 + }, + { + "description": "Public addresses assigned by a RIR", + "name": "Public", + "slug": "public", + "weight": 1000 + }, + { + "description": "", + "name": "Region", + "slug": "region", + "weight": 1000 + }, + { + "description": "RBD mirror for cross-site Ceph replication. Routed via EVPN type-5 between DCs.", + "name": "Replication", + "slug": "repl", + "weight": 1000 + }, + { + "description": "Ceph-Public (L3-routed) + Ceph-Cluster (non-routed VLAN inside /23 L2).", + "name": "Storage", + "slug": "storage", + "weight": 1000 + }, + { + "description": "OpenStack tenant networks (Geneve underlay touchdown). Also absorbs DMZ roles under regional scheme.", + "name": "Tenant", + "slug": "tenant", + "weight": 1000 + }, + { + "description": "", + "name": "Transit", + "slug": "transit", + "weight": 1000 + }, + { + "description": "VPN client pools \u2014 site-independent (10.2.0.0/16 Corp Private).", + "name": "VPN", + "slug": "vpn", + "weight": 1000 + } + ] +} diff --git a/netbox/office1-record-dump.py b/netbox/office1-record-dump.py new file mode 100644 index 0000000..8e53b93 --- /dev/null +++ b/netbox/office1-record-dump.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 +""" +Dump the OFFICE1-NETBOX RECORD (the VR1 working IPAM apex) to a reviewable JSON +artifact. READ-ONLY. NOTHING is ever written to NetBox. + +WHY A SEPARATE SCRIPT FROM netbox/prod-draft-dump.py (operator-directed 2026-07-25): +one script per SOURCE, so each holds only its own credential/URL and the source can +never be confused. The two NetBoxes are DIFFERENT systems with DIFFERENT roles: + + - prod-draft-dump.py -> netbox.baldurkeep.com : the FROZEN v1 REFERENCE (4.5.8, + bare 40-char v1 token). Takes NO write during VR1 (DOCFIX-195); it is the + eventual production apex, held read-only. + - THIS script -> office1-netbox 10.10.1.10:8000 : the VR1 WORKING APEX / + "the RECORD" (4.6.4, assembled v2 token nbt_.). This is what + every VR1 consuming system (OpenTofu, MAAS, the overlays, the Juju bundle) + actually reads (DOCFIX-195), and what has been EDITED as the dc0/dc1 buildout + proceeded -- so this is the "current in-cloud NetBox" state. + +Use this to capture the CURRENT apex for a design/review session that has no live infra +(e.g. Chat). It is a point-in-time snapshot; re-run to refresh. + +TOKEN NEVER TRAVELS: the script reads NETBOX_URL + NETBOX_TOKEN from the environment; +source the record env first (below). It is not embedded and not printed (only the base +URL + per-endpoint counts are printed). + +TRAP -- User-Agent (references/platform-traps.md): the baldurkeep upstream 403s the +default Python UA; office1-netbox does not have that WAF, but we send an accepted UA +regardless (harmless) so the same code path works against either 4.5/4.6 apex. + +Usage: + . ~/vr1-office1-creds/vr1-netbox-sandbox.env # NETBOX_URL=http://10.10.1.10:8000 + v2 NETBOX_TOKEN + python3 netbox/office1-record-dump.py --out netbox/draft/vr1-office1-current-YYYYMMDD.json +""" + +import argparse +import json +import os +import sys +import urllib.error +import urllib.request + +UA = "curl/8.5.0" + +# Same IPAM object set + dependency order as prod-draft-dump.py, so the two apexes +# produce structurally comparable dumps (a fidelity diff is then meaningful). +ENDPOINTS = [ + ("ipam/rirs", ["name", "slug", "is_private", "description"]), + ("ipam/roles", ["name", "slug", "weight", "description"]), + ("dcim/regions", ["name", "slug", "parent", "description"]), + ("dcim/sites", ["name", "slug", "status", "region", "description"]), + ("ipam/aggregates", ["prefix", "rir", "description"]), + ("ipam/prefixes", ["prefix", "status", "role", "scope_type", "scope_id", + "description", "is_pool", "mark_utilized"]), + ("ipam/ip-ranges", ["start_address", "end_address", "status", "role", "description"]), + ("ipam/ip-addresses", ["address", "status", "role", "dns_name", "description"]), +] + + +def die(msg): + print("FAIL: %s" % msg, file=sys.stderr) + sys.exit(2) + + +def require_env(name): + v = os.environ.get(name) + if not v: + die("%s is not set. Source the RECORD env first: " + ". ~/vr1-office1-creds/vr1-netbox-sandbox.env" % name) + return v + + +def get_all(base, token, path): + """Paginate an endpoint fully. Read-only.""" + out = [] + url = "%s/api/%s/?limit=200" % (base, path) + while url: + req = urllib.request.Request(url, headers={ + "Authorization": "Token %s" % token, # v2 wire form: Token nbt_<key>.<plaintext> + "Accept": "application/json", + "User-Agent": UA, + }) + try: + with urllib.request.urlopen(req, timeout=45) as r: + data = json.load(r) + except urllib.error.HTTPError as exc: + if exc.code in (401, 403): + die("HTTP %d on %s -- check the RECORD env token is the ASSEMBLED v2 form " + "(nbt_<key>.<plaintext>), not the API's bare token field." % (exc.code, path)) + die("HTTP %d on %s: %s" % (exc.code, path, exc.reason)) + out += data["results"] + url = data.get("next") or None + return out + + +def slim(obj, fields): + """Keep only what a downstream fidelity/seed step needs; nested refs -> slug/value. + IDs are DISCARDED (they are apex-local and would mis-link on the way into another apex).""" + rec = {} + for f in fields: + v = obj.get(f) + rec[f] = (v.get("slug") or v.get("value")) if isinstance(v, dict) else v + return rec + + +def rewrite_prefix_scope(rec, obj, site_id_to_slug, region_id_to_slug): + """Rewrite a prefix's scope_id (apex-local id) to a slug the reader can re-resolve.""" + sid, st = obj.get("scope_id"), obj.get("scope_type") + if sid is not None and st == "dcim.site": + rec["scope_site"] = site_id_to_slug.get(sid) + elif sid is not None and st == "dcim.region": + rec["scope_region"] = region_id_to_slug.get(sid) + rec.pop("scope_id", None) + return rec + + +def main(): + ap = argparse.ArgumentParser(description=__doc__.split("\n\n", 1)[0]) + ap.add_argument("--out", required=True, help="Path to write the JSON snapshot") + args = ap.parse_args() + + base = require_env("NETBOX_URL").rstrip("/") + token = require_env("NETBOX_TOKEN") + + print("Reading the office1-netbox RECORD from %s (READ-ONLY) ..." % base) + raw_sites = get_all(base, token, "dcim/sites") + site_id_to_slug = {s["id"]: s["slug"] for s in raw_sites} + raw_regions = get_all(base, token, "dcim/regions") + region_id_to_slug = {r["id"]: r["slug"] for r in raw_regions} + + draft = {"_source": base, + "_note": "READ-ONLY snapshot of the office1-netbox RECORD (VR1 working apex, " + "DOCFIX-195). IDs discarded; refs by slug/prefix."} + for path, fields in ENDPOINTS: + rows = raw_sites if path == "dcim/sites" else get_all(base, token, path) + slimmed = [] + for o in rows: + rec = slim(o, fields) + if path == "ipam/prefixes": + rec = rewrite_prefix_scope(rec, o, site_id_to_slug, region_id_to_slug) + if path == "ipam/ip-ranges": + rec["range"] = "%s-%s" % (rec.get("start_address"), rec.get("end_address")) + slimmed.append(rec) + draft[path] = slimmed + print(" %-18s %d" % (path, len(slimmed))) + + os.makedirs(os.path.dirname(os.path.abspath(args.out)), exist_ok=True) + with open(args.out, "w") as fh: + json.dump(draft, fh, indent=2, sort_keys=True) + fh.write("\n") + print("\nWrote %s. NOTHING was written to NetBox." % args.out) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/netbox/prod-draft-dump.py b/netbox/prod-draft-dump.py index af7793a..686080d 100755 --- a/netbox/prod-draft-dump.py +++ b/netbox/prod-draft-dump.py @@ -1,6 +1,11 @@ #!/usr/bin/env python3 """ -Dump the UPSTREAM NetBox draft to a reviewable JSON artifact. READ-ONLY. +Dump the FROZEN v1 REFERENCE NetBox (netbox.baldurkeep.com) to a reviewable JSON +artifact. READ-ONLY. SOURCE SEPARATION (operator-directed 2026-07-25): this script +pulls ONLY the baldurkeep v1 reference (4.5.8, bare 40-char token, no writes during +VR1 per DOCFIX-195). To dump the CURRENT VR1 working apex / RECORD (office1-netbox, +4.6.4, v2 token), use the SEPARATE netbox/office1-record-dump.py -- one script per +source so a credential/URL can never be confused. This is phase 1 of the two-phase sandbox seeding loop documented in docs/session-ledger.md: diff --git a/tests/office1-record-dump/run-tests.sh b/tests/office1-record-dump/run-tests.sh new file mode 100755 index 0000000..de4f13b --- /dev/null +++ b/tests/office1-record-dump/run-tests.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# tests/office1-record-dump/run-tests.sh +# +# OFFLINE unit harness for netbox/office1-record-dump.py's PURE transform functions +# (slim / prefix-scope rewrite / ip-range key). NO network, no live NetBox -- the +# network path (get_all) is not exercised here; this proves the record->JSON shaping +# that a downstream fidelity/diff depends on. Mutates NOTHING. +# Exit: 0 all pass | 1 any failed. ASCII + LF. +set -uo pipefail +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO="$(cd "$HERE/../.." && pwd)" +MOD="$REPO/netbox/office1-record-dump.py" + +python3 - "$MOD" <<'PY' +import sys, importlib.util +spec = importlib.util.spec_from_file_location("o1dump", sys.argv[1]) +m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m) + +P = F = 0 +def ok(cond, label): + global P, F + if cond: print(" PASS %s" % label); P += 1 + else: print(" FAIL %s" % label); F += 1 + +# T1 slim keeps only requested fields, resolves a nested ref to its slug +r = m.slim({"prefix": "10.12.64.0/22", "role": {"slug": "provider-public", "id": 9}, + "status": {"value": "active"}, "extra": "dropped"}, + ["prefix", "role", "status"]) +ok(r == {"prefix": "10.12.64.0/22", "role": "provider-public", "status": "active"}, + "T1 slim resolves nested ref->slug/value and drops unrequested fields") + +# T2 slim keeps a missing field as None (stable schema) +ok(m.slim({"prefix": "x"}, ["prefix", "role"]) == {"prefix": "x", "role": None}, + "T2 slim fills a missing field with None") + +# T3 prefix scope rewrite: dcim.site id -> scope_site slug, scope_id dropped +rec = m.rewrite_prefix_scope({"prefix": "p", "scope_type": "dcim.site", "scope_id": 5}, + {"scope_id": 5, "scope_type": "dcim.site"}, + {5: "vr1-dc1"}, {}) +ok(rec.get("scope_site") == "vr1-dc1" and "scope_id" not in rec, + "T3 prefix scope dcim.site -> scope_site slug, scope_id dropped") + +# T4 prefix scope rewrite: dcim.region id -> scope_region slug (the region-scoped case) +rec = m.rewrite_prefix_scope({"prefix": "p"}, + {"scope_id": 2, "scope_type": "dcim.region"}, + {}, {2: "vr1"}) +ok(rec.get("scope_region") == "vr1" and "scope_id" not in rec, + "T4 prefix scope dcim.region -> scope_region slug") + +# T5 the record source is office1-netbox via the RECORD env (source separation); +# require_env names the sandbox env, and the Usage line sources it -- prove it targets +# the record, not the frozen reference. +import inspect +src = inspect.getsource(m) +ok("office1-netbox" in src and "vr1-netbox-sandbox.env" in src and "10.10.1.10:8000" in src, + "T5 script targets the RECORD (office1-netbox 10.10.1.10:8000 / sandbox env)") + +print("\nRESULT: PASS=%d FAIL=%d" % (P, F)) +sys.exit(1 if F else 0) +PY +rc=$? +[[ "$rc" -eq 0 ]] && echo "ALL PASS" || echo "SOME FAILED" +exit $rc