# openstack-caracal-ipv4 -- VR0 DC0 Omega Cloud (v1)

**Scope:** Charmed OpenStack Caracal (2024.1), IPv4-only, on the 4-VM KVM lab and
modeled in NetBox as **VR0 DC0 Omega Cloud**. This repository is the deployment
method: bundle, overlay, gated runbook, and validation scripts together describe
everything required to bring the cloud up from a clean MAAS-managed Juju model. It is
a rehearsal for the future bare-metal **Roosevelt** deployment; design choices favour
the transferable answer over the quick fix so the testcloud surfaces real production
requirements.

## v1 vs. v2 -- read this first

v1 is IPv4-only Caracal on the existing MAAS-provisioned network layout; it ships first
because the upstream router infrastructure is not yet IPv6-ready. v2 adds IPv6 /
dual-stack (decisions D-004 / D-004a, retained as v2-scope in
`docs/design-decisions.md`) and will ship either as a sibling overlay on a `v2` branch
or as a separate repository (TBD when v2 begins). IPv6 prefixes already imported into
NetBox under VR0 DC0 remain at **Reservation** status to document v2 intent without
implying they are active (`netbox/ipv6-mark-reserved.py`).

## Source of truth

**NetBox is authoritative for IPAM.** Every IP, prefix, and VLAN referenced in this
repository traces back to NetBox. The exception is per-project tenant subnets, which
under the v1 hybrid model (D-016) are Neutron-managed inside a NetBox-modeled upstream
pool -- the pool has NetBox standing; individual tenant subnets do not.

## Repository layout

```
openstack-caracal-ipv4/
|-- README.md                        this file
|-- bundle.yaml                      canonical Charmed OpenStack bundle (IPv4); the
|                                      testcloud num_units / VIPs / hacluster are baked in
|-- overlays/                        empty in git -- the only overlay (octavia-pki.yaml)
|                                      is generated at deploy (phase-01) and is secret-
|                                      bearing, so it is never committed
|-- runbooks/                        the gated deploy runbook (phase-NN) + appendices
|   |-- README.md                    runbook index, order, and conventions
|   |-- phase-00-teardown-maas-reset.md
|   |-- phase-01-bundle-deploy.md
|   |-- phase-02-vault-bringup.md
|   |-- phase-03-core-verify.md
|   |-- phase-04-network-carve.md
|   |-- phase-05-octavia-enablement.md
|   |-- phase-06-incloud-mgmt-cluster.md
|   |-- phase-07-conductor-graft.md
|   |-- phase-08-workload-cluster-acceptance.md
|   |-- appendix-A-troubleshooting.md
|   \-- appendix-B-asbuilt-version-lock.md
|-- scripts/
|   |-- pre-flight-checks.sh         pre-deploy sanity checks
|   |-- validate.sh                  end-to-end validation runner
|   \-- review-bundle.py             bundle lint / review
|-- netbox/
|   |-- README.md                    what is imported vs. deferred to v2
|   |-- ipv4-prefixes-import.py      IPv4 prefixes + IPv4 tenant pool
|   \-- ipv6-mark-reserved.py        marks IPv6 entries Reservation (v2 intent)
\-- docs/
    |-- design-decisions.md          architectural record (D-NNN)
    |-- netbox-vip-queue.md          post-deploy NetBox imports
    \-- v1-pre-deploy-fixes.md       completed pre-deploy repo-hardening change list (D-019 series)
```

## Deploy order

Run the `runbooks/phase-NN-*.md` documents in numeric order. Each phase ends in a hard
gate (an explicit pass/fail check); do not begin the next phase until the current gate
passes. The two appendices are reference, not steps. See `runbooks/README.md` for the
per-phase summary and the RUN-location conventions.

| Phase    | Purpose                                                          |
| -------- | ---------------------------------------------------------------- |
| phase-00 | Teardown + MAAS reset (clean state for rebuild)                  |
| phase-01 | Bundle deploy (incl. Octavia PKI overlay generation) + settle    |
| phase-02 | Vault bring-up (PKI root; cert cascade)                          |
| phase-03 | Core verify (settle, admin-openrc regeneration, Horizon)         |
| phase-04 | Network carve (provider external network + IPAM reference)       |
| phase-05 | Octavia enablement                                               |
| phase-06 | In-cloud CAPI management cluster (D-035)                         |
| phase-07 | Magnum conductor graft (magnum-capi-helm driver; trustee domain-setup; D-031/D-037/D-042/D-046/D-047) |
| phase-08 | Workload-cluster acceptance (D-011)                             |

NetBox imports run separately, gated on external NetBox-engineer review
(`netbox/README.md`).

## Key v1 scope (full record in docs/design-decisions.md)

- **D-015 v1/v2 fork** -- IPv4-only v1; IPv6 / dual-stack deferred to v2.
- **D-016 IPv4 tenant-pool hybrid** -- NetBox owns the upstream pool; Neutron owns
  per-project subnets within it.
- **D-019 (supersedes D-008) DNS scope reduction** -- Designate deferred to v2; tenant
  subnets use public DNS (1.1.1.1 / 1.0.0.1) via `--dns-nameserver`; the internal
  `*.cloud.neumatrix.local` tree is resolved by static `/etc/hosts` on
  bootstrap-relevant hosts.
- **D-020 dual provider+metal HA VIPs** -- API charms carry a VIP on both the provider
  and metal spaces (front-loaded; exact values live in `bundle.yaml` / NetBox).
- **D-035 in-cloud management cluster** -- the CAPI / Magnum management cluster is a
  single-homed in-cloud tenant VM (no out-of-cloud node, no clusterctl pivot).
- **D-031 / D-037 / D-042 Magnum KaaS** -- tenant self-service Kubernetes via Magnum + the
  magnum-capi-helm driver + the azimuth capi-helm-charts engine; the driver pin must be
  contract-coherent with the CAPI core (see Appendix B).
- **D-009 hacluster at num_units=1** -- decorative on testcloud; documents the relation
  pattern for Roosevelt scale-up.

v2-scope decisions (D-004 dual-stack/IPv6 matrix; D-004a host-management-to-metal) are
recorded but NOT actioned in v1.

> `docs/design-decisions.md` is the authoritative decision record. If it lags the
> bundle/runbook (for example the D-020 VIP scheme or the D-028..D-042 series),
> reconcile it there.
