A franchised Sovereign now supports N parent zones, NOT one. The
operator brings 1+ parent domains at signup (`omani.works` for own
use, `omani.trade` for the SME pool, etc.) and may add more
post-handover via the admin console (#829).
bp-powerdns 1.2.0 (platform/powerdns/chart):
- New `zones: []` values key listing parent domains to bootstrap
- New Helm post-install/post-upgrade hook Job
(templates/zone-bootstrap-job.yaml) that POSTs each entry to
/api/v1/servers/localhost/zones at install time. Idempotent on
HTTP 409 — re-runs after upgrades or chart bumps never fail.
- Default-values render skips when zones is empty (legacy behavior).
bp-catalyst-platform 1.4.0 (products/catalyst/chart):
- New `parentZones: []` + `wildcardCert.{enabled,namespace,issuerName}`
values
- New templates/sovereign-wildcard-certs.yaml renders one
cert-manager.io/v1.Certificate per zone (each `*.<zone>` + apex)
via the letsencrypt-dns01-prod-powerdns ClusterIssuer. Each cert
renews independently. Skips entirely when parentZones is empty so
the legacy clusters/_template/sovereign-tls/cilium-gateway-cert.yaml
retains ownership of `sovereign-wildcard-tls` (avoids
helm-vs-kustomize ownership flap).
- New `catalystApi.{powerdnsURL,powerdnsServerID}` values threaded
into the catalyst-api Pod as CATALYST_POWERDNS_API_URL +
CATALYST_POWERDNS_SERVER_ID env vars.
catalyst-api (products/catalyst/bootstrap/api):
- New internal/powerdns package with typed Client (CreateZone,
ZoneExists). Idempotent on HTTP 409/412.
- handler.pdmCreatePowerDNSZone (issue #829's stub) now uses the
typed client when wired via SetPowerDNSZoneClient — the
admin-console "Add another parent domain" flow now creates real
zones in the Sovereign's PowerDNS at runtime.
- main.go wires the client when CATALYST_POWERDNS_API_URL +
CATALYST_POWERDNS_API_KEY are set.
- Comprehensive unit tests (client_test.go: 9 cases incl.
201/409/412/500 + custom NS + custom serverID).
Bootstrap-kit slot integration:
- clusters/_template/bootstrap-kit/11-powerdns.yaml: bumps to
bp-powerdns 1.2.0 and threads `zones: ${PARENT_DOMAINS_YAML}` from
Flux postBuild.substitute.
- clusters/_template/bootstrap-kit/13-bp-catalyst-platform.yaml:
bumps to bp-catalyst-platform 1.4.0 and threads `parentZones:
${PARENT_DOMAINS_YAML}` (same source-of-truth string so the two
slots stay in lockstep).
- infra/hetzner: new `parent_domains_yaml` Terraform variable
(defaults to single-zone array derived from sovereign_fqdn) →
cloud-init renders the PARENT_DOMAINS_YAML Flux substitute.
DoD verified end-to-end with helm template + envsubst:
- Multi-zone overlay (omani.works + omani.trade) renders 2
PowerDNS zone-create API calls in the bootstrap Job AND 2
Certificate resources (`*.omani.works`, `*.omani.trade`) in
bp-catalyst-platform.
- Single-zone fallback (PARENT_DOMAINS_YAML defaults to
`[{name: "<sov_fqdn>", role: "primary"}]`) keeps legacy
provisioning paths working without per-overlay edits.
Closes#827.
Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>