Skip to content

Add interval and Infoblox maxResults to ExternalDNS CR - #483

Open
sanjaytripathi97 wants to merge 11 commits into
openshift:mainfrom
sanjaytripathi97:add-infoblox-max-results-and-interval
Open

Add interval and Infoblox maxResults to ExternalDNS CR#483
sanjaytripathi97 wants to merge 11 commits into
openshift:mainfrom
sanjaytripathi97:add-infoblox-max-results-and-interval

Conversation

@sanjaytripathi97

@sanjaytripathi97 sanjaytripathi97 commented Jun 1, 2026

Copy link
Copy Markdown

Related issue

Customers integrating OpenShift External DNS Operator with Infoblox require two external-dns flags that were not exposed through the ExternalDNS CR:

  • --interval — controls how often external-dns synchronizes DNS records (reduces load on Infoblox)
  • --infoblox-max-results — sets the _max_results WAPI query parameter, required for Infoblox grids with thousands of DNS records.

Without these, operator-managed deployments only received a fixed set of hardcoded args. Manual patches to the Deployment were reverted on reconcile because the operator owns and reconciles container args.

This blocked successful Infoblox integration in enterprise environments and forced workarounds such as removing ownerReference from the Deployment (operator-unmanaged), which is unsupported and fragile.

With this PR, Expose both settings declaratively via the ExternalDNS CR and wire them through the operator deployment builder.

New CR fields

CR field external-dns flag Scope
spec.interval --interval All providers
spec.provider.infoblox.maxResults --infoblox-max-results Infoblox only
Both fields are optional. When omitted, external-dns uses its defaults (1 minute sync interval; no _max_results on WAPI requests).

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sanjaytripathi97, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e9dd2da-6497-42d6-8a19-a112977e698a

📥 Commits

Reviewing files that changed from the base of the PR and between 260dafe and 13f0516.

📒 Files selected for processing (7)
  • api/v1beta1/externaldns_types.go
  • bundle/manifests/external-dns-operator.clusterserviceversion.yaml
  • bundle/manifests/externaldns.olm.openshift.io_externaldnses.yaml
  • config/crd/bases/externaldns.olm.openshift.io_externaldnses.yaml
  • docs/usage.md
  • pkg/operator/controller/externaldns/deployment_test.go
  • test/e2e/operator_test.go
📝 Walkthrough

Walkthrough

Adds optional intervalSeconds and Infoblox maxResults fields to the ExternalDNS API and CRD with validation. The operator passes configured values as --interval and --infoblox-max-results container arguments. Unit tests cover unset and configured values. Samples and usage documentation include the new settings. Infoblox end-to-end coverage validates deployed arguments and synchronization timing.

Suggested reviewers: grzpiotrowski

🚥 Pre-merge checks | ✅ 13 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ipv6 And Disconnected Network Test Compatibility ⚠️ Warning New e2e test talks to Infoblox outside the cluster via tls.Dial/readServerTLSCert and WAPI creds, so it won't work in disconnected CI. Gate the test with [Skipped:Disconnected] or an explicit Infoblox-connectivity check so disconnected jobs skip it.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change by adding interval and Infoblox maxResults to the ExternalDNS CR.
Description check ✅ Passed The description is directly related to the changeset and accurately explains the new CR fields and wiring.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No Ginkgo titles were added; the new t.Run names are static strings and the e2e test name is deterministic.
Test Structure And Quality ✅ Passed No Ginkgo-style issues: the new tests use deferred cleanup, bounded PollUntilContextTimeout waits, and descriptive failures, matching repo patterns.
Microshift Test Compatibility ✅ Passed The new e2e test is a plain Test*, and it only uses Kubernetes resources plus Route-based ExternalDNS config; no MicroShift-forbidden APIs or HA assumptions appear.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PASS: The added e2e test is a plain testing.T test and only checks one running pod plus deployment args/logs; no multi-node/HA assumptions or SNO-sensitive scheduling logic.
Topology-Aware Scheduling Compatibility ✅ Passed Changed files only add args/CR fields; targeted searches found no affinity, nodeSelector, topology-spread, taint, or replica logic.
Ote Binary Stdout Contract ✅ Passed The PR only adds helper/test wiring; the changed init/setup paths don’t write to stdout, and existing TestMain/Infoblox prints predate this PR.
No-Weak-Crypto ✅ Passed Touched files only add interval/maxResults plumbing and tests; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons found.
Container-Privileges ✅ Passed No PR-added manifest sets privileged/host* or allowPrivilegeEscalation:true; pod builder keeps Privileged=false, RunAsNonRoot=true, AllowPrivilegeEscalation=false.
No-Sensitive-Data-In-Logs ✅ Passed New logs only mention resource names and sync timings; no passwords, tokens, API keys, PII, or raw pod log contents are emitted.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@openshift-ci

