ovn-central cert: root-caused, fix PROVEN live, and wired for redeploy
...
Root cause (measured, corrects the committed rdns_mode/binding framing):
charm-ovn-central derives its TLS common_name from get_hostname(its
metal-internal address); that plane is deliberately isolated (D-052) with no
reachable resolver, so the reverse lookup returns None -> empty CN -> vault
issues no server cert -> OVN cluster never forms. rdns_mode=2 and the PTR
exist; only the reverse is unreachable from the isolated plane.
Binding approach REFUTED live (3 configs): the charm uses the metal-internal
address regardless of which endpoint is rebound, and juju default-route
selection is not tied to the default binding. So the app STAYS on
metal-internal (D-052-correct for its OVSDB/certificates data type).
Fix PROVEN end-to-end (controlled single-unit test): an /etc/hosts reverse
entry -> CN populated -> vault issued ovn-central_0.server.cert ->
/etc/ovn/{cert_host,key_host,ovn-central.crt} written; control units without
it stayed broken. OVN imposes no CN-content rule; vault signs any non-empty CN.
Wired (verify-at-provision on the redeploy):
- NEW scripts/dc-node-etchosts.sh + tests/dc-node-etchosts (harness 9/9):
renders a per-DC cloudinit-userdata adding each node's metal-internal
address -> hostname to /etc/hosts at provision; CIDR derived from lib-net
(dc0 10.12.12.0/22, dc1 10.12.72.0/22). Rendered runcmd executed live and
correctly scoped to metal-internal.
- runbooks/phase-01-bundle-deploy.md Step 1.2b: gated pre-deploy step
(after add-model, before deploy), VR1-only.
- A NEW mechanism borrowing D-008's shape, not D-008 itself.
Records: reeval RESOLUTION + CURRENT-STATE RESOLVED+WIRED + changelog; the old
rdns_mode remediation is VOID. Gauntlet ALL GREEN (99), repo-lint 0 fail.
Live tests were reversible; model left at its captured before-state.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf