diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index ff83c2b..1dc4a5e 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -46,6 +46,63 @@ > - Stage-5 runbook: `runbooks/dc-dc-phase4-juju-bundle-per-dc.md`; Step 4 delegates to > `phase-01-bundle-deploy.md` verbatim. +- **Stage 5 / Phase 4 -- "Juju controller + OpenStack bundle, per DC" + (`runbooks/dc-dc-phase4-juju-bundle-per-dc.md`): OPEN 2026-07-30.** Opened on the + standing operator directive quoted in the block above. Branch + `dc-dc-stage5-preconditions` (NOT re-branched off `main`: it carries the D-136 + renderer, both per-DC overlay pairs, `octavia-pki.sh reissue`, preflight P7 and + `lib-identity.sh`, none of which are on `main` -- re-branching first would be the + record-churn the directive shuts down). There is NO ruled DC ordering (GA-R5 + 2026-07-27, section 1); both DCs deploy from voffice1 by the same procedure. + **ENTRY GATE, measured ON voffice1 -- the D-128 Plane-2 host, which is the only + host whose reading counts** (gauntlet and P5/P7 are all host-dependent; capture + `docs/audit/stage5-preflight-dc0-20260730.txt`, `DC=vr1-dc0 bash scripts/preflight.sh`, + exit 1): **P1 repo-lint PASS; P2 bundle invariants PASS; P3 channel assert PASS + (33 pins, 0 fail, 0 warn); P4 live pre-flight PASS incl. all 9 dc0 nodes Ready, + all six planes present by CIDR, 13 aligned VIPs 0 bad, overlay present with 5 + lb-mgmt-* keys; P7 Octavia PKI PASS 37 assertions / 0 failed WITH the literal + zone line `A12 DNS SANs are all in this DC's expected zone + 'omega.dc0.vr1.cloud.neumatrix.local'`; P5 credential matrix FAIL, 101 rows, 19 + check groups clean, 6 findings.** Both clones verified at `c58bf95` on the same + branch before any gate output was trusted (the 07-27 stale-clone hazard is the + reason this is checked, not assumed). Deploy artifacts verified to EXIST as files + on voffice1 rather than inferred from the record -- `bundle.yaml` is the VR1 + 9-node role-separated layout, plus `vr1-dc{0,1}-{vips,machines,octavia-pki}.yaml` + (the PKI pair `0600` and gitignored). The 2026-07-24 committee finding that + `bundle.yaml` was still VR0's 4-node hyperconverged layout is SUPERSEDED by that + measurement. + **P5 ACCEPTED BY OPERATOR RULING 2026-07-30 (GA-R5).** Question as presented: + "Preflight on voffice1 is RED on P5 only, with 6 pre-existing credential-register + findings: (1) S2 vr1-dc0 'opnsense-api.txt' (dc0-edge-api, SEC-021) expected by the + matrix but not declared in the manifest; (2-4) three S5 per-DC power-key asymmetries + (dc0 declares id_ed25519 + maas-virsh_ed25519 with no dc1 counterpart; dc1 declares + id_dcN_power with no dc0 counterpart); (5) S6 identity conflation -- 'maas-region-admin' + serves both human and service principal types (SEC-020); (6) E4 two rows uncheckable + for lack of a declared location (capi-mgmt-kubeconfig, rbd-mirror-peer-token). P1-P4 + and P7 all PASS. Per your standing directive I have not re-audited these. Accept and + proceed to the deploy, or remediate first?" **Operator answer, exact utterance: + "Accept and proceed to deploy (Recommended)".** CONSEQUENCE: the six findings are + accepted, known, pre-existing exposure carried forward on their existing open SEC + rows (SEC-020, SEC-021) -- they are register/custody hygiene, not deploy-blocking + defects. `preflight.sh` will continue to exit FAIL on P5 for the duration of this + stage; that RED is ruled-accepted and is NOT a reason to re-run the audit, and it + must NOT be made green by deleting or weakening a matrix row (the standing rule that + a checker which cannot fail is not a gate applies here). Remediation stays coupled to + the D-137 forks. **A future session must not read this acceptance as covering any + NEW P5 finding** -- it covers these six, enumerated, and nothing else. + **LOGGED, NOT EXECUTED (hard rule 1) -- `bundle.yaml:592` gives `ceph-osd` the + constraint `tags=openstack`.** It is the ONLY application of 56 carrying a tag + constraint; every other reads `arch=amd64` alone. That tag is a VR0-era value and is + MEASURED ABSENT from the VR1 region (`maas admin tags read` -> `virtual`, + `pod-console-logging`, `serial-console`, `openstack-vr1-dc0`, `openstack-vr1-dc1`, + `control`, `compute`, `storage`, `juju-controller-vr1-dc0`, `juju-controller-vr1-dc1` + -- no bare `openstack`). Neither machines overlay overrides it. `ceph-osd` has + explicit placement (`to: ["5","6","7","8"]`) so the initial deploy is expected to + place by machine id regardless; the exposure that is REASONED AND NOT MEASURED is a + later unplaced `juju add-unit ceph-osd`, which would match no machine. The real + impact is measurable at Step 4.2's `--dry-run` and not before, so it is recorded here + and decided there -- it is not folded into the P5 ruling above. + - Project: Omega Cloud, VR1 DC-DC rehearsal -- a two-DC + Office1-headend virtual rehearsal on KVM (vcloud host), rehearsing the future bare-metal Roosevelt deployment (D-100, `docs/design-decisions.md:1946`). diff --git a/docs/audit/stage5-preflight-dc0-20260730.txt b/docs/audit/stage5-preflight-dc0-20260730.txt new file mode 100644 index 0000000..1d56848 --- /dev/null +++ b/docs/audit/stage5-preflight-dc0-20260730.txt @@ -0,0 +1,237 @@ +PREFLIGHT TARGET: DC=vr1-dc0 (override: DC=vr1-dc1 bash scripts/preflight.sh) + Every gate below is run against THIS DC; the verdict line repeats it. +================ P1: repo lint ================ + [WARN] L1 docs/design-decisions.md: 239 non-ASCII byte(s) (legacy D-001..018 carve-out; NEW entries must be ASCII) + +WARN: repo lint (0 fail, 1 warn, 627 files scanned) +================ P2: bundle invariants ================ + validating the MERGED vr1-dc0 deploy input: bundle.yaml --overlay overlays/vr1-dc0-vips.yaml --overlay overlays/vr1-dc0-machines.yaml --overlay overlays/vr1-dc0-octavia-pki.yaml --dc vr1-dc0 + [ok] 11 charms bind public->provider-public; none on provider-vip + [ok] 13 clustered VIP(s) are provider/admin/internal, octet 50-99 (13 dual-family) + [ok] ovn-chassis bridge-interface-mappings: 2 well-formed MAC(s) (role-sep; VR0 set N/A) + [ok] 108 relations well-formed (explicit endpoints, all apps exist) + [ok] mysql-innodb-cluster num_units=3 (D-062) + [ok] 12 hacluster principal(s) all carry a VIP (R11) + [ok] 12 hacluster subordinate(s) declare cluster_count == principal num_units + [ok] keystone policyd-override wired in-bundle; zip content matches source (DOCFIX-071) + [ok] machines block: all 9 machine(s) tagged openstack-vr1-dc0, matching --dc vr1-dc0 + [ok] placement: role-separated (3 control/2 compute/4 storage); anti-affinity + role placement + counts OK + +PASS: Pattern A / D-052-D-053 bundle invariants (bundle.yaml) +================ P3: channel assert (charmhub) ================ + [ok] barbican 2024.1/stable (barbican) + [ok] barbican-vault 2024.1/stable (barbican-vault) + [ok] ceph-mon squid/stable (ceph-mon) + [ok] ceph-osd squid/stable (ceph-osd) + [ok] ceph-radosgw squid/stable (ceph-radosgw) + [ok] ceph-rbd-mirror squid/stable (ceph-rbd-mirror) + [ok] cinder 2024.1/stable (cinder) + [ok] cinder-backup 2024.1/stable (cinder-backup) + [ok] cinder-ceph 2024.1/stable (cinder-ceph) + [ok] designate 2024.1/stable (designate) + [ok] designate-bind 2024.1/stable (designate-bind) + [ok] glance 2024.1/stable (glance) + [ok] glance-simplestreams-sync 2024.1/stable (glance-simplestreams-sync) + [ok] hacluster 2.4/stable (keystone-hacluster, glance-hacluster, neutron-api-hacluster, nova-cloud-controller-hacluster, placement-hacluster, openstack-dashboard-hacluster, cinder-hacluster, octavia-hacluster, barbican-hacluster, magnum-hacluster, ceph-radosgw-hacluster, designate-hacluster) + [ok] keystone 2024.1/stable (keystone) + [ok] magnum 2024.1/stable (magnum) + [ok] magnum-dashboard 2024.1/stable (magnum-dashboard) + [ok] memcached latest/stable (memcached) + [ok] mysql-innodb-cluster 8.0/stable (mysql-innodb-cluster) + [ok] mysql-router 8.0/stable (vault-mysql-router, keystone-mysql-router, glance-mysql-router, ncc-mysql-router, placement-mysql-router, neutron-api-mysql-router, cinder-mysql-router, dashboard-mysql-router, octavia-mysql-router, barbican-mysql-router, magnum-mysql-router, designate-mysql-router) + [ok] neutron-api 2024.1/stable (neutron-api) + [ok] neutron-api-plugin-ovn 2024.1/stable (neutron-api-plugin-ovn) + [ok] nova-cloud-controller 2024.1/stable (nova-cloud-controller) + [ok] nova-compute 2024.1/stable (nova-compute) + [ok] octavia 2024.1/stable (octavia) + [ok] octavia-dashboard 2024.1/stable (octavia-dashboard) + [ok] octavia-diskimage-retrofit 2024.1/stable (octavia-diskimage-retrofit) + [ok] openstack-dashboard 2024.1/stable (openstack-dashboard) + [ok] ovn-central 24.03/stable (ovn-central) + [ok] ovn-chassis 24.03/stable (ovn-chassis, ovn-chassis-octavia) + [ok] placement 2024.1/stable (placement) + [ok] rabbitmq-server 3.9/stable (rabbitmq-server) + [ok] vault 1.8/stable (vault) + +PASS: channel assert (33 pins, 0 fail, 0 warn) +================ P4: live pre-flight (MAAS/overlay/nodes) ================ + +=== DC selection === +PASS: gating DC=vr1-dc0 (planes 10.12.4.0/22 .. 10.12.36.0/22; 10 node(s)) + +=== Repo (informational) === +NOTE: REPO=/home/jessea123/openstack-caracal-dc-dc +NOTE: HEAD: c58bf95 GA-R4 session close: F9 closed live, the reissue tool, P7, lib-identity +NOTE: working tree clean + +=== CHECK 0: per-DC octavia-pki overlay (no key material printed) === +PASS: overlay present with 5 lb-mgmt-* keys +PASS: overlay ASCII clean + +=== CHECK 1: bundle VIPs -- v4 triple or R2 dual-family sextet, .50-.99 (provider/admin/internal) === +PASS: vip: line count = 13 (from overlays/vr1-dc0-vips.yaml) +PASS: aligned VIPs OK=13 bad=0 (DC=vr1-dc0 bands 10.12.4/10.12.8/10.12.12) + +=== MAAS reachability gate (read-only) === +PASS: MAAS reachable (profile=admin) + +=== CHECK 3: six planes resolved BY CIDR (id/vid/gw/dns) === + provider-public 10.12.4.0/22 id=7 vid=0 gw=10.12.4.1 dns=[] + metal-admin 10.12.8.0/22 id=6 vid=0 gw=none dns=["10.12.8.3"] + metal-internal 10.12.12.0/22 id=12 vid=0 gw=none dns=[] + data-tenant 10.12.16.0/22 id=13 vid=0 gw=none dns=[] + storage 10.12.32.0/22 id=14 vid=0 gw=none dns=[] + replication 10.12.36.0/22 id=15 vid=0 gw=none dns=[] +PASS: all six planes present (by CIDR) +PASS: metal-internal is UNTAGGED (vid 0) -- D-133 flat carve +NOTE: stale-NAME check is juju-side (run scripts/juju-spaces-check.sh after add-model) + +=== CHECK 2: data/storage NIC links BY CIDR (DC=vr1-dc0 role nodes; octet per D-134 band) === + == vr1-dc0-control-01 (nhg3nf, octet .100) == + enp3s0 -> 10.12.12.0/22 10.12.12.100 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.100 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.100 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.100 type=physical + == vr1-dc0-control-02 (ssyexn, octet .101) == + enp3s0 -> 10.12.12.0/22 10.12.12.101 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.101 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.101 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.101 type=physical + == vr1-dc0-control-03 (sk8c4d, octet .102) == + enp3s0 -> 10.12.12.0/22 10.12.12.102 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.102 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.102 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.102 type=physical + == vr1-dc0-compute-01 (dbcq8h, octet .120) == + enp3s0 -> 10.12.12.0/22 10.12.12.120 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.120 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.120 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.120 type=physical + == vr1-dc0-compute-02 (sgwfnb, octet .121) == + enp3s0 -> 10.12.12.0/22 10.12.12.121 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.121 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.121 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.121 type=physical + == vr1-dc0-storage-01 (kghggm, octet .150) == + enp3s0 -> 10.12.12.0/22 10.12.12.150 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.150 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.150 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.150 type=physical + == vr1-dc0-storage-02 (8mtpxq, octet .151) == + enp3s0 -> 10.12.12.0/22 10.12.12.151 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.151 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.151 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.151 type=physical + == vr1-dc0-storage-03 (sn6qda, octet .152) == + enp3s0 -> 10.12.12.0/22 10.12.12.152 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.152 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.152 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.152 type=physical + == vr1-dc0-storage-04 (xqqwdq, octet .153) == + enp3s0 -> 10.12.12.0/22 10.12.12.153 type=physical + enp4s0 -> 10.12.16.0/22 10.12.16.153 type=physical + enp5s0 -> 10.12.32.0/22 10.12.32.153 type=physical + enp6s0 -> 10.12.36.0/22 10.12.36.153 type=physical +NOTE: vr1-dc0-juju-01 (7n87bt, octet .5) is D-134 utility-band infrastructure, not an OpenStack role node -- data-plane carve not asserted + +=== CHECK 4: DC=vr1-dc0 OpenStack role nodes -- status / power === + vr1-dc0-control-01 -> wired-thrush Ready power=off +PASS: vr1-dc0-control-01 Ready + vr1-dc0-control-02 -> ace-robin Ready power=off +PASS: vr1-dc0-control-02 Ready + vr1-dc0-control-03 -> real-filly Ready power=off +PASS: vr1-dc0-control-03 Ready + vr1-dc0-compute-01 -> keen-dove Ready power=off +PASS: vr1-dc0-compute-01 Ready + vr1-dc0-compute-02 -> superb-piglet Ready power=off +PASS: vr1-dc0-compute-02 Ready + vr1-dc0-storage-01 -> first-oryx Ready power=off +PASS: vr1-dc0-storage-01 Ready + vr1-dc0-storage-02 -> wise-stud Ready power=off +PASS: vr1-dc0-storage-02 Ready + vr1-dc0-storage-03 -> alert-cub Ready power=off +PASS: vr1-dc0-storage-03 Ready + vr1-dc0-storage-04 -> moral-salmon Ready power=off +PASS: vr1-dc0-storage-04 Ready + +Summary: 0 fatal, 0 warning +================ P5: credential matrix (D-137 tier 1 + tier 2 local) ================ +=== creds-matrix: tier 1 (STATIC) === +=== creds-matrix: tier 2 (EXISTENCE) === + (host: voffice1) + [ok] S1 schema: 101 rows, all enums valid, site-keys region-qualified, no duplicate (id,site,host-role,filename) + [ok] S3 render: 3 source field(s) SKIPPED -- rendering them needs the declared path from creds-manifests/vm-secret-locations (ruling 3); the list now EXISTS but the source-field derivation is not wired + [ok] S3 render drift: rendered row fields (mode, source) match checked-in; header prose and non-jumphost rows are OUT OF SCOPE of this compare + [ok] S4 mint-ref: every script:/runbook: reference resolves to a real location + [ok] S4 provenance debt: 30 row(s) are mint-ref=operator-terminal -- NOT reproducible from the repo (research FINDING 1). Admitted by design; converting them is remediation, not a checker fix. + [ok] S7 notes: 37 note key(s) referenced, all resolve, none orphaned + [ok] E0 jumphost location '~/vr1-office1-creds/*' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '~/vr1-dc0-creds/*' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '~/vr1-dc1-creds/*' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '~/vault-init/*' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '~/tenant-*/*' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '/home/jessea123/openstack-caracal-dc-dc/opentofu/terraform.tfstate' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '/home/jessea123/openstack-caracal-dc-dc/opentofu/terraform.tfstate.backup' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '/home/jessea123/openstack-caracal-dc-dc/opentofu/terraform.tfstate.pre-*' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 jumphost location '~/admin-openrc' NOT PROBED -- role 'jumphost' lives on 'vcloud' and this run is on 'voffice1'; probing it here would measure a different host's filesystem, so absence is not asserted over it + [ok] E0 8 remote location(s) SKIPPED -- rerun with --remote to include the headend shadow stores (SEC-022) and the region secrets dir (SEC-020) + [ok] E1 71 expected artifact(s) NOT JUDGED -- their role (headend/-, headend/vr1-dc0, headend/vr1-dc1, headend/vr1-office1, jumphost/-, jumphost/vr1-dc0, jumphost/vr1-dc1, jumphost/vr1-office1, netbox/vr1-office1) has at least one location that could not be probed, so absence cannot be asserted over it + [ok] E1/E3 existence: every expected artifact present and nothing undeclared, across 0 fully-probed role(s) + [ok] tier 3 (VALIDITY) NOT RUN -- pass --tier3 (with --tier2) to compare cross-copy sha256 provenance + [FAIL] S2 vr1-dc0 EXPECTED-BUT-ABSENT: 'opnsense-api.txt' (id dc0-edge-api, SEC-021) is expected by the matrix but NOT declared in the manifest -- the credential is either missing or undeclared + [FAIL] S5 ASYMMETRY: vr1-dc0 declares id=dcN-maas-power-key file=id_ed25519 on headend (custody=off-manifest-known) with no counterpart in vr1-dc1 -- a per-DC credential must exist at BOTH DCs in the same shape + [FAIL] S5 ASYMMETRY: vr1-dc0 declares id=dcN-maas-power-key file=maas-virsh_ed25519 on headend (custody=off-manifest-known) with no counterpart in vr1-dc1 -- a per-DC credential must exist at BOTH DCs in the same shape + [FAIL] S5 ASYMMETRY: vr1-dc1 declares id=dcN-maas-power-key file=id_dcN_power on headend (custody=off-manifest-known) with no counterpart in vr1-dc0 -- a per-DC credential must exist at BOTH DCs in the same shape + [FAIL] S6 IDENTITY CONFLATION: id 'maas-region-admin' serves 2 principal types (human via gui; service via api, cli-profile) -- ruling 5 requires one identity to serve one principal type + [FAIL] E4 UNCHECKABLE: 2 row(s) have no declared location for their (role, site) and can never be verified -- add a location row or correct the matrix: capi-mgmt-kubeconfig 'config' (cloud/-); rbd-mirror-peer-token 'rbd-mirror-bootstrap-token' (unit/-) + +FAIL: creds-matrix tier 1 -- 101 row(s), 19 check group(s) clean, 6 finding(s) +================ P7: Octavia amphora PKI ================ +=== octavia-pki verify: vr1-dc0 === + ok host: 'voffice1' is the declared headend, so its filesystem is the right one to measure + (expect CA label 'VR1 DC0'; provider VIP v4=10.12.4.57 v6=2602:f3e2:f02:11::57) + ok A1 workspace present: ~/octavia-pki/vr1-dc0 + ok A2 all 10 expected artifacts present + ok A3 private issuing-ca/passphrase.txt is 0600 + ok A3 private issuing-ca/issuing-ca.key.enc is 0600 + ok A3 private controller-ca/passphrase.txt is 0600 + ok A3 private controller-ca/controller-ca.key.enc is 0600 + ok A3 private controller/controller.key is 0600 + ok A3 private controller/controller.bundle.pem is 0600 + ok A3 cert issuing-ca/issuing-ca.cert.pem is 600 -- not group/world writable + ok A3 cert controller-ca/controller-ca.cert.pem is 600 -- not group/world writable + ok A3 cert controller-ca/controller-ca.cert.srl is 600 -- not group/world writable + ok A3 cert controller/controller.cert.pem is 600 -- not group/world writable + ok A4 issuing CA subject names this DC: contains 'VR1 DC0 Omega Cloud Octavia Issuing CA' + ok A5 controller CA subject names this DC: contains 'VR1 DC0 Omega Cloud Octavia Controller CA' + ok A6 issuing CA self-signature verifies + ok A7 controller CA self-signature verifies + ok A8 controller cert verifies against the CONTROLLER CA + ok A8 controller cert correctly does NOT verify against the issuing CA + ok A9 SAN carries 2 DNS names + ok A9 SAN carries this DC's provider v4 VIP (10.12.4.57) + ok A9 SAN carries this DC's provider v6 VIP (2602:f3e2:f02:11::57) + ok A12 DNS SANs are INERT -- os-public-hostname is set in no deploy artifact (B5 IP-only), so nothing resolves them; this assertion ARMS ITSELF when D-106 sets it + ok A12 DNS SANs are all in this DC's expected zone 'omega.dc0.vr1.cloud.neumatrix.local' + ok A13 controller cert CN is 'octavia-controller.omega.dc0.vr1.cloud.neumatrix.local' + ok A14 controller.key and controller.cert.pem carry the SAME public key (they are a pair) + ok A14 bundle carries exactly one CERTIFICATE block and one PRIVATE KEY block + ok A14 the bundle's CERTIFICATE block is byte-identical to controller.cert.pem + ok A14 the bundle's PRIVATE KEY block is byte-identical to controller.key + ok A15 controller cert carries keyUsage (critical: digitalSignature, keyEncipherment) and EKU (clientAuth, serverAuth) + ok A16 controller cert is valid and not expiring within 30 days + ok A10 overlay is 0600 + ok A10 overlay declares 5 lb-mgmt-* keys + ok A10 overlay is ASCII clean + ok A10 overlay is gitignored (F4) + ok A17 the overlay's controller cert and CA values decode byte-identically to this workspace's bundle and controller CA + ok A11 all 3 compared artifacts differ from vr1-dc1 -- per-DC independence holds + +octavia-pki verify (vr1-dc0): PASS -- 37 assertion(s), 0 failed + [ok] P7 octavia PKI verified for vr1-dc0, and its DNS SANs are in this DC's own zone +================ P6: stage-2 reminders (NOT run here) ================ + - after 'juju add-model': bash scripts/juju-spaces-check.sh + - with sudo: bash scripts/osd-blank-check.sh + - phase-01 Step 1.2: juju deploy --dry-run (plan: 50 apps / 97 relations) + +PREFLIGHT: FAIL (DC=vr1-dc0) -- do NOT deploy diff --git a/docs/changelog-20260730-stage5-open.md b/docs/changelog-20260730-stage5-open.md new file mode 100644 index 0000000..284d225 --- /dev/null +++ b/docs/changelog-20260730-stage5-open.md @@ -0,0 +1,79 @@ +# Changelog 2026-07-30 (part 3) -- STAGE 5 OPENED: the Juju deployment + +Session changelog part 3 (part 1 = `changelog-20260730-docfix205-d117-annotation.md`, +part 2 = `changelog-20260730-octavia-reissue-tool.md`). Branch +`dc-dc-stage5-preconditions`. Status claims live ONLY in `docs/CURRENT-STATE.md`. + +**Trigger.** The standing operator directive recorded at the 2026-07-30 part-2 close: +"we have to continue to juju deployment next session no matter what". This session opens +Stage 5 and runs the deployment. + +**No new D-number (GA-R3).** Opening a stage is OPS; the P5 acceptance is an operational +gate disposition against existing SEC rows, not architecture. Next-free UNCHANGED: +D 138 / DOCFIX 206 / BUNDLEFIX 053. + +--- + +## Operator rulings recorded (GA-R5, one exchange each, verbatim) + +1. **P5 GATE** -- **"Accept and proceed to deploy (Recommended)".** Question as presented + and the full consequence text are in `docs/CURRENT-STATE.md` section 1 (the status + authority). The six enumerated findings are accepted, known, pre-existing exposure; + `preflight.sh` continues to exit FAIL on P5 for the stage's duration and that RED is + ruled-accepted. The acceptance covers those six and nothing else. + +--- + +## Items + +### 1. Stage 5 OPENED; the P5 acceptance ruling recorded; entry gate captured + +**What.** `docs/CURRENT-STATE.md` section 1 gains the Stage-5 OPEN entry: the branch +decision and why, the measured entry gate, the P5 ruling with the question and the +operator's exact utterance, and one logged-not-executed finding. New capture +`docs/audit/stage5-preflight-dc0-20260730.txt` (237 lines, `DC=vr1-dc0 bash +scripts/preflight.sh` run ON voffice1, exit 1). + +**Why (evidence).** GA-R1/C1 puts the status change and the document update in one commit; +GA-R5 requires the ruling committed and pushed before dependent work. Four read-only +checks were made BEFORE putting the question, so it was asked once and asked grounded: + +- **Both clones at `c58bf95`, same branch, clean.** voffice1 was found on a 105-commit-stale + retired branch at the 2026-07-27 close and the "back to `main` at merge" follow-up never + fired, because nothing merged. Verified rather than assumed: a stale clone silently + deploys the wrong bundle. +- **Preflight run ON voffice1, not here.** P5 was found probing the wrong host's filesystem + on 2026-07-30 (34 findings vs the true 7), P7 is headend-only, and one gate was found RED + on the only host that deploys. A vcloud reading is not the gate reading. +- **Deploy artifacts verified as FILES** (`bundle.yaml` VR1 9-node role-separated; both + per-DC `-vips`/`-machines`/`-octavia-pki` overlays present, the PKI pair `0600` and + gitignored). This is the standing "RULED IS NOT BUILT -- check the artifact" rule applied + to the 2026-07-24 committee record, which is now superseded by measurement. +- **The deploy-order ruling was READ, not taken from its summary** (`CURRENT-STATE.md:986`). + There is no ruled DC ordering; dc1-first artifacts are not a divergence. + +**Revert.** `git revert ` -- it removes the Stage-5 OPEN entry, the recorded +ruling and the capture reference. The capture file itself can be deleted separately; it is +evidence, not configuration, and nothing reads it. Reverting the ruling does NOT un-ask the +question: re-asking would need a fresh GA-R5 exchange. + +### 2. LOGGED, NOT EXECUTED -- `ceph-osd` carries the stale VR0 constraint `tags=openstack` + +**What.** `bundle.yaml:592`. Recorded in `docs/CURRENT-STATE.md` section 1; no edit made. + +**Why (evidence).** `ceph-osd` is the ONLY application of 56 carrying a tag constraint -- +every other reads `arch=amd64` alone (parsed from `bundle.yaml`, not grepped). The tag is +measured ABSENT from the VR1 region: `maas admin tags read` returns `virtual`, +`pod-console-logging`, `serial-console`, `openstack-vr1-dc0`, `openstack-vr1-dc1`, `control`, +`compute`, `storage`, `juju-controller-vr1-dc0`, `juju-controller-vr1-dc1` -- no bare +`openstack`. Neither machines overlay overrides it (`vr1-dc0-machines.yaml` is +`applications:`-only and says so). + +**What is NOT measured, and is labelled as such.** `ceph-osd` has explicit placement +(`to: ["5","6","7","8"]`), so the initial deploy is EXPECTED to place by machine id +regardless. The reasoned-not-measured exposure is a later unplaced `juju add-unit ceph-osd` +matching no machine. The real impact is observable at Step 4.2's `--dry-run` and nowhere +earlier, which is why it is recorded now and decided there. Hard rule 1 forbids fixing it +mid-step, and the standing rule is that a finding is an observation, not a conclusion. + +**Revert.** Nothing to revert -- no artifact was changed.