Make intra-cluster NOTIFY loop-free (TSIG-keyed allow-notify, no pod IPs in restart config) #15
Reference in New Issue
Block a user
Delete Branch "benvin/notify-fix-loopfree"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
v0.2.5 (PR #14) added an options-scope
allow-notify { <primaryPodIP>; <transferAddr>; }on secondaries so intra-cluster NOTIFYs (which egress with the primary's pod IP as source, since k8s Services only NAT inbound) would be accepted. But options-scope config feeds the config-hash annotation that rolls the StatefulSet. So:The production deployment was reverted to v0.2.4 (argocd revert #291); the v0.2.5 code stayed on
main. This PR fixes it in place for v0.2.6.Constraint learned: nothing rendered into restart-scoped (config-hash) config may depend on pod IPs.
Chosen design — A: TSIG-signed NOTIFYs, fully static secondary config
allow-notify { key "<name>"; };— an address-match-list key element with NO IPs. It depends only on the key name, so pod-IP churn can never change the render, the hash, or trigger a restart. (BIND 9.20 accepts akeyelement in an address-match-list.)also-notifyentries (already enumerating replica pod IPs, applied viarndc addzone/modzonewith no restart) now carrykey "<name>":also-notify { <replicaIP> key "<name>"; ... };. (BIND 9.20 supports keyedalso-notifyentries.)BindCatalogZone.spec.transferKeyRef). Secondaries already present this key for AXFR (it is in the secondary'scatalog-zones default-primaries { <ip> key "<name>"; }), it is materialised intokeys.confon every pod (primary and secondary), and the primary already requiresallow-transfer { key "<name>"; }. No new key plumbing — the cluster's existing replication key doubles as the NOTIFY key.Why this is loop-free
also-notifylives in zone-scope config applied via rndc (BindZoneReconciler.buildZoneConfig→Exec.AddZone), which never touches named.conf and never rolls pods — so listing pod IPs there is safe. The only pod-IP-bearing input was the v0.2.5 options-scopeallow-notify; it is gone.RenderInputno longer has any pod-IP field.Regression test (permanent, loop class killed)
TestConfigHashIndependentOfPrimaryPodIP(controller): reconciles the ConfigMap with the primary pod on two different IPs (stable primary Service ClusterIP held constant) and asserts the config-hash is byte-identical. Fault-injection verified: reintroducing any primary-pod-IP dependency into restart-scoped config makes this test FAIL.TestRenderRestartScopedConfigIndependentOfPodIPs+TestRenderSecondaryAllowNotifyByKey(render): assert no pod/service IP appears inallow-notifyand the render is stable.go build ./...,go test ./...,go vet ./..., gofmt — all clean.Rollout
Tag
v0.2.6→ bump the argocd image. The deployment is currently pinned to v0.2.4 by revert #291; the bump to v0.2.6 re-enables immediate intra-cluster NOTIFY without the roll loop. (This PR does not tag or release.)61324ae89atoaab11457af