Skip to content

fix(gateway-endpoint): keep receipted hostnames published through transient gateway reprogramming - #11

Merged
reoring merged 1 commit into
mainfrom
fix/gateway-endpoint-in-place
Sep 14, 2026
Merged

reoring merged 1 commit into
mainfrom
fix/gateway-endpoint-in-place

Conversation

@reoring

@reoring reoring commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Consumer of this controller: appthrust.dev PMC (appthrust-dns/dns-api-controller-manager, delivered by platform internal-delivery unit dns-api).

Problem

During a gateway-fleet reprogram cycle the project-wide EndpointRecordSet for pj-af59d1dc379b was deleted and recreated (creationTimestamp 13:44:52Z → 13:48:32Z → 13:54:01Z on 2026-09-14). All four hostnames behind that Gateway (payment.appthrust.dev among them) lost their A/AAAA records each time; resolver negative caching made every cycle a multi-minute outage.

Proven pre-fix path (unit test replay of observed hub states): route replaced with a new UID while the Gateway momentarily has no addresses → exact UID/generation receipt match fails → the accepted hostname is not retained without targets → len(targets)==0 swaps hostnames for the empty retained set → desired == nil → Delete.

Fix

See commit message. Withdrawal still requires an explicit current-generation Accepted=False, spec detachment, or route/Gateway deletion; Unknown/absent conditions and apply conflicts retain the receipted hostname and existing targets.

Verification

go test ./internal/go/apps/gatewayendpoint/... -count=1 ok, go vet ok, gofmt -l clean. New table tests replay: unknown Gateway acceptance + empty addresses, missing route parent status, route generation advanced before status is current, route replacement with new UID (receipt rebinds), update-conflict retry, and the negative case that an unreceipted new hostname is not published during address loss.

Platform pin follow-up: platform#3923 carries the operator side; the edge chart/image digests from this merge will be pinned in internal/controllers/internaldelivery/manifestsets/dns-api.json afterwards.

…nsient gateway reprogramming

A gateway-fleet reprogram cycle (route replaced with a new UID while the hub
Gateway briefly reports no addresses, or a route generation advancing before
its parent status is current) made endpointRecordSetsForGateway return no
desired EndpointRecordSet: the exact UID/generation receipt match failed, the
accepted hostname was not retained without targets, and the empty desired set
deleted the project-wide EndpointRecordSet. Every hostname behind that Gateway
(four in the observed project) then lost its A/AAAA records until the next
pass recreated the object, and resolver negative caching turned each cycle
into a multi-minute outage.

- A receipt for the same route UID at another generation retains the hostname
  while the new observation is pending.
- A replacement route (same name, new UID) inherits the receipt only once all
  its parent refs are currently Accepted, and rebinds it even while the
  Gateway has no addresses.
- A replacement Gateway is a new authority: the old receipt is not carried, but
  the current accepted binding publishes its own receipt in the same pass
  instead of leaving a one-reconcile delete gap.

Withdrawal still requires an explicit current-generation Accepted=False, spec
detachment, or route/Gateway deletion.
@reoring
reoring merged commit 3e56e5a into main Sep 14, 2026
2 checks passed
@reoring
reoring deleted the fix/gateway-endpoint-in-place branch September 14, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant