reconcile zone apex NS off the pod IP placeholder
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful

Add BindZone.spec.nameservers and sync the apex NS RRset on every reconcile.
This commit is contained in:
2026-09-26 18:27:11 +10:00
parent 03df5d56b4
commit 4a41cbc427
14 changed files with 346 additions and 39 deletions
+23 -10
View File
@@ -99,6 +99,8 @@ func (r *BindZoneReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
return r.setPhase(ctx, &zone, "Error", "ConfigError", err.Error())
}
nameservers := zoneNameservers(zone.Spec.Nameservers, cluster)
created := !r.Exec.ZoneExists(ctx, zone.Namespace, primaryPod, zone.Spec.ZoneName, zone.Spec.ViewRef)
if created && (zone.Spec.Type == bindv1alpha1.ZonePrimary || zone.Spec.Type == "") {
primaryIP := primaryPodIP(ctx, r.Client, cluster)
@@ -108,7 +110,7 @@ func (r *BindZoneReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
// The zone is absent from named's memory, but its database file and
// journal may still be on the PVC from a previous incarnation.
path := bind.ZoneFilePath(zone.Spec.ZoneName)
if err := r.Exec.EnsureSeedZone(ctx, zone.Namespace, primaryPod, zone.Spec.ZoneName, path, primaryIP); err != nil {
if err := r.Exec.EnsureSeedZone(ctx, zone.Namespace, primaryPod, zone.Spec.ZoneName, path, primaryIP, nameservers); err != nil {
return r.setPhase(ctx, &zone, "Error", "SeedFailed", err.Error())
}
}
@@ -116,18 +118,29 @@ func (r *BindZoneReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
return r.setPhase(ctx, &zone, "Error", "AddZoneFailed", err.Error())
}
// Seed static records (primary zones only).
// Sync the apex NS on every pass, not only at seed time, so an existing zone
// converges off the seed placeholder. Best-effort: a zone that permits no
// dynamic update keeps what it was seeded with rather than failing to
// reconcile.
recordCount := 0
if isPrimaryType(zone.Spec.Type) && len(zone.Spec.Records) > 0 {
creds, err := r.zoneUpdateCreds(ctx, &zone)
if err != nil {
return r.setPhase(ctx, &zone, "Error", "NoUpdateKey", err.Error())
if isPrimaryType(zone.Spec.Type) {
creds, credErr := r.zoneUpdateCreds(ctx, &zone)
if apex := apexNSUpdates(&zone, nameservers); len(apex) > 0 && credErr == nil {
if err := r.Exec.NSUpdate(ctx, zone.Namespace, primaryPod, zone.Spec.ZoneName, creds, apex); err != nil {
logger.V(1).Info("apex NS sync failed", "zone", zone.Spec.ZoneName, "err", err.Error())
}
}
updates := recordsToUpdates(zone.Spec.ZoneName, zone.Spec.Records, zone.Spec.DefaultTTL)
if err := r.Exec.NSUpdate(ctx, zone.Namespace, primaryPod, zone.Spec.ZoneName, creds, updates); err != nil {
return r.setPhase(ctx, &zone, "Error", "RecordUpdateFailed", err.Error())
// Seed static records.
if len(zone.Spec.Records) > 0 {
if credErr != nil {
return r.setPhase(ctx, &zone, "Error", "NoUpdateKey", credErr.Error())
}
updates := recordsToUpdates(zone.Spec.ZoneName, zone.Spec.Records, zone.Spec.DefaultTTL)
if err := r.Exec.NSUpdate(ctx, zone.Namespace, primaryPod, zone.Spec.ZoneName, creds, updates); err != nil {
return r.setPhase(ctx, &zone, "Error", "RecordUpdateFailed", err.Error())
}
recordCount = len(updates)
}
recordCount = len(updates)
}
// Register in the catalog so secondaries auto-provision.