feat(conformance): L0 guard that the external-dns annotationPrefix matches the tree
gate / gate (pull_request) Successful in 2m58s
gate / conformance (pull_request) Skipped

Add assertion (8) to internal-services-publish-no-public-dns. The external-dns
HelmRelease must declare annotationPrefix explicitly, and every
external-dns annotation in apps/, platform/, runbooks/ and catalog/render.py
must use that prefix. The v0.23.0 default-prefix change on 2026-11-07
ignored the controller: none, target and hostname annotations while
assertions (1)-(3) stayed green.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 5.5 committed 2026-11-07 17:56:12 -06:00
1 parent 267446c68f
commit 9c51f60a35
2 files changed
+128 -6

No files matched your search

@@ -0,0 +1,51 @@
---
date: 2026-11-07
branch: feat/l0-externaldns-annotation-prefix
title: L0 guard — external-dns annotationPrefix must match every external-dns annotation in the tree
---
## What changed
`conformance/tests/l0-static/internal-services-publish-no-public-dns/check.sh` gains assertion
(8). The check is already whole-repo-scoped, so it runs on every gate.
- **(8a)** `platform/externaldns/helmrelease.yaml` must set `values.annotationPrefix` explicitly,
and it must equal the check's `ANNOTATION_PREFIX` (`external-dns.alpha.kubernetes.io/`). The
check does not trust the upstream default, because that default is what changed.
- **(8b)** `extraArgs` must not carry `--annotation-prefix` or `--enable-legacy-annotation-prefix`,
so the prefix has one declared place.
- **(8c)** Every external-dns-looking annotation key under apps/, platform/ and runbooks/ must use
that prefix. The match is any `external-dns(.x)*.kubernetes.io/` key.
- **(8d)** catalog/render.py must emit no external-dns key under any other prefix.
`CONTROLLER_KEY` and `HOSTNAME_KEY` are now derived from `ANNOTATION_PREFIX`. The Service
inventory matches any external-dns prefix variant, not only the alpha one.
Why: on 2026-11-07, external-dns v0.23.0 (whose default prefix is GA) ignored every alpha
annotation. Assertions (1) to (3) stayed green, because they prove the annotations are present,
not that the controller reads them. See `decisions/2026-11-07-public-dns-wan-a-record.md`.
This branch is stacked on `fix/public-dns-wan-a-record` (PR #140). Without that fix, (8a) fails,
which is correct. Merge #140 first.
## What I verified
Run on the host (PyYAML):
- the check passes on this tree: `check OK: 62 assertions passed`.
- it **fails (8a)** with origin/main's HelmRelease, which has no `annotationPrefix`.
- it **fails (8c)** when `platform/gateway/gateway.yaml`'s `target` key is changed to the GA
prefix.
Toolbox gate: see the PR description.
## What I did NOT verify
- Whether a future chart could read the prefix from somewhere other than `values.annotationPrefix`,
for example a renamed chart value. (8a) would then pass while the flag silently vanished from the
rendered args. Rendering the chart in the gate would close that gap. Not done: it needs network
access or a vendored chart in L0.
- `conformance/**` is a **sensitive path**. This PR needs the operator's approving review or
`/approve-override`. The agent did not post one.
- The header of the sibling chainsaw-test.yaml still says "external-dns v0.21.0". That is cosmetic
and I left it alone.