Newer
Older
openstack-caracal-dc-dc / docs / changelog-20260721-g12-dc1-authoring.md

2026-07-21 -- G12 [V] leg: vr1-dc1 substrate authoring (session changelog)

Session scope: the G12 remaining [V] leg per the D-124 AMENDMENT (2026-07-21): apex confirm-free -> vr1_dc1 vars -> dc1 substrate authoring -> gated build. Branch: dc-dc-g12-dc1-substrate (off post-Stage-3-merge main, per the stage-close rule). One changelog for the session (GA-R2/D1); every item carries its revert.

Item 1 -- dc1 apex confirm-free capture (read-only; the [V] leg's first step)

Read-only GETs on office1-netbox (token used on-host, never printed), captured to docs/audit/dc1-apex-confirm-20260721.txt. Findings:

  • The six dc1 plane /22s ALREADY EXIST in the apex, scoped vr1-dc1, exactly matching the ratified D-124-amendment scheme (provider-public 10.12.64.0/22 ... replication 10.12.84.0/22, roles per D-101). Confirm-CONSISTENT: the assignment landed at the original D-101/D-115 import; the ruled derivation matches it.
  • Transit 172.31.0.4/30 FREE (container 172.31.0.0/24 + dc0's /30 are its only occupants; zero ip-addresses in the /30).
  • Uplink 172.30.3.0/24 already registered to vr1-dc1 (D-115 edge import, 2026-07-17). Rack IP 10.12.68.2 + forwarder .3 free (zero ip-addresses in 10.12.68.0/22). Site vr1-dc1 and role transit exist.

Consequence: the ONLY apex write still owed for dc1 is the transit /30 + rack metal-admin IP -- exactly the dc-rack-mgmt-import.py surface (dc0 precedent: those are the only two objects dc0 registered either; transit endpoint IPs and the D-131 forwarder alias are NOT apex objects for dc0 and dc1 mirrors that).

Revert: delete the capture file (no state touched).

Item 2 -- dc-rack-mgmt-import.py: per-site support (vr1-dc0 + vr1-dc1)

What: the importer was dc0-hardcoded (SITE_SLUG/METAL_ADMIN/RACK_DNS/desc constants). Replaced with a SITES map (dc0: 10.12.8.0/22 / vvr1-dc0, ratified 2026-07-16; dc1: 10.12.68.0/22 / vvr1-dc1, D-124 amendment 2026-07-21) selected by a new REQUIRED --site {vr1-dc0,vr1-dc1} flag (env: RACK_SITE). Explicit by design: one DC's values can never land scoped to another site. An env-supplied site is validated against SITES in code (argparse choices does not validate env-default values). ROLE_SLUG / CONTAINER / D-120 band offsets stay global (convention-wide). Also generalized dc0-specific error/usage text and fixed two stale "(Cloud)" labels on the container messages (the container has been 172.31.0.0/24, not Cloud, since 2026-07-16).

Why: unblocks the one owed dc1 apex write; the D-124 scheme "generalizes per-leg" and the tool now encodes that instead of forking a dc1 copy.

Harness: tests/dc-rack-mgmt-import/ extended in the same change -- all CLI cases pass --site, new cases: missing --site dies; bogus RACK_SITE env dies; dc1 happy path (site id binding, /22 mask, dns vvr1-dc1); cross-site guard (dc0 rack IP under --site vr1-dc1 rejected, zero writes); dc1 band edges .2/.49 accepted, .1 gateway rejected; missing vr1-dc1 site precondition dies. Structural pins moved from the retired globals to the SITES map. 117/117 PASS (was 96).

Live dry-run vs the real apex (read-only, on office1-netbox): docs/audit/dc1-rack-import-dryrun-20260721.txt -- whole preflight PASS, plan = would-create exactly 172.31.0.4/30 (role transit, scope vr1-dc1) + 10.12.68.2/22 (dns vvr1-dc1). The --commit is a GATED operator step (apex mutation), not run here.

Revert: git checkout main -- netbox/dc-rack-mgmt-import.py tests/dc-rack-mgmt-import/ (restores the dc0-only tool); delete the two capture files. No apex state touched (dry-run only).