Skip to content

fix(source): skip pod DNS when PodIP is empty for IP-derived records#6376

Open
isumitsolanki wants to merge 3 commits intokubernetes-sigs:masterfrom
isumitsolanki:issue_6375
Open

fix(source): skip pod DNS when PodIP is empty for IP-derived records#6376
isumitsolanki wants to merge 3 commits intokubernetes-sigs:masterfrom
isumitsolanki:issue_6375

Conversation

@isumitsolanki
Copy link
Copy Markdown

What does it do ?

Skips pod-source endpoint generation whenever the record would be built from pod.Status.PodIP but that value is still empty (e.g. pod is Pending). This applies to internal hostname annotation, --pod-source-domain without explicit targets, and kops-dns-controller internal hostname. It avoids SuitableType("") producing a CNAME with an empty target; skips are logged at debug, consistent with hostsFromTemplate. Adds three TestPodSource table cases for pending pods with empty PodIP.

Motivation

Fixes #6375 — empty-target CNAMEs could block later A records at the same name (e.g. Azure Private DNS CNAME naming restriction).

More

  • Yes, this PR title follows Conventional Commits
  • Yes, I added unit tests
  • Yes, I updated end user documentation accordingly

Signed-off-by: Sumit Solanki <sumit.solanki@ibm.com>
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Apr 17, 2026
@k8s-ci-robot k8s-ci-robot requested a review from szuecs April 17, 2026 11:59
@k8s-ci-robot k8s-ci-robot requested a review from vflaux April 17, 2026 11:59
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

Welcome @isumitsolanki!

It looks like this is your first PR to kubernetes-sigs/external-dns 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-sigs/external-dns has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Apr 17, 2026
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

Hi @isumitsolanki. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Apr 17, 2026
@ivankatliarchuk
Copy link
Copy Markdown
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Apr 30, 2026
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 30, 2026

Coverage Report for CI Build 25158358874

Coverage increased (+0.005%) to 80.491%

Details

  • Coverage increased (+0.005%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 3 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

3 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
pod.go 2 97.33%
openshift_route.go 1 82.93%

Coverage Stats

Coverage Status
Relevant Lines: 21405
Covered Lines: 17229
Line Coverage: 80.49%
Coverage Strength: 1465.09 hits per line

💛 - Coveralls

Copy link
Copy Markdown
Member

@ivankatliarchuk ivankatliarchuk left a comment

Choose a reason for hiding this comment

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

The same pattern appears four times in pod.go — identical log message, identical condition

something like

 // addInternalHostnameAnnotationEndpoints
  if len(targets) == 0 && pod.Status.PodIP == "" {
      log.Debugf("skipping pod %q. PodIP is empty with phase %q", pod.Name, pod.Status.Phase)
      return
  }

  // addKopsDNSControllerEndpoints
  if pod.Status.PodIP == "" {
      log.Debugf("skipping pod %q. PodIP is empty with phase %q", pod.Name, pod.Status.Phase)
  }

  // addPodSourceDomainEndpoints
  if pod.Status.PodIP == "" {
      log.Debugf("skipping pod %q. PodIP is empty with phase %q", pod.Name, pod.Status.Phase)
  }

  // hostsFromTemplate (pre-existing)
  if address.IP == "" {
      log.Debugf("skipping pod %q. PodIP is empty with phase %q", pod.Name, pod.Status.Phase)
  }

A small helper could eliminate the repetition and have a common method

// returns false and logs if PodIP is empty
  func podIPReady(pod *v1.Pod) bool {
      if pod.Status.PodIP == "" {
          log.Debugf("skipping pod %q. PodIP is empty with phase %q", pod.Name, pod.Status.Phase)
          return false
      }
      return true
  }

Then the call sites become a single line each - e.g. if !podIPReady(pod) { return }

Comment thread source/pod.go Outdated
Comment thread source/pod.go Outdated
Comment thread source/pod.go Outdated
Comment thread source/pod_test.go
@ivankatliarchuk
Copy link
Copy Markdown
Member

Actually after review, a more robust fix would be a single check at the top of addPodEndpointsToEndpointMap

  func (ps *podSource) addPodEndpointsToEndpointMap(endpointMap map[endpoint.EndpointKey][]string, pod *v1.Pod) {
      if ps.ignoreNonHostNetworkPods && !pod.Spec.HostNetwork {
          log.Debugf("skipping pod %s. hostNetwork=false", pod.Name)
          return
      }
      if pod.Status.Phase != v1.PodRunning {
          log.Debugf("skipping pod %q. phase is %q", pod.Name, pod.Status.Phase)
          return
      }
      // ...
  }

This would cover all paths — current and future - with one guard instead of per-function checks. The trade-off is that it also skips Succeeded/Failed pods with explicit targets annotations (which currently still produce records), but that's arguably correct behavior anyway — a terminated pod shouldn't own DNS records.

@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 ivankatliarchuk. 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

@k8s-ci-robot k8s-ci-robot added 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 Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. docs ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pod source creates CNAME records with empty target when PodIP is not yet assigned

4 participants