Skip to content

[WIP] OCPBUGS-63219: Support clientIPPreservationMode for AWS NLB#1426

Open
gcs278 wants to merge 2 commits into
openshift:masterfrom
gcs278:OCPBUGS-63219-proxy-protocol
Open

[WIP] OCPBUGS-63219: Support clientIPPreservationMode for AWS NLB#1426
gcs278 wants to merge 2 commits into
openshift:masterfrom
gcs278:OCPBUGS-63219-proxy-protocol

Conversation

@gcs278
Copy link
Copy Markdown
Contributor

@gcs278 gcs278 commented Apr 29, 2026

Summary

  • Add support for the new clientIPPreservationMode field on AWSNetworkLoadBalancerParameters to control how client IP addresses are preserved by NLBs
  • When set to ProxyProtocol, configures the NLB target group with preserve_client_ip.enabled=false and proxy_protocol_v2.enabled=true, and enables ROUTER_USE_PROXY_PROTOCOL=true on the router — this fixes hairpin connection failures on internal NLBs (OCPBUGS-63219)
  • When set to Native (or omitted on existing IngressControllers), preserves current behavior using AWS's native client IP preservation
  • New IngressControllers default to ProxyProtocol via controller-managed defaulting (not CRD default), so existing ICs are not modified on upgrade

Dependencies

Test plan

  • Unit tests for desiredLoadBalancerService with ProxyProtocol and Native modes
  • Unit tests for IsProxyProtocolNeeded with NLB ProxyProtocol/Native
  • Unit tests for defaulting behavior (new vs existing ICs)
  • Manual: New NLB defaults to ProxyProtocol, connectivity works
  • Manual: CLB → NLB with ProxyProtocol, correct annotations, connectivity works
  • Manual: CLB → NLB with Native, no proxy annotations, connectivity works
  • Manual: NLB → CLB, CLB proxy annotation restored, connectivity works
  • Manual: Upgrade test — existing NLB not modified after deploying new operator
  • Manual: Hairpin test — internal NLB with ProxyProtocol, curl from same node succeeds
  • Manual: Hairpin test — internal NLB with Native, curl from same node times out (confirms bug)

🤖 Generated with Claude Code

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 29, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 29, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot openshift-ci-robot added jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. labels Apr 29, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@gcs278: This pull request references Jira Issue OCPBUGS-63219, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • Add support for the new clientIPPreservationMode field on AWSNetworkLoadBalancerParameters to control how client IP addresses are preserved by NLBs
  • When set to ProxyProtocol, configures the NLB target group with preserve_client_ip.enabled=false and proxy_protocol_v2.enabled=true, and enables ROUTER_USE_PROXY_PROTOCOL=true on the router — this fixes hairpin connection failures on internal NLBs (OCPBUGS-63219)
  • When set to Native (or omitted on existing IngressControllers), preserves current behavior using AWS's native client IP preservation
  • New IngressControllers default to ProxyProtocol via controller-managed defaulting (not CRD default), so existing ICs are not modified on upgrade

Dependencies

Test plan

  • Unit tests for desiredLoadBalancerService with ProxyProtocol and Native modes
  • Unit tests for IsProxyProtocolNeeded with NLB ProxyProtocol/Native
  • Unit tests for defaulting behavior (new vs existing ICs)
  • E2E: New NLB defaults to ProxyProtocol, connectivity works
  • E2E: CLB → NLB with ProxyProtocol, correct annotations, connectivity works
  • E2E: CLB → NLB with Native, no proxy annotations, connectivity works
  • E2E: NLB → CLB, CLB proxy annotation restored, connectivity works
  • E2E: Upgrade test — existing NLB not modified after deploying new operator
  • E2E: Hairpin test — internal NLB with ProxyProtocol, curl from same node succeeds
  • E2E: Hairpin test — internal NLB with Native, curl from same node times out (confirms bug)

🤖 Generated with Claude Code

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 openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Apr 29, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

📝 Walkthrough

Walkthrough

Adds a clientIPPreservationMode enum (Native | ProxyProtocol) to IngressController CRD schemas (spec and status) across manifests. Updates controller logic to default unset AWS NLB mode to ProxyProtocol, to propagate the effective mode into status, and to mark PROXY usage for AWS NLBs when status is ProxyProtocol. Service annotation handling now writes AWS target-group-attributes for NLB proxy protocol v2. A go.mod replace redirects github.com/openshift/api to github.com/gcs278/api. Unit and e2e tests exercising both modes were added/updated.

🚥 Pre-merge checks | ✅ 8 | ❌ 4

❌ Failed checks (2 warnings, 2 inconclusive)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning TestAWSNLBClientIPPreservationMode violates single responsibility by testing multiple unrelated behaviors: initial ProxyProtocol configuration and mode transition in one test. Refactor into separate focused tests using t.Run() subtests or rename to document intentional coupling. Extract repeated verification patterns into helper functions.
Microshift Test Compatibility ⚠️ Warning New tests reference OpenShift APIs (Infrastructure, IngressController) unavailable on MicroShift and lack required compatibility protections. Add [apigroup:config.openshift.io] tag or [Skipped:MicroShift] label to test functions to ensure MicroShift CI skips them.
Single Node Openshift (Sno) Test Compatibility ❓ Inconclusive E2e test files referenced in summary (test/e2e/nlb_client_ip_preservation_test.go, test/e2e/all_test.go) do not exist in repository; repository uses standard Go testing, not Ginkgo. Provide the actual e2e test code for SNO compatibility assessment once files are available in the repository state being reviewed.
Ipv6 And Disconnected Network Test Compatibility ❓ Inconclusive The test file test/e2e/nlb_client_ip_preservation_test.go does not exist in the repository, preventing verification of IPv4 assumptions or external connectivity requirements in the actual implementation. Provide the actual test implementation file to verify it uses dynamically obtained load balancer addresses, avoids IPv4 hardcoding, and does not require external internet connectivity for test execution.
✅ Passed checks (8 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding support for clientIPPreservationMode field for AWS NLB, which aligns with the substantial changes across multiple files including CRD manifests, controller logic, and E2E tests.
Description check ✅ Passed The description is directly related to the changeset, providing a comprehensive summary of the feature (clientIPPreservationMode field), behavior for ProxyProtocol vs Native modes, defaulting strategy, dependencies, and test plan that matches the file changes.
Docstring Coverage ✅ Passed Docstring coverage is 93.33% which is sufficient. The required threshold is 80.00%.
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 Test names (TestAWSNLBClientIPPreservationMode and TestAWSNLBDefaultClientIPPreservationMode) are stable, descriptive, and free of dynamic identifiers.
Topology-Aware Scheduling Compatibility ✅ Passed The pull request only updates CRD schemas and controller logic for AWS NLB clientIPPreservationMode, without adding any pod scheduling constraints, affinities, topology spread rules, nodeSelectors, or PDB changes.
Ote Binary Stdout Contract ✅ Passed The new test file does not violate the OTE Binary Stdout Contract. No process-level stdout writes exist in init(), TestMain(), or top-level initializers. All logging uses t.Logf(), which is properly intercepted by the testing framework.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

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

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 29, 2026

[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 candita 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

Consume the new clientIPPreservationMode field on
AWSNetworkLoadBalancerParameters to control how client IP addresses
are preserved by NLBs.

When set to ProxyProtocol, the operator configures the NLB target
group with preserve_client_ip.enabled=false and
proxy_protocol_v2.enabled=true via the target-group-attributes
Service annotation. It also sets ROUTER_USE_PROXY_PROTOCOL=true on
the router deployment so HAProxy parses PROXY protocol headers.
This avoids hairpin connection failures on internal NLBs.

When set to Native (or omitted on existing IngressControllers),
the NLB uses AWS's native client IP preservation, which is the
current default behavior.

New IngressControllers default to ProxyProtocol via controller-managed
defaulting in setDefaultProviderParameters, gated with !alreadyAdmitted
so that existing IngressControllers are not modified on upgrade.

https://redhat.atlassian.net/browse/OCPBUGS-63219

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gcs278 gcs278 force-pushed the OCPBUGS-63219-proxy-protocol branch from 4f32483 to c3b1e27 Compare April 29, 2026 01:52
@gcs278 gcs278 force-pushed the OCPBUGS-63219-proxy-protocol branch 2 times, most recently from 7ca9715 to 6a46693 Compare April 29, 2026 02:03
@gcs278 gcs278 marked this pull request as ready for review April 29, 2026 02:11
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 29, 2026
@gcs278 gcs278 changed the title OCPBUGS-63219: Support clientIPPreservationMode for AWS NLB [WIP] OCPBUGS-63219: Support clientIPPreservationMode for AWS NLB Apr 29, 2026
@gcs278
Copy link
Copy Markdown
Contributor Author

gcs278 commented Apr 29, 2026

/jira refresh

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 29, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Apr 29, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@gcs278: This pull request references Jira Issue OCPBUGS-63219, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @anuragthehatter

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

/jira refresh

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 openshift-eng/jira-lifecycle-plugin repository.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
manifests/00-custom-resource-definition-OKD.yaml (1)

2760-2763: Optional: clarify status wording.

Line 2760–2763 says “the user has no opinion,” which is spec-oriented language. For the status schema, consider wording that reflects observed/effective state instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@manifests/00-custom-resource-definition-OKD.yaml` around lines 2760 - 2763,
Update the status schema description text that currently reads “the user has no
opinion” to language that reflects observed/effective state — e.g., replace that
phrase with “not specified by the user; the platform may choose a default
(currently 'ProxyProtocol')” and ensure any other status-related descriptions
use present-tense, observed wording rather than spec-oriented phrasing so the
status describes the effective value rather than intent.
test/e2e/nlb_client_ip_preservation_test.go (1)

37-38: Prefer generated IC names to reduce collision risk in repeated runs.

Using fixed names can cause intermittent AlreadyExists failures in reruns or partially cleaned environments.

♻️ Suggested change
-	name := types.NamespacedName{Namespace: operatorNamespace, Name: "nlb-pp-test"}
+	name := types.NamespacedName{Namespace: operatorNamespace, Name: names.SimpleNameGenerator.GenerateName("nlb-pp-")}
...
-	name := types.NamespacedName{Namespace: operatorNamespace, Name: "nlb-default"}
+	name := types.NamespacedName{Namespace: operatorNamespace, Name: names.SimpleNameGenerator.GenerateName("nlb-default-")}

Also applies to: 125-126

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/nlb_client_ip_preservation_test.go` around lines 37 - 38, The test
currently uses a fixed NamespacedName (variable name :=
types.NamespacedName{Namespace: operatorNamespace, Name: "nlb-pp-test"}) and
derived domain, which risks AlreadyExists on reruns; change the creation to
generate a unique resource name (e.g., append a short random/UUID/timestamp
suffix) when constructing the types.NamespacedName and update the derived domain
assignment (domain := name.Name + "." + dnsConfig.Spec.BaseDomain) accordingly;
apply the same change to the other fixed NamespacedName usage referenced around
lines 125-126 so all test resources use generated unique names to avoid
collisions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@go.mod`:
- Line 229: The go.mod contains a replace directive "replace
github.com/openshift/api => github.com/gcs278/api
v0.0.0-20260429000454-cff0427099ea" that introduces a fork without explanation;
either remove this replace to use the upstream github.com/openshift/api, or if
the fork is required keep the replace but add a nearby comment explaining why
the fork is necessary (reference the commit cff0427099ea and the specific
issue/bug it fixes), mark it as TODO with a target removal date/version, and
ensure the rationale is committed so reviewers know it’s intentional.

In `@test/e2e/nlb_client_ip_preservation_test.go`:
- Around line 169-171: The wait timeout in
waitForIngressControllerClientIPPreservationMode is set to 2 minutes causing
intermittent flakes; update the timeout argument in the
wait.PollUntilContextTimeout call from 2*time.Minute to 5*time.Minute to match
other readiness waits so reconciliation has more time to settle (reference
function name waitForIngressControllerClientIPPreservationMode and the
wait.PollUntilContextTimeout invocation).

---

Nitpick comments:
In `@manifests/00-custom-resource-definition-OKD.yaml`:
- Around line 2760-2763: Update the status schema description text that
currently reads “the user has no opinion” to language that reflects
observed/effective state — e.g., replace that phrase with “not specified by the
user; the platform may choose a default (currently 'ProxyProtocol')” and ensure
any other status-related descriptions use present-tense, observed wording rather
than spec-oriented phrasing so the status describes the effective value rather
than intent.

In `@test/e2e/nlb_client_ip_preservation_test.go`:
- Around line 37-38: The test currently uses a fixed NamespacedName (variable
name := types.NamespacedName{Namespace: operatorNamespace, Name: "nlb-pp-test"})
and derived domain, which risks AlreadyExists on reruns; change the creation to
generate a unique resource name (e.g., append a short random/UUID/timestamp
suffix) when constructing the types.NamespacedName and update the derived domain
assignment (domain := name.Name + "." + dnsConfig.Spec.BaseDomain) accordingly;
apply the same change to the other fixed NamespacedName usage referenced around
lines 125-126 so all test resources use generated unique names to avoid
collisions.
🪄 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: 7aaec5b4-af35-4500-903f-2af108380f15

📥 Commits

Reviewing files that changed from the base of the PR and between 961ac21 and 6a46693.

⛔ Files ignored due to path filters (49)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/envtest-releases.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/types_pacemakercluster.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1/types_ingress.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_20_kube-apiserver_01_kubeapiservers-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_20_kube-apiserver_01_kubeapiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_20_kube-apiserver_01_kubeapiservers-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_20_kube-apiserver_01_kubeapiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_20_kube-apiserver_01_kubeapiservers.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/quota/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/security/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/security/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/security/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/security/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (13)
  • go.mod
  • manifests/00-custom-resource-definition-CustomNoUpgrade.yaml
  • manifests/00-custom-resource-definition-DevPreviewNoUpgrade.yaml
  • manifests/00-custom-resource-definition-OKD.yaml
  • manifests/00-custom-resource-definition-TechPreviewNoUpgrade.yaml
  • manifests/00-custom-resource-definition.yaml
  • pkg/operator/controller/ingress/controller.go
  • pkg/operator/controller/ingress/controller_test.go
  • pkg/operator/controller/ingress/load_balancer_service.go
  • pkg/operator/controller/ingress/load_balancer_service_test.go
  • pkg/operator/controller/ingress/status.go
  • test/e2e/all_test.go
  • test/e2e/nlb_client_ip_preservation_test.go

Comment thread go.mod
// Replace needed because the fork keeps upstream module name for compatibility.
replace github.com/istio-ecosystem/sail-operator => github.com/openshift-service-mesh/sail-operator v0.0.0-20260327145107-d4059b965c68

replace github.com/openshift/api => github.com/gcs278/api v0.0.0-20260429000454-cff0427099ea
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 29, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Checking replacement in go.mod:"
rg -n 'replace github.com/openshift/api' go.mod

FORK_VERSION="$(awk '/replace github.com\/openshift\/api =>/{print $5}' go.mod)"
FORK_COMMIT="${FORK_VERSION##*-}"

echo "Fork pseudo-version: ${FORK_VERSION}"
echo "Derived commit: ${FORK_COMMIT}"

echo
echo "Commit presence in upstream openshift/api:"
git ls-remote https://github.com/openshift/api.git "${FORK_COMMIT}" || true

echo
echo "Commit presence in fork gcs278/api:"
git ls-remote https://github.com/gcs278/api.git "${FORK_COMMIT}" || true

Repository: openshift/cluster-ingress-operator

Length of output: 373


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check for comments around the replacement in go.mod
echo "=== Context around line 229 in go.mod ==="
sed -n '225,235p' go.mod

echo
echo "=== Full go.mod to find any comments about this replacement ==="
grep -B 5 -A 5 "replace github.com/openshift/api" go.mod || echo "(No additional context found)"

echo
echo "=== Check if there are TODOs or FIXMEs related to this ==="
rg -i "gcs278|openshift/api|replace.*api" go.mod go.sum 2>/dev/null || echo "(No matches)"

Repository: openshift/cluster-ingress-operator

Length of output: 1361


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Try to verify the commit hash with different approaches
COMMIT_HASH="cff0427099ea"
FORK_REPO="gcs278/api"
UPSTREAM_REPO="openshift/api"

echo "=== Attempting to verify commit in fork repository ==="
# Try fetching via GitHub API instead of git ls-remote
curl -s "https://api.github.com/repos/${FORK_REPO}/commits/${COMMIT_HASH}" | jq -r '.sha, .message, .commit.message' 2>/dev/null || echo "Fork commit lookup failed or repo not found"

echo
echo "=== Attempting to verify commit in upstream repository ==="
curl -s "https://api.github.com/repos/${UPSTREAM_REPO}/commits/${COMMIT_HASH}" | jq -r '.sha, .message, .commit.message' 2>/dev/null || echo "Upstream commit lookup failed or commit doesn't exist"

Repository: openshift/cluster-ingress-operator

Length of output: 2007


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check if there are any other references to this fork or temporary replacements
echo "=== Search for any documentation about this replacement ==="
find . -type f \( -name "*.md" -o -name "*.txt" -o -name "CHANGES*" \) -exec grep -l "gcs278\|openshift/api" {} \; 2>/dev/null | head -20 || echo "(No documentation found)"

echo
echo "=== Check recent git history for context about this change ==="
git log --oneline --all -20 -- go.mod 2>/dev/null | head -10 || echo "(git log unavailable)"

echo
echo "=== Check git blame for this specific line ==="
git blame -L 229,229 go.mod 2>/dev/null || echo "(git blame unavailable)"

Repository: openshift/cluster-ingress-operator

Length of output: 1300


Remove the fork replacement or document why it's necessary.

The replacement to github.com/gcs278/api introduces a supply-chain maintenance risk for a core dependency, especially because the commit (cff0427099ea) exists in the upstream github.com/openshift/api repository. There is no explanation in the code for why the fork is required instead of using the upstream version directly. If the fork is temporary, mark it with a TODO and target a removal date. If it serves a specific purpose, document that rationale in a comment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` at line 229, The go.mod contains a replace directive "replace
github.com/openshift/api => github.com/gcs278/api
v0.0.0-20260429000454-cff0427099ea" that introduces a fork without explanation;
either remove this replace to use the upstream github.com/openshift/api, or if
the fork is required keep the replace but add a nearby comment explaining why
the fork is necessary (reference the commit cff0427099ea and the specific
issue/bug it fixes), mark it as TODO with a target removal date/version, and
ensure the rationale is committed so reviewers know it’s intentional.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@CodeRabbit I know - I'm waiting for openshift/api#2661 to merge

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@gcs278, thanks for the context! That makes sense. Once openshift/api#2661 merges, this replace directive should be removed and the dependency updated to the official upstream version.

In the meantime, it would be helpful to add a comment above the replace directive (similar to the other replace stanzas in the file) so reviewers understand it's intentional and temporary:

// Temporary: replace with upstream once https://github.com/openshift/api/pull/2661 merges.
replace github.com/openshift/api => github.com/gcs278/api v0.0.0-20260429000454-cff0427099ea

📝 Learnings were identified and not saved (knowledge base disabled). Enable

Comment thread test/e2e/nlb_client_ip_preservation_test.go Outdated
@gcs278
Copy link
Copy Markdown
Contributor Author

gcs278 commented Apr 29, 2026

/retest

Add two E2E tests:

TestAWSNLBClientIPPreservationMode creates an NLB with ProxyProtocol,
verifies the target-group-attributes annotation, router env var, and
status are correct, tests connectivity, then switches to Native and
verifies the annotation and env var are removed.

TestAWSNLBDefaultClientIPPreservationMode creates an NLB without
specifying clientIPPreservationMode and verifies the controller
defaults it to ProxyProtocol.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gcs278 gcs278 force-pushed the OCPBUGS-63219-proxy-protocol branch from 6a46693 to dbb29d0 Compare April 29, 2026 14:14
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/e2e/nlb_client_ip_preservation_test.go (1)

37-38: Use generated IngressController names to reduce rerun collision flakes.

Since these tests run in parallel, fixed names ("nlb-pp-test", "nlb-default") can conflict with leftovers from interrupted runs. Prefer generated names.

♻️ Suggested change
- name := types.NamespacedName{Namespace: operatorNamespace, Name: "nlb-pp-test"}
+ name := types.NamespacedName{
+   Namespace: operatorNamespace,
+   Name:      names.SimpleNameGenerator.GenerateName("nlb-pp-test-"),
+ }
  domain := name.Name + "." + dnsConfig.Spec.BaseDomain
- name := types.NamespacedName{Namespace: operatorNamespace, Name: "nlb-default"}
+ name := types.NamespacedName{
+   Namespace: operatorNamespace,
+   Name:      names.SimpleNameGenerator.GenerateName("nlb-default-"),
+ }
  domain := name.Name + "." + dnsConfig.Spec.BaseDomain

Also applies to: 125-126

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/nlb_client_ip_preservation_test.go` around lines 37 - 38, Replace
the fixed IngressController names with generated, unique names to avoid parallel
test collisions: instead of using the literal "nlb-pp-test" when constructing
the NamespacedName stored in the variable name (and building domain from
name.Name), generate a unique name (e.g., using a random/suffix or Kubernetes
GenerateName pattern) and use that value for name.Name and domain; do the same
replacement for the other hardcoded "nlb-default" occurrence (lines around where
that literal is used). Update any assertions or cleanup that reference those
literals to use the generated name variables (name and domain) so tests don't
collide across runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/e2e/nlb_client_ip_preservation_test.go`:
- Around line 37-38: Replace the fixed IngressController names with generated,
unique names to avoid parallel test collisions: instead of using the literal
"nlb-pp-test" when constructing the NamespacedName stored in the variable name
(and building domain from name.Name), generate a unique name (e.g., using a
random/suffix or Kubernetes GenerateName pattern) and use that value for
name.Name and domain; do the same replacement for the other hardcoded
"nlb-default" occurrence (lines around where that literal is used). Update any
assertions or cleanup that reference those literals to use the generated name
variables (name and domain) so tests don't collide across runs.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: d9f49a9a-0e30-4b40-b195-94d238657d59

📥 Commits

Reviewing files that changed from the base of the PR and between 6a46693 and dbb29d0.

📒 Files selected for processing (2)
  • test/e2e/all_test.go
  • test/e2e/nlb_client_ip_preservation_test.go

@jcmoraisjr
Copy link
Copy Markdown
Member

/assign

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 29, 2026

@gcs278: 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-ovn-serial-1of2 dbb29d0 link true /test e2e-aws-ovn-serial-1of2
ci/prow/e2e-aws-ovn-hypershift-conformance dbb29d0 link true /test e2e-aws-ovn-hypershift-conformance
ci/prow/e2e-aws-ovn-upgrade dbb29d0 link true /test e2e-aws-ovn-upgrade
ci/prow/e2e-aws-ovn dbb29d0 link true /test e2e-aws-ovn
ci/prow/e2e-aws-operator-techpreview dbb29d0 link false /test e2e-aws-operator-techpreview

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

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants