Skip to content

fix(annotations)!: require --annotation-prefix to be set explicitly to prevent silent DNS record deletion#6476

Open
ivankatliarchuk wants to merge 17 commits into
kubernetes-sigs:masterfrom
gofogo:fix/require-explicit-annotation-prefix-to-prevent-silent-dns-deletion
Open

fix(annotations)!: require --annotation-prefix to be set explicitly to prevent silent DNS record deletion#6476
ivankatliarchuk wants to merge 17 commits into
kubernetes-sigs:masterfrom
gofogo:fix/require-explicit-annotation-prefix-to-prevent-silent-dns-deletion

Conversation

@ivankatliarchuk

@ivankatliarchuk ivankatliarchuk commented Jun 6, 2026

Copy link
Copy Markdown
Member

What does it do ?

Relates #6424
Relates #6449

  • --annotation-prefix is now a required flag with no default; omitting it causes a hard startup failure via config validation
  • The validation error message explains the breaking prefix change and gives both migration paths (old prefix for unmigrated clusters, new prefix once migration is complete)
  • NewConfig() now returns a true zero-value struct — all defaults belong in flag binding, not the constructor
  • StringMapVar in the flag binder initializes nil maps before registering with kingpin, removing the need for any map pre-initialization in NewConfig()
  • Tests updated throughout to pass --annotation-prefix explicitly, reflecting the new required-flag contract

Motivation

  • The default annotation prefix changed from external-dns.alpha.kubernetes.io/ to external-dns.kubernetes.io/ with no migration gate
  • Users upgrading without updating their resource annotations would silently lose all DNS records: the controller would see owned TXT records but no sources claiming them, triggering deletion
  • The failure was completely silent — no error, no warning, just records deleted on the first sync loop
  ┌───────────────────────────────────┬──────────────────────────────────────────────────┬──────────────────────────────────────────────────────┐
  │             Dimension             │      Default (external-dns.kubernetes.io/)       │             Empty (required, our change)             │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Startup with no flag set          │ Silently continues                               │ Hard fails with actionable error                     │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Upgrade experience                │ Transparent — DNS records deleted with no signal │ Deployment fails to start — no sync loop runs        │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ DR risk                           │ High — deletion happens before anyone notices    │ None — nothing runs until operator acts              │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Time to detect                    │ After DNS records are already gone               │ Immediately at pod startup                           │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Operator action required          │ None — that's the problem                        │ Explicit flag must be set                            │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Helm/GitOps rollout               │ Rolls out successfully, deletes records          │ Rollout fails, old pod stays up (if rolling update)  │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Migration path clarity            │ None — no signal that a migration exists         │ Error message explains both paths                    │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Backward compat with alpha prefix │ Broken silently                                  │ Broken loudly — same end state, different visibility │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Future default restoration        │ N/A (already defaulted)                          │ Possible once ecosystem has migrated                 │
  ├───────────────────────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤
  │ Blast radius                      │ All DNS records for unmigrated clusters          │ Zero — nothing changes until operator intervenes     │
  └───────────────────────────────────┴──────────────────────────────────────────────────┴──────────────────────────────────────────────────────┘

More

  • Yes, this PR title follows Conventional Commits
  • Yes, I added unit tests
  • Yes, I updated end user documentation accordingly
Screenshot 2026-06-06 at 17 43 03 Screenshot 2026-06-06 at 17 43 52

… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@k8s-ci-robot k8s-ci-robot requested review from szuecs and u-kai June 6, 2026 16:36
@k8s-ci-robot k8s-ci-robot added apis Issues or PRs related to API change controller Issues or PRs related to the controller labels Jun 6, 2026
@ivankatliarchuk ivankatliarchuk changed the title fix(annotations): require --annotation-prefix to be set explicitly to prevent silent DNS record deletion fix(annotations)!: require --annotation-prefix to be set explicitly to prevent silent DNS record deletion Jun 6, 2026
@k8s-ci-robot k8s-ci-robot added internal Issues or PRs related to internal code size/S Denotes a PR that changes 10-29 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jun 6, 2026
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Jun 6, 2026
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@k8s-ci-robot k8s-ci-robot added scripts Issues or PRs related to internal scripts size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jun 6, 2026
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@coveralls

coveralls commented Jun 6, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 27496709866

Coverage decreased (-0.06%) to 81.585%

Details

  • Coverage decreased (-0.06%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 37 coverage regressions across 3 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

37 previously-covered lines in 3 files lost coverage.

File Lines Losing Coverage Coverage
execute.go 33 66.67%
flags/binders.go 2 95.74%
controller.go 2 93.39%

Coverage Stats

Coverage Status
Relevant Lines: 21005
Covered Lines: 17137
Line Coverage: 81.59%
Coverage Strength: 1484.22 hits per line

💛 - Coveralls

… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@ivankatliarchuk

Copy link
Copy Markdown
Member Author

I've added file scripts/migrate-annotation-prefix.sh. However, I'm not sure if we should provide anything. As we have no idea how end users environments looks like. Too many ways to deploy things to kubernetes.

@mloiseleur

Copy link
Copy Markdown
Collaborator

I've added file scripts/migrate-annotation-prefix.sh. However, I'm not sure if we should provide anything.

Nowadays, there are so many ways to send resources
=> I think we should not provide a migration tool.

That said, helping our users in this migration is a good idea 👍.

🤔 Instead of providing a migrate-annotation-prefix.sh, wdyt of providing a list-annotated-resources.sh that would list resources with previous or current annotations? Something to help users to choose its prefix and get a quick view of how many resources should be updated.

@ivankatliarchuk

Copy link
Copy Markdown
Member Author

Instead of providing a migrate-annotation-prefix.sh, wdyt of providing a list-annotated-resources.sh that would list resources with previous or current annotations? Something to help users to choose its prefix and get a quick view of how many resources should be updated.

Agree on that. I was thinking same way. Will re-do it

… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
… prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@ivankatliarchuk

Copy link
Copy Markdown
Member Author

Made the script read only, it will output only resources and annotations that needs adding

Comment thread pkg/apis/externaldns/types.go Outdated
ivankatliarchuk and others added 2 commits June 10, 2026 21:27
…o prevent silent DNS record deletion

Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com>
…o prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>

@mloiseleur mloiseleur left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@k8s-ci-robot k8s-ci-robot added lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 10, 2026
…prevent-silent-dns-deletion

* master:
  test(source): assert RefObject via ValidateEndpoints opt-in (kubernetes-sigs#6493)
  feat(source): attach RefObject to remaining sources (kubernetes-sigs#6492)
  fix: allow releasing helm charts with immutable releases turned on  (kubernetes-sigs#6477)
  fix(coredns): return AAAA for IPv6 targets (kubernetes-sigs#6489)
  feat(source): add --fqdn-* flag support to gloo-proxy source (kubernetes-sigs#6475)
  chore(deps): bump the dev-dependencies group with 22 updates (kubernetes-sigs#6488)
  test(source): fix flaky unstructured source test (kubernetes-sigs#6483)
  feat(source): add --fqdn-* flag support to f5-virtualserver and f5-transportserver sources (kubernetes-sigs#6470)
  refactor: use Set structs instead of map[]struct{} (kubernetes-sigs#6360)
  refactor: use Set structs instead of map[]struct{} (kubernetes-sigs#6360)
  feat(source): migrate ingress and node sources to Indexers pattern (kubernetes-sigs#6445)
  ci(e2e): use rollout status for etcd instead of kubectl wait (kubernetes-sigs#6474)
  docs(ai): add instructions for agents (kubernetes-sigs#6453)
  refactor(endpoint): add WithAliasProperty and replace alias string literals (kubernetes-sigs#6455)
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 14, 2026
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@k8s-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from mloiseleur. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

…o prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 14, 2026
…o prevent silent DNS record deletion

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apis Issues or PRs related to API change cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. controller Issues or PRs related to the controller docs internal Issues or PRs related to internal code scripts Issues or PRs related to internal scripts size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants