# NetBox subnetting DRAFT -- VR1 DC-DC rebuild on 10.13.0.0/16

**DRAFT -- proposal, NOT ruled, NOT committed.** This is a planning artifact only.
It does not touch live NetBox, live infra, `lib-net.sh`, the overlays, or any other
authoritative surface. No `git commit`. It exists to let the operator rule the re-IP
(F1 pivot, below) with the full blast radius in view.

- Author: background agent (Task #2), 2026-08-08.
- Method: read-only extraction from `scripts/lib-net.sh` (full),
  `netbox/draft/vr1-office1-current-20260801.json`, `docs/design-decisions.md` (D-115,
  D-134), and a repo-wide `grep` sweep for `10.12.` literals. Every value below is
  measured from those files this session; none is inferred.
- Governing decisions named for the owed ruling: **D-101 / D-115 / D-124 / D-134**
  (per `docs/audit/queued-findings-20260808-...-reip-pivot.txt` F1).

---

## 1. Why (the pivot)

`docs/audit/queued-findings-20260808-dc0-tailscale-incident-reip-pivot.txt` **F1** records
the operator pivot verbatim: the VR1 build's `10.12.0.0/16` **collides with the
still-online IPv4 single-DC cloud** (the NetBox draft that seeded VR1 was that cloud's
external export). It surfaced at the Headscale step -- advertising `10.12.8.0/22`
overlaps the live cloud on the shared tailnet, and Headscale has no 4via6, so routes
must be non-overlapping. Operator plan: drive dc0 to a full-deployment checkpoint, then
**teardown + redeploy on `10.13.0.0/16`** -- a fresh subnetting build, never editing
live infra.

This draft is the addressing half of that redeploy. It is a **greenfield build on a
free /16**, so "re-IP" here means "author the new plan"; there is no live-object edit.

---

## 2. Proposed mapping principle -- 1:1 octet-preserving shift

**`10.12.a.b -> 10.13.a.b` for every DC (Cloud) address. Second octet `12 -> 13`;
octets 3 and 4 unchanged.**

This preserves, exactly and by construction:
- the six-plane role layout and offsets for both DCs,
- dc1's `10.12.64.0/19 -> 10.13.64.0/19` /19 supernet (D-115),
- the D-134 utility octet map (`.4/.5/.6/.7`) and the `.4-.49` / `.50-.99` bands,
- the triple-HA VIP columns and octets (D-020),
- the FIP pool sizes and offsets,
- the keystone public VIP octet.

Only the DC (Cloud-role) `10.12` space moves. Everything else stays (Section 6).

---

## 3. Before / after tables

### 3.1 DC0 planes (`vr1-dc0`; flat /22s, D-052/D-053 offsets)

| Role            | Before (10.12)   | After (10.13)    |
|-----------------|------------------|------------------|
| provider-public | 10.12.4.0/22     | 10.13.4.0/22     |
| metal-admin     | 10.12.8.0/22     | 10.13.8.0/22     |
| metal-internal  | 10.12.12.0/22    | 10.13.12.0/22    |
| data-tenant     | 10.12.16.0/22    | 10.13.16.0/22    |
| storage         | 10.12.32.0/22    | 10.13.32.0/22    |
| replication     | 10.12.36.0/22    | 10.13.36.0/22    |

### 3.2 DC1 planes (`vr1-dc1`; contiguous /22s inside the `10.12.64.0/19` supernet, D-115)

| Role            | Before (10.12)   | After (10.13)    |
|-----------------|------------------|------------------|
| (supernet)      | 10.12.64.0/19    | 10.13.64.0/19    |
| provider-public | 10.12.64.0/22    | 10.13.64.0/22    |
| metal-admin     | 10.12.68.0/22    | 10.13.68.0/22    |
| metal-internal  | 10.12.72.0/22    | 10.13.72.0/22    |
| data-tenant     | 10.12.76.0/22    | 10.13.76.0/22    |
| storage         | 10.12.80.0/22    | 10.13.80.0/22    |
| replication     | 10.12.84.0/22    | 10.13.84.0/22    |

### 3.3 Gateways (`PLANE_GW`) -- unchanged posture, shifted value

Per D-134 the `.1` gateway exists on the **provider-public** subnet ONLY; metal-admin
and the four data planes are `gw=none` (measured; MAAS returns `none`, `.1` is held by
NOTHING on both DCs). The VR0-only `vr0-dc0` arm additionally pins metal-admin `10.12.8.1`
-- that arm is NOT part of this rebuild (it is the live cloud; see OQ (a)/(c)).

| Plane                       | Before      | After       |
|-----------------------------|-------------|-------------|
| vr1-dc0 provider-public gw  | 10.12.4.1   | 10.13.4.1   |
| vr1-dc1 provider-public gw  | 10.12.64.1  | 10.13.64.1  |
| all other planes, both DCs  | none        | none        |

### 3.4 VIP prefixes (triple-HA columns, D-020/D-052) + keystone public VIP

| Item                          | Before     | After      |
|-------------------------------|------------|------------|
| dc0 VIP_PREFIX_PROVIDER       | 10.12.4    | 10.13.4    |
| dc0 VIP_PREFIX_ADMIN          | 10.12.8    | 10.13.8    |
| dc0 VIP_PREFIX_INTERNAL       | 10.12.12   | 10.13.12   |
| dc0 KEYSTONE_VIP_DEFAULT      | 10.12.4.50 | 10.13.4.50 |
| dc1 VIP_PREFIX_PROVIDER       | 10.12.64   | 10.13.64   |
| dc1 VIP_PREFIX_ADMIN          | 10.12.68   | 10.13.68   |
| dc1 VIP_PREFIX_INTERNAL       | 10.12.72   | 10.13.72   |
| dc1 KEYSTONE_VIP_DEFAULT      | 10.12.64.50| 10.13.64.50|

VIP band `.50-.99` (`VIP_OCTET_MIN=50`, `VIP_OCTET_MAX=99`), `VIP_COUNT_EXPECT=13`
(11 + vault `.61` + designate `.62`, R11) -- all UNCHANGED. The 13 service VIP octets
(.50 keystone .. .62 designate) are octet-preserved on each of the three legs.

### 3.5 D-134 utility bands + octet map (per plane)

Each plane carries a `.4-.49` utility band and a `.50-.99` VIP band (NetBox ip-ranges).
The **D-134 utility octet map** (extended by D-129(iii)(a) for `.7`) rides the
**metal-admin** plane:

| Octet | Role                    | dc0 before / after       | dc1 before / after        |
|-------|-------------------------|--------------------------|---------------------------|
| .4    | artifact mirror         | 10.12.8.4  / 10.13.8.4   | 10.12.68.4  / 10.13.68.4  |
| .5    | juju controller         | 10.12.8.5  / 10.13.8.5   | 10.12.68.5  / 10.13.68.5  |
| .6    | MAAS region             | 10.12.8.6  / 10.13.8.6   | 10.12.68.6  / 10.13.68.6  |
| .7    | tailscale subnet router | 10.12.8.7  / 10.13.8.7   | 10.12.68.7  / 10.13.68.7  |

(The `.4-.49` / `.50-.99` band ip-ranges exist on ALL six planes per DC, 24 ranges
total; each shifts by the same 12->13 rule.)

### 3.6 FIP pools (D-003) -- NOTE: MAAS reserved ipranges, not NetBox objects

| DC       | Before                    | After                     | Size      |
|----------|---------------------------|---------------------------|-----------|
| vr1-dc0  | 10.12.5.0 - 10.12.7.254   | 10.13.5.0 - 10.13.7.254   | 767 addrs |
| vr1-dc1  | 10.12.65.0 - 10.12.67.254 | 10.13.65.0 - 10.13.67.254 | 767 addrs |

Each sits inside its DC's provider-public /22 and does not overlap the D-134
`.4-.49` / `.50-.99` bands. **These pools are RESERVED ipranges on the MAAS provider
subnet (KI-P3-001), asserted by `scripts/phase-04-network-verify.sh` -- they are NOT
NetBox ip-range objects** (the office1 draft holds no FIP-pool range). The re-IP
therefore touches MAAS ipranges at build time; NetBox has a standing record gap here.

### 3.7 MAAS rack-controller statics (D-124 / D-120 static band)

| Host      | Before        | After         |
|-----------|---------------|---------------|
| vvr1-dc0  | 10.12.8.2/22  | 10.13.8.2/22  |
| vvr1-dc1  | 10.12.68.2/22 | 10.13.68.2/22 |

---

## 4. NetBox objects to re-scope (from `vr1-office1-current-20260801.json`)

Counts of objects whose value lies in `10.12` and would shift to `10.13` under the 1:1 rule:

| Object class        | Count | Notes                                                          |
|---------------------|-------|----------------------------------------------------------------|
| ipam/prefixes       | 13    | `10.12.0.0/16` Cloud + twelve plane /22s (6 dc0 + 6 dc1)       |
| ipam/ip-ranges      | 24    | D-134 `.4-.49` + `.50-.99` bands, 2 per plane x 12 planes      |
| ipam/ip-addresses   | 80    | 78 VIP legs (13 services x 3 legs x 2 DCs) + 2 rack `.2` statics|
| ipam/aggregates     | 0     | `10.0.0.0/8` is the parent; it ALREADY covers 10.13 -- no change|
| ipam/vlans          | 0     | none present in the draft                                      |
| dcim/regions,sites  | 0     | topology objects carry no v4 literal -- no change              |

**Two structural observations (feed OQ (b), not defects):**
- The dc1 **/19 supernet `10.12.64.0/19` has no NetBox prefix object** -- only its six
  child /22s are present. If the plan wants the supernet represented, that is a new
  object either way.
- The **FIP pools have no NetBox ip-range object** (Section 3.6) -- they live only as
  MAAS reserved ipranges.

---

## 5. Consumer inventory BEYOND NetBox (repo grep sweep, `10.12.` literals)

The re-IP is not a NetBox-only change. `lib-net.sh` names its own twins-of-record
(`opentofu/variables.tf` `vr1_dc1_planes`; `overlays/vr1-dc*-vips.yaml`;
`provider-bundle-check.py`'s independent octet band). Grouped literal-bearing LIVE
surfaces (historical `asbuilt/` snapshots and `docs/audit/osd-carve-*` frozen captures
EXCLUDED -- those are verbatim records, not to be edited):

| Surface class                 | Files | 10.12 literal hits | Key members                                                                 |
|-------------------------------|-------|--------------------|-----------------------------------------------------------------------------|
| scripts/                      | 27    | 246                | lib-net.sh (source of truth), phase-00-maas-standup, dc-rack-net, dc-snap-proxy |
| overlays/                     | 3     | 77                 | vr1-dc0-vips.yaml, vr1-dc1-vips.yaml (ratified VIP source, D-119 R9)         |
| opentofu/                     | 4     | 35                 | variables.tf (`vr1_dc1_planes` -- lib-net.sh's named twin)                   |
| netbox/ importers + drafts    | 11    | 257                | dc-dc-prefixes-import, dc-plane-apex-import, dc-util-hosts-import, d120-compose-bands, the draft JSONs |
| bundle.yaml                   | 1     | 16                 | deploy input (VIPs)                                                          |
| tests/ harnesses + fixtures   | 62    | 724                | dc-selector (re-parses the overlay), provider-bundle-check, render-baseline, phase-04 fixtures |
| runbooks/                     | 22    | 194                | procedure text citing plane CIDRs                                            |
| docs/ prose                   | 85    | 1337               | design-decisions, CURRENT-STATE, audit -- **prose record; update via new dated entries, do NOT rewrite** |

Discipline note: each script change ships with its `tests/<name>/run-tests.sh` green,
`repo-lint` clean, and a changelog entry (per CLAUDE.md). The two-file twins
(`lib-net.sh` <-> `opentofu/variables.tf`, and `lib-net.sh` <-> `overlays/*-vips.yaml`
via `tests/dc-selector`) must change in the SAME commit. This inventory is scope
visibility for the ruling, NOT a per-line remediation plan.

**Stale 10.13 reference already in-repo (pre-D-115):** `netbox/README.md:49` still shows
`VR1_DC1_V4_SUPERNET=10.13.0.0/19`, an importer default that D-115 superseded (dc1 became
`10.12.64.0/19`). Reusing 10.13 as the rebuild /16 is unrelated to that old /19 default,
but the stale line should be reconciled so the two 10.13 meanings do not confuse.

---

## 6. What does NOT shift

| Space                         | Value                          | Why it stays                                                       |
|-------------------------------|--------------------------------|-------------------------------------------------------------------|
| Rack transit /30s             | 172.31.0.0/30 (dc0), 172.31.0.4/30 (dc1) | Not in 10.12; D-124 Scheme A. See caveat below.          |
| Office1 LAN / compose         | 10.10.0.0/22 (10.10.0.0/24, 10.10.1.0/24) | Office role, D-115; not part of the DC space.            |
| Edge (sim ISP/WAN)            | 172.30.0.0/16 (office1-wan 172.30.1.0/24) | Edge role, D-115.                                        |
| Dev clouds                    | 10.16.0.0/16, 10.17.0.0/16     | Willamette / Roosevelt dev; unrelated.                           |
| Aggregate                     | 10.0.0.0/8                     | Parent of BOTH 10.12 and 10.13 -- unchanged, 10.13 falls under it. |
| IPv6 (all)                    | 2602:f3e2::/36 GUA, fd50:840e:74e2::/48 ULA | This is a v4-only re-IP; v6 is region-hierarchical and untouched. |

**Caveat -- transit ADDRESSES stay, transit ROUTES do not.** The 172.31.0.x /30 endpoint
addresses are unchanged, but the routes carried OVER them point at `10.12.*` DC
destinations today and must be re-pointed to `10.13.*` at rebuild. Flagged so "transit
unchanged" is not misread as "transit needs no work."

---

## 7. Dependent surfaces beyond IPAM (for the redeploy plan, not this draft)

- **Vault-issued cert SANs / IP SANs** on every API endpoint and VIP -- reissued against
  the new addresses at redeploy (D-052 TLS).
- **MAAS DHCP ranges** on the provisioning planes -- re-declared on 10.13. (Currency
  note: the measured dc1 DHCP range is `.201-.254`, not a recalled `.100-.200`.)
- **Tailscale subnet router advertised prefix** -- the whole reason for the pivot:
  `10.12.8.0/22 -> 10.13.8.0/22` (metal-admin), and the **Headscale ACL** that references
  the advertised metal-admin prefix per D-129(iii)(b) star model.
- **OVN / neutron provider network** definitions, and any external/provider network CIDR.
- **Charm config / bundle VIPs** (`bundle.yaml`, overlays) -- deploy inputs.
- **/etc/hosts and internal DNS** seeds (dc-node-etchosts and similar).

---

## 8. OPEN QUESTIONS for the operator (DO NOT decide here)

**(a) Confirm 10.13.0.0/16 is genuinely free -- LIVE, not just in a snapshot.**
The 10.13 scan in this draft was against `vr1-office1-current-20260801.json` (a dated
snapshot) -- absent there, NOT a measured live absence. Before committing, confirm
`10.13.0.0/16` is free of (i) the still-online IPv4 single-DC cloud, and (ii) anything
advertised on the shared tailnet (the exact class of overlap that caused the pivot).
10.14/10.15 also sit free between 10.13 and the 10.16/10.17 dev clouds, if a range choice
is wanted.

**(b) Exact 1:1 shift, or regularize a wart while greenfield?**
The 1:1 shift preserves everything but also PRESERVES dc0's non-contiguous offsets
(`4/8/12/16` then jump to `32/36`, skipping `20/24/28`) and the resulting dc0-vs-dc1
asymmetry (dc1 fits a /19; dc0 cannot). A greenfield /16 is the only cheap moment to
regularize dc0 into a contiguous, /19-shaped block symmetric with dc1 -- at the cost of
breaking octet-preservation and diverging further from the Roosevelt/VR0 layout D-101
was built to inherit. Presented as an option with its cost; NOT recommended here.

**(c) This re-IP needs a GA-R5 ruling BEFORE any dependent work.**
Governed by **D-101 / D-115 / D-124 / D-134** (F1). The number is deliberately NOT minted
here -- grep next-free `D-NNN` at ruling time. Two reconciliations the ruling must make
explicit:

- **D-101 inheritance terminates.** `lib-net.sh`'s `vr1-dc0` arm exists because D-101
  rules VR1 DC0 *inherits VR0 DC0's v4 layout unchanged*, and the live 10.12 cloud IS
  vr0-dc0. Moving VR1 to 10.13 ends that inheritance: **vr0-dc0 STAYS on 10.12 (live,
  untouched); the `vr0-dc0` and `vr1-dc0` case arms genuinely split for the first time**,
  and lib-net.sh's lines 124-134 comment ("Same PLANE values as vr0-dc0 ... INHERITS VR0
  DC0's v4 layout UNCHANGED") becomes FALSE and owes an update.
- **D-115 rejected 10.13 as "outside every allocated block."** D-115 (adopted) put the
  NetBox **Cloud** role at `10.12.0.0/16` and explicitly superseded a `10.13.0.0/19`
  recommendation because 10.13.x was unallocated. Its option (b) even floated a per-region
  /16 (VR1 = `10.15.0.0/16`) and the operator chose role-based instead. Picking
  `10.13.0.0/16` now REVIVES 10.13 as an allocation and must decide: does the NetBox
  **Cloud** role/prefix move to 10.13.0.0/16 (leaving the live cloud's 10.12 as its own
  record), does 10.13 become a NEW role (e.g. "Cloud -- VR1 rebuild") coexisting with the
  10.12 Cloud, and is this a D-115 amendment or a superseding decision? This is a genuine
  fork in the IPAM apex, not a mechanical shift.

---

## 9. Summary line

**Proposed: octet-preserving `10.12.a.b -> 10.13.a.b` for the entire VR1 Cloud DC space
(both DCs), everything else held.** Remapped: **12 planes** (6 per DC), **13 prefixes**,
**24 ip-ranges**, **80 ip-addresses** (78 VIP legs + 2 MAAS rack statics), **2 FIP pools**
(MAAS ipranges), **2 keystone VIPs**, **1 provider gateway per DC**. Held: 172.31 transit
addresses (routes re-point), 10.10 office, 172.30 edge, 10.16/10.17 dev, all IPv6, the
10.0.0.0/8 aggregate.

**DRAFT -- proposal, not ruled, not committed.**