openshift-ci Bot commented Jun 1, 2026

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 assign miciah for approval. 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

@openshift-ci openshift-ci Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jun 1, 2026
@openshift-ci

openshift-ci Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Hi @sanjaytripathi97. Thanks for your PR.

I'm waiting for a openshift 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
docs/usage.md (1)

213-214: 💤 Low value

Consider clarifying that interval applies to all providers.

The interval field is provider-agnostic and can be used with AWS, GCP, Azure, BlueCat, and Infoblox. Currently it's only documented in the Infoblox example, which may give the impression it's Infoblox-specific. Consider adding a brief note such as "optional, applies to all providers" or showing it in another provider example.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/usage.md` around lines 213 - 214, Clarify that the interval field is
provider-agnostic by updating the docs: add a short note next to the existing
"interval: 5m" line (or in a shared config section) stating "optional, applies
to all providers (AWS, GCP, Azure, BlueCat, Infoblox)" and/or show the same
interval comment in at least one other provider example so readers don't assume
it's Infoblox-specific; update the text around the example to reference the
global nature of the interval setting and ensure the symbol "interval" and
provider names AWS, GCP, Azure, BlueCat, Infoblox are mentioned.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@docs/usage.md`:
- Around line 213-214: Clarify that the interval field is provider-agnostic by
updating the docs: add a short note next to the existing "interval: 5m" line (or
in a shared config section) stating "optional, applies to all providers (AWS,
GCP, Azure, BlueCat, Infoblox)" and/or show the same interval comment in at
least one other provider example so readers don't assume it's Infoblox-specific;
update the text around the example to reference the global nature of the
interval setting and ensure the symbol "interval" and provider names AWS, GCP,
Azure, BlueCat, Infoblox are mentioned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 2b2c06bf-7b29-4061-b5b4-9062bd77b002

📥 Commits

Reviewing files that changed from the base of the PR and between f97b82d and 8d02f77.

⛔ Files ignored due to path filters (2)
  • api/v1alpha1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • api/v1beta1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
📒 Files selected for processing (8)
  • api/v1alpha1/externaldns_types.go
  • api/v1beta1/externaldns_types.go
  • api/v1beta1/externaldns_webhook.go
  • config/crd/bases/externaldns.olm.openshift.io_externaldnses.yaml
  • config/samples/infoblox/operator_v1beta1_infoblox_openshift.yaml
  • docs/usage.md
  • pkg/operator/controller/externaldns/pod.go
  • pkg/operator/controller/externaldns/pod_interval_test.go

@theiratenate

Copy link
Copy Markdown

@alebedev87 @grzpiotrowski Please review when you can. We have some developers looking to use CNAME records in our root domain and need the max results added to resolve their plight.

@alebedev87

Copy link
Copy Markdown
Contributor

@theiratenate, @sanjaytripathi97 : https://redhat.atlassian.net/browse/RFE-6781 is not accepted yet. But I think it would be easier to do so if the PR will be in a ready state. Let me have a look.

Comment thread api/v1alpha1/externaldns_types.go
Comment thread api/v1beta1/externaldns_types.go Outdated
Comment thread api/v1beta1/externaldns_types.go Outdated
Comment thread api/v1beta1/externaldns_webhook.go Outdated
Comment thread pkg/operator/controller/externaldns/pod_interval_test.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/e2e/infoblox_sync_options_test.go`:
- Around line 81-94: The code at the end of the container validation loop
returns true, nil unconditionally at line 94, even if no external-dns container
was found and validated. To prevent false-positive test passes, introduce a
boolean flag before the loop to track whether an external-dns container was
found. Set this flag to true after successfully validating a container that has
a name starting with "external-dns" and contains both the intervalArg and
maxResultsArg arguments. At the end of the function, check this flag and return
false if no matching external-dns container was ever found and validated,
ensuring the test fails when expected containers are missing.
- Around line 57-59: The defer cleanup block in the test is ignoring the error
returned from common.KubeClient.Delete(context.TODO(), &extDNS) by using the
underscore operator, which violates the coding guideline of never ignoring error
returns and can hide leaked Custom Resources. Replace the underscore with a
proper error variable and handle the error appropriately by either logging it or
asserting that the deletion should succeed, rather than discarding the error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 914281a1-313e-4627-bee0-d63885c658f7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d02f77 and fc8963e.

⛔ Files ignored due to path filters (1)
  • api/v1beta1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
📒 Files selected for processing (6)
  • api/v1beta1/externaldns_types.go
  • config/crd/bases/externaldns.olm.openshift.io_externaldnses.yaml
  • pkg/operator/controller/externaldns/pod.go
  • pkg/operator/controller/externaldns/pod_interval_test.go
  • test/e2e/infoblox.go
  • test/e2e/infoblox_sync_options_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/operator/controller/externaldns/pod.go
  • pkg/operator/controller/externaldns/pod_interval_test.go
  • config/crd/bases/externaldns.olm.openshift.io_externaldnses.yaml

Comment thread test/e2e/infoblox_sync_options_test.go Outdated
Comment thread test/e2e/infoblox_sync_options_test.go Outdated
Sanjay Tripathi added 2 commits June 22, 2026 14:47
Expose sync interval and Infoblox WAPI pagination settings in the
ExternalDNS API so operator-managed deployments can integrate with large
Infoblox grids without manual deployment patches.
Revert v1alpha1 API changes, move validation to CRD defaults and bounds,
remove webhook validators, and add an Infoblox e2e test for operand args.
@sanjaytripathi97
sanjaytripathi97 force-pushed the add-infoblox-max-results-and-interval branch from fc8963e to ecd0951 Compare June 22, 2026 09:18

@alebedev87 alebedev87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks a lot for the follow-up! I think we are closer to the good implementation. I re-reviewed the OpenShift API conventions meanwhile and had to reconsider the defaulting strategy PTAL.

Comment thread api/v1beta1/externaldns_types.go Outdated
Comment thread api/v1beta1/externaldns_types.go Outdated
Comment thread pkg/operator/controller/externaldns/pod_interval_test.go Outdated
Rename interval to intervalSeconds as int32 with CRD min/max and no
default. Drop maxResults CRD default. Update e2e to verify sync spacing
from operand logs instead of only checking deployment args.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/e2e/infoblox_sync_options_test.go`:
- Line 194: Update the resource cleanup around readCloser in the
timestamp-parsing flow so its Close error is propagated when parsing otherwise
succeeds. Preserve any existing timestamp parsing error as the returned error,
and ensure the defer no longer discards readCloser.Close()’s result.
- Around line 102-108: Update the failure logging in the container argument
checks within the e2e test to omit the full container.Args list, which may
expose internal hostnames. Keep logging the container name and the missing
expected flag (intervalArg or maxResultsArg) only, while preserving the existing
failure returns.
- Around line 49-53: Register cleanup for the independently created credentials
Secret in the test immediately after the successful common.KubeClient.Create
call, using the test cleanup mechanism to delete credSecret and prevent stale
resources or name collisions. Keep the existing creation failure handling
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d887fcc-ceb1-45d6-9ea5-a21b73640b5d

📥 Commits

Reviewing files that changed from the base of the PR and between fc8963e and 2da7130.

📒 Files selected for processing (8)
  • api/v1beta1/externaldns_types.go
  • config/crd/bases/externaldns.olm.openshift.io_externaldnses.yaml
  • config/samples/infoblox/operator_v1beta1_infoblox_openshift.yaml
  • docs/usage.md
  • pkg/operator/controller/externaldns/pod.go
  • pkg/operator/controller/externaldns/pod_interval_test.go
  • test/e2e/infoblox.go
  • test/e2e/infoblox_sync_options_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • config/samples/infoblox/operator_v1beta1_infoblox_openshift.yaml
  • docs/usage.md
  • test/e2e/infoblox.go
  • pkg/operator/controller/externaldns/pod.go

Comment thread test/e2e/infoblox_sync_options_test.go Outdated
Comment thread test/e2e/infoblox_sync_options_test.go Outdated
Comment thread test/e2e/infoblox_sync_options_test.go Outdated
if err != nil {
return nil, err
}
defer readCloser.Close()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Handle the stream close error.

Line 194 discards Close()’s error. Propagate it when timestamp parsing otherwise succeeds.

As per path instructions, **/*.go: “Never ignore error returns”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/infoblox_sync_options_test.go` at line 194, Update the resource
cleanup around readCloser in the timestamp-parsing flow so its Close error is
propagated when parsing otherwise succeeds. Preserve any existing timestamp
parsing error as the returned error, and ensure the defer no longer discards
readCloser.Close()’s result.

Source: Path instructions

@alebedev87

Copy link
Copy Markdown
Contributor

I just checked out and found that https://redhat.atlassian.net/browse/RFE-8890 and https://redhat.atlassian.net/browse/RFE-8888 got approved in April. This PR addresses both of these RFEs. Let's reference them in the description.

@alebedev87

Copy link
Copy Markdown
Contributor

/ok-to-test

@openshift-ci openshift-ci Bot 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 Jul 28, 2026
Sanjay Tripathi added 2 commits July 28, 2026 22:16
The operand Deployment is created in the operator namespace unless
E2E_SEPARATE_OPERAND_NAMESPACE is set; the test was looking in
external-dns. Also commit the regenerated bundle CRD so verify and
e2e install the intervalSeconds/maxResults schema.
make bundle regenerates CSV examples from config/samples; commit the
intervalSeconds and maxResults values so verify stays clean.

@alebedev87 alebedev87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Another review with a deeper look into unit and e2e tests.

Comment thread api/v1beta1/externaldns_types.go Outdated
Comment thread api/v1beta1/externaldns_types.go Outdated
Comment thread config/crd/bases/externaldns.olm.openshift.io_externaldnses.yaml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think that we should add both interval and maxresults tests in the existing TestDesiredExternalDNSDeployment test function in deployment_test.go. A new Infoblox test case which specifies both of the new fields. The omitted values are supposed to be covered by the existing Infloblox test case(s).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Added an Infoblox case in TestDesiredExternalDNSDeployment that sets both intervalSeconds and maxResults and asserts --interval=120s and --infoblox-max-results=2000. Omitted values remain covered by the existing Nominal Infoblox case. Removed the standalone pod_interval_test.go.

Comment thread test/e2e/infoblox_sync_options_test.go Outdated
Comment on lines +40 to +42
if helper.platform() != infobloxDNSProvider {
t.Skip("test only runs against Infoblox provider")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We try to keep all test provider agnostic and add them to operator_test.go. The intervalSeconds is exactly this case. Let's add it there and not skip for any provider.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Moved intervalSeconds coverage into TestExternalDNSSyncInterval in operator_test.go. It runs for all providers (no Infoblox-only skip) and verifies both the operand arg and sync spacing from logs. Removed infoblox_sync_options_test.go.

Comment thread test/e2e/infoblox_sync_options_test.go Outdated
Update intervalSeconds/maxResults godoc for oc explain, cover both
fields in TestDesiredExternalDNSDeployment, and move intervalSeconds
e2e into provider-agnostic operator_test.go. Rely on unit tests for
maxResults instead of a heavy Infoblox e2e scenario.

@alebedev87 alebedev87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The API LGTM, some remarks about the e2e test though.

Comment thread test/e2e/operator_test.go Outdated
}
}

func TestExternalDNSSyncInterval(t *testing.T) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We prefer to let the file grow by appending to the end. Can you please add this new test after the last TestXXX function?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Moved TestExternalDNSSyncInterval to the end of operator_test.go, after the other TestXXX functions.

Comment thread test/e2e/operator_test.go Outdated
Comment on lines +132 to +137
expected := []appsv1.DeploymentCondition{
{Type: appsv1.DeploymentAvailable, Status: corev1.ConditionTrue},
}
if err := waitForOperatorDeploymentStatusCondition(context.TODO(), t, common.KubeClient, expected...); err != nil {
t.Fatalf("operator was not available: %v", err)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is redundant TestOperatorAvailable should validate this before TestExternalDNSSyncInterval kicks in.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Removed the extra operator availability wait; TestOperatorAvailable covers that earlier.

Comment thread test/e2e/operator_test.go Outdated
Comment on lines +41 to +45
testSyncIntervalExtDNSName = "test-extdns-interval"
testSyncIntervalSeconds int32 = 120
syncLogMessage = "All records are already up to date"
minObservedSyncGap = 90 * time.Second
maxObservedSyncGap = 150 * time.Second

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Those are variables which make sense only for TestExternalDNSSyncInterval, so should be moved in there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Moved the sync-interval-only constants/vars into TestExternalDNSSyncInterval.

Comment thread test/e2e/operator_test.go Outdated
Comment thread test/e2e/operator_test.go Outdated
Comment thread test/e2e/operator_test.go Outdated
Comment thread test/e2e/operator_test.go Outdated
Comment thread test/e2e/operator_test.go Outdated
curr := timestamps[len(timestamps)-1]
gap := curr.Sub(prev)
t.Logf("observed sync gap between %s and %s: %s", prev.Format(time.RFC3339), curr.Format(time.RFC3339), gap)
if gap < minObservedSyncGap || gap > maxObservedSyncGap {

@alebedev87 alebedev87 Jul 29, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why the range is so vast? The sync interval is 120s and we are expecting it to be between 90s and 150s. I could understand +/- 5s but +/- 30s seems like a little too much.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Tightened the expected gap to [115s, 125s] (±5s around the configured 120s interval), I hope this is fine now.

Comment thread test/e2e/operator_test.go Outdated
Comment on lines +262 to +315
func containsContainerArg(args []string, expected string) bool {
for _, arg := range args {
if arg == expected {
return true
}
}
return false
}

func collectSyncTimestamps(ctx context.Context, namespace, podName, containerName string) ([]time.Time, error) {
opts := &corev1.PodLogOptions{
Container: containerName,
Follow: false,
}
readCloser, err := common.KubeClientSet.CoreV1().Pods(namespace).GetLogs(podName, opts).Stream(ctx)
if err != nil {
return nil, err
}
defer func() {
_ = readCloser.Close()
}()

return parseSyncTimestamps(readCloser)
}

func parseSyncTimestamps(r io.Reader) ([]time.Time, error) {
var timestamps []time.Time
scanner := bufio.NewScanner(r)
buf := make([]byte, 0, 64*1024)
scanner.Buffer(buf, 1024*1024)

for scanner.Scan() {
line := scanner.Text()
if !strings.Contains(line, syncLogMessage) {
continue
}
matches := logTimestampPattern.FindStringSubmatch(line)
if len(matches) != 2 {
continue
}
ts, err := time.Parse(time.RFC3339Nano, matches[1])
if err != nil {
ts, err = time.Parse(time.RFC3339, matches[1])
if err != nil {
continue
}
}
timestamps = append(timestamps, ts)
}
if err := scanner.Err(); err != nil {
return nil, err
}
return timestamps, nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you please move all the helper functions to the bottom of the file? There is a dedicated comment marker there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Moved the helper functions under the existing // HELPER FUNCTIONS marker.

Comment thread test/common/common.go Outdated
Comment on lines +320 to +328
// OperandNamespace returns the namespace where ExternalDNS operand Deployments are created.
// By default the operator deploys operands into its own namespace; when
// E2E_SEPARATE_OPERAND_NAMESPACE=true it uses the dedicated "external-dns" namespace.
func OperandNamespace() string {
if os.Getenv(e2eSeparateOperandNsEnvVar) == "true" {
return operandNamespace
}
return OperatorNamespace
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Deploying operands in external-dns-operator is defacto standard now. No need to count for the other case, you can drop this function and use common.OperatorNamespace wherever the operand namespace is needed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. Removed OperandNamespace() and now use common.OperatorNamespace for operand lookups.

sanjaytripathi97 and others added 4 commits July 29, 2026 16:50
Co-authored-by: Andrey Lebedev <alebedev87@gmail.com>
Co-authored-by: Andrey Lebedev <alebedev87@gmail.com>
Co-authored-by: Andrey Lebedev <alebedev87@gmail.com>
Co-authored-by: Andrey Lebedev <alebedev87@gmail.com>
Move TestExternalDNSSyncInterval to the end of operator_test.go, drop
the redundant operator readiness wait, tighten the observed sync gap
tolerance, hard-fail when interval args are missing, and always use
OperatorNamespace for operand lookups.
@openshift-ci

openshift-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

@sanjaytripathi97: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-shared-vpc-phz-operator 13f0516 link true /test e2e-aws-shared-vpc-phz-operator
ci/prow/e2e-gcp-operator 13f0516 link true /test e2e-gcp-operator
ci/prow/e2e-aws-operator 13f0516 link true /test e2e-aws-operator

Full PR test history. Your PR dashboard.

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. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Indicates a non-member PR verified by an org member that is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants