|
D-119: region-qualify the VR1 DC namespace -- C3 / gap #19 CLOSED (Stage 3 unblocked)
THE BUG: the token `dc0` meant TWO DIFFERENT CLOUDS depending on the file --
VR0's LIVE testcloud in scripts/lib-net.sh, VR1's FIRST DC in the NetBox
importer. One string, two clouds, one of them in production.
THE RULING (operator): the repo adopts the apex's names verbatim.
vr0-dc0 VR0's DC0 the LIVE testcloud (a DIFFERENT region)
vr1-dc0 VR1's FIRST DC GUA 2602:f3e2:f02::/48
vr1-dc1 VR1's SECOND DC GUA 2602:f3e2:f03::/48
Bare dc0/dc1/dc2 are now REJECTED LOUDLY everywhere.
D-119 COMPLETES D-117, it does not reverse it: it executes D-117's own amendment
across the three surfaces D-117 never touched. ZERO NetBox writes -- the apex was
already correct and self-consistent (MEASURED: f02::/48 -> vr1-dc0, f03::/48 ->
vr1-dc1); the REPO was the only surface out of step. Renaming the apex to match
the repo was considered and REJECTED (production IPAM write; VR1 would become the
only 1-indexed region; and vr1-dc1 would mean VR1's FIRST DC while vr0-dc1 means
VR0's SECOND).
THE PRIZE: the importer's DC->site map is now an IDENTITY -- there is no offset
table left to get wrong, and an assert enforces it. The original defect was
precisely a WRONG LOOKUP TABLE. The bug class is deleted, not defended.
TWO REAL BUGS the naming fix ALONE would NOT have closed (found by review sweep):
- BREAK-1: descriptions were built with f"VR1 {dc.upper()} ..." -- under D-119 that
renders "VR1 VR1-DC0 provider-public" on all 36 prefixes. Same class as the
original bug (deriving a label by munging a token), hidden in the description
field where slug-focused review missed it. Now looked up from SITES[name].
- BREAK-2 (the important one): DC_GUA_PREFIX was NEVER cross-checked against --dc.
`--dc vr1-dc0 DC_GUA_PREFIX=<f03>` was ACCEPTED: it writes the SECOND DC's GUA,
carved with the FIRST DC's ULA nibble, scoped to the FIRST DC's site -- a
silently mis-bound datacenter assembled from two disagreeing sources. Identity-
mapping the slug leaves the ADDRESSING free-floating. Now guarded by EXPECTED_GUA.
ALSO: vdc1/vdc2 -> vvr1-dc0/vvr1-dc1 (D-114 amendment). D-114's own DR primitive is
`virsh destroy vdc1`, which read as "destroy VR1 DC1" while MEANING "destroy VR1
DC0". A mislabelled destroy command in a DR drill is not cosmetic. Neither VM is
built, so it is free. voffice1/Office1 KEEP their number (operator ruling).
Env var: DC1_/DC2_V4_SUPERNET -> VR1_DC1_V4_SUPERNET (both old names rejected).
rbd-mirror's --site-name aligned: `--dc vr1-dc0 --site-name dc1` was a re-created
two-namespace collision on one command line.
TESTS: dc-selector 21->30, prefixes-import 40->82 (identity invariant; EXPECTED_GUA
in BOTH mismatch directions; mismatched run writes NOTHING; matching pair still
succeeds; no munged description). GAUNTLET ALL GREEN (57). repo-lint 0 fail.
The old harnesses PINNED THE WRONG MAPPING -- they would have gone green while
enforcing the bug.
THE tofu apply IS NOT DONE -- IT IS GATED. Plan: 11 to add, 0 to change, 11 to
destroy (libvirt object names are ForceNew; moved{} makes the plan reviewable but
cannot suppress a replace). MEASURED SAFE: all 11 are EMPTY -- no guests, no
volumes, Stage 3 hasn't run. Office1's live objects are not in the plan.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|---|
|
|
| docs/changelog-20260714-d119-region-qualified-dc-namespace.md 0 → 100644 |
|---|
| docs/dc-dc-deployment-workflow.md |
|---|
| docs/design-decisions.md |
|---|
| docs/session-ledger.md |
|---|
| docs/vr1-office1-as-built.md |
|---|
| netbox/README.md |
|---|
| netbox/dc-dc-prefixes-import.py |
|---|
| opentofu/main.tf |
|---|
| opentofu/modules/cloudinit-vm/variables.tf |
|---|
| opentofu/variables.tf |
|---|
| runbooks/dc-dc-phase0-vcloud-prep.md |
|---|
| runbooks/dc-dc-phase1-office1-standup.md |
|---|
| runbooks/dc-dc-phase3-maas-enlist-deploy.md |
|---|
| runbooks/dc-dc-phase4-juju-bundle-per-dc.md |
|---|
| runbooks/dc-dc-phase5-dr-failover-drill.md |
|---|
| runbooks/dc-dc-phase6-designate-cos-magnum.md |
|---|
| scripts/carve-host-interfaces.sh |
|---|
| scripts/dc-dc-ceph-disk-budget.sh |
|---|
| scripts/dc-dc-dr-drill.sh |
|---|
| scripts/dc-dc-radosgw-multisite.sh |
|---|
| scripts/dc-dc-rbd-mirror.sh |
|---|
| scripts/lib-hosts.sh |
|---|
| scripts/lib-net.sh |
|---|
| scripts/phase-00-maas-standup.sh |
|---|
| scripts/reenroll-hosts.sh |
|---|
| scripts/site-headend-install.sh |
|---|
| tests/carve-host-interfaces/run-tests.sh |
|---|
| tests/dc-dc-ceph-disk-budget/run-tests.sh |
|---|
| tests/dc-dc-dr-drill/run-tests.sh |
|---|
| tests/dc-dc-prefixes-import/test_logic.py |
|---|
| tests/dc-dc-radosgw-multisite/run-tests.sh |
|---|
| tests/dc-dc-rbd-mirror/run-tests.sh |
|---|
| tests/dc-selector/run-tests.sh |
|---|
| tests/phase-00-maas-standup/run-tests.sh |
|---|
| tests/reenroll-hosts/run-tests.sh |
|---|