Skip to content

fix(oauth): use kubeAPIServerDNSName for LoginURL when configured - #8854

Closed
chdeshpa-hue wants to merge 1 commit into
openshift:mainfrom
chdeshpa-hue:fix/OCPBUGS-86260-oauth-login-url-dns
Closed

fix(oauth): use kubeAPIServerDNSName for LoginURL when configured#8854
chdeshpa-hue wants to merge 1 commit into
openshift:mainfrom
chdeshpa-hue:fix/OCPBUGS-86260-oauth-login-url-dns

Conversation

@chdeshpa-hue

@chdeshpa-hue chdeshpa-hue commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Bug

OCPBUGS-86260: Hosted Clusters show internal API IP instead of DNS name in login token page

Problem

When a HostedCluster is configured with spec.kubeAPIServerDNSName (e.g., api.ocp4.example.com),
the OAuth server login token page shows the raw Load Balancer IP address in the --server
parameter instead of the configured DNS name.

Actual: --server=https://10.71.22.118:6443
Expected: --server=https://api.ocp4.example.com:6443

Root Cause

adaptOAuthConfig in v2/oauth/config.go constructs the LoginURL using
controlPlaneEndpoint.Host (the LB IP from status) unconditionally, without checking
if spec.kubeAPIServerDNSName is set.

The kubeconfig generation path (v2/kas/kubeconfig.go) already handles this correctly
via customExternalURL(hcp.Spec.KubeAPIServerDNSName, ...) but the OAuth config path
was missed during the v2 refactor.

Fix

Check hcp.Spec.KubeAPIServerDNSName before constructing LoginURL. Precedence:

  1. OauthLoginURLOverrideAnnotation (highest — IBMCloud ROKS)
  2. Spec.KubeAPIServerDNSName (when set — this fix)
  3. Status.ControlPlaneEndpoint.Host (default)

Also adds pki.AddBracketsIfIPv6 wrapping for proper IPv6 address formatting (aligning
with the pattern used elsewhere in the codebase).

Testing

$ go test ./control-plane-operator/controllers/hostedcontrolplane/v2/oauth/ -run TestAdaptOAuthConfig -v -count=1

=== RUN   TestAdaptOAuthConfig_LoginURL
=== RUN   TestAdaptOAuthConfig_LoginURL/no_kubeAPIServerDNSName_—_uses_controlPlaneEndpoint_host
=== RUN   TestAdaptOAuthConfig_LoginURL/kubeAPIServerDNSName_set_—_uses_DNS_name
=== RUN   TestAdaptOAuthConfig_LoginURL/kubeAPIServerDNSName_set_but_annotation_override_present_—_annotation_wins
=== RUN   TestAdaptOAuthConfig_LoginURL/only_annotation_override,_no_DNS_name_—_annotation_used
--- PASS: TestAdaptOAuthConfig_LoginURL (0.03s)
PASS

Files Changed

  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go — fix LoginURL construction
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go — new unit tests (4 cases)

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes

    • Improved OAuth login URL handling so the app now uses the correct host when a custom API server DNS name is set.
    • Added proper IPv6 formatting for login URLs to help prevent connection issues.
    • Kept existing override behavior intact when a login URL override is provided.
  • Tests

    • Added coverage for login URL selection across override, DNS name, and default host scenarios.

When a HostedCluster is configured with spec.kubeAPIServerDNSName and
custom named certificates, the OAuth token display page showed the raw
internal LB IP in --server= instead of the configured DNS name.

adaptOAuthConfig was building LoginURL from
hcp.Status.ControlPlaneEndpoint.Host without checking
hcp.Spec.KubeAPIServerDNSName. The kubeconfig generation path
(adaptCustomAdminKubeconfigSecret) already correctly prefers
kubeAPIServerDNSName — OAuth config was never updated when that feature
was added.

Prefer hcp.Spec.KubeAPIServerDNSName as the LoginURL host when set,
wrapped with pki.AddBracketsIfIPv6 to match the customExternalURL pattern
exactly. The existing OauthLoginURLOverrideAnnotation (IBMCloud) still
takes final precedence. The change is inert for all clusters that do not
set kubeAPIServerDNSName.

Fixes: https://issues.redhat.com/browse/OCPBUGS-86260
Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci openshift-ci Bot added do-not-merge/needs-area needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 28, 2026
@openshift-ci

openshift-ci Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

PR needs rebase.

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 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

adaptOAuthConfig in config.go now derives loginHost by defaulting to controlPlaneEndpoint.Host and overriding it with hcp.Spec.KubeAPIServerDNSName when set. The host is then wrapped with pki.AddBracketsIfIPv6 before being used to construct cfg.OAuthConfig.LoginURL. A new table-driven test TestAdaptOAuthConfig_LoginURL in config_test.go covers three cases: no DNS name (uses endpoint host), DNS name set, and annotation override.

Possibly related PRs

  • openshift/hypershift#8433: Modifies the same adaptOAuthConfig function and config_test.go with overlapping logic for KubeAPIServerDNSName-based LoginURL derivation and IPv6 bracketing.

Suggested reviewers

  • clebs
🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: OAuth LoginURL now prefers kubeAPIServerDNSName when configured.
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 All new test titles are static t.Run names; no dynamic values, IPs, timestamps, or generated identifiers appear in titles.
Test Structure And Quality ✅ Passed PASS: This is a plain table-driven Go unit test, not Ginkgo; it has isolated subtests, no shared resources/waits, and matches nearby oauth test style.
Topology-Aware Scheduling Compatibility ✅ Passed PR only changes OAuth LoginURL logic/tests; no replicas, node selectors, affinities, tolerations, or topology-based scheduling code was introduced.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Only a unit test was added; no Ginkgo e2e specs or external connectivity requirements are present.
No-Weak-Crypto ✅ Passed No weak-crypto primitives, custom crypto, or insecure secret/token comparisons appear in the changed files; the diff only adjusts OAuth URL formatting and tests.
Container-Privileges ✅ Passed Changed files are Go-only OAuth URL logic; no container/K8s manifests or privilege settings were added.
No-Sensitive-Data-In-Logs ✅ Passed PASS: The modified oauth files add no log calls; changes only build URLs and add tests, with no passwords/tokens/PII emitted to logs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/OCPBUGS-86260-oauth-login-url-dns

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 28, 2026

Copy link
Copy Markdown
Contributor

@chdeshpa-hue: 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/security 0c3defe link true /test security
ci/prow/okd-scos-images 0c3defe link true /test okd-scos-images
ci/prow/images 0c3defe link true /test images
ci/prow/verify-deps 0c3defe link true /test verify-deps

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.

@openshift-ci

openshift-ci Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: chdeshpa-hue
Once this PR has been reviewed and has the lgtm label, please assign bryan-cox 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 area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release label Jun 28, 2026
@openshift-ci
openshift-ci Bot requested review from cblecker and sjenning June 28, 2026 09:52

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go (1)

35-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use When ... it should ... for the new subtest names.

These case descriptions do not follow the repository’s required unit-test wording. As per coding guidelines, Always use "When ... it should ..." format for describing test cases when creating unit tests.

🤖 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
`@control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go`
around lines 35 - 52, The new table-driven subtest names in the OAuth config
test do not follow the required unit-test wording. Update the `name` values in
`config_test.go` to use the repository’s `When ... it should ...` format,
keeping the same scenarios in the `Test...`/subtest cases that exercise the
login URL selection logic.

Source: Coding guidelines

🤖 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
`@control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go`:
- Around line 28-56: The LoginURL test table in config_test.go does not cover
the new IPv6 bracketing behavior introduced through pki.AddBracketsIfIPv6, so
add a case in the existing table-driven test that uses an IPv6 host and expects
the bracketed https URL. Update the relevant assertions in the login URL test
helper/setup so the new case exercises the same path as the current
kubeAPIServerDNS and annotation scenarios, ensuring the IPv6 formatting is
verified alongside the existing LoginURL logic.

---

Nitpick comments:
In
`@control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go`:
- Around line 35-52: The new table-driven subtest names in the OAuth config test
do not follow the required unit-test wording. Update the `name` values in
`config_test.go` to use the repository’s `When ... it should ...` format,
keeping the same scenarios in the `Test...`/subtest cases that exercise the
login URL selection logic.
🪄 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: 3f3d33b2-1d3a-4596-9a3a-5c55ffb8cf4d

📥 Commits

Reviewing files that changed from the base of the PR and between c180b15 and 0c3defe.

📒 Files selected for processing (2)
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go

Comment on lines +28 to +56
tests := []struct {
name string
kubeAPIServerDNS string
loginURLAnnotation string
expectedLoginURL string
}{
{
name: "no kubeAPIServerDNSName — uses controlPlaneEndpoint host",
kubeAPIServerDNS: "",
expectedLoginURL: fmt.Sprintf("https://%s:%d", lbHost, lbPort),
},
{
name: "kubeAPIServerDNSName set — uses DNS name",
kubeAPIServerDNS: dnsName,
expectedLoginURL: fmt.Sprintf("https://%s:%d", dnsName, lbPort),
},
{
name: "kubeAPIServerDNSName set but annotation override present — annotation wins",
kubeAPIServerDNS: dnsName,
loginURLAnnotation: "https://iam.custom.ibm.com/login",
expectedLoginURL: "https://iam.custom.ibm.com/login",
},
{
name: "only annotation override, no DNS name — annotation used",
kubeAPIServerDNS: "",
loginURLAnnotation: "https://iam.custom.ibm.com/login",
expectedLoginURL: "https://iam.custom.ibm.com/login",
},
}

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a case for the new IPv6 bracketing path.

The production change now routes LoginURL through pki.AddBracketsIfIPv6(...), but this table only exercises IPv4, DNS, and annotation inputs. A regression back to an unbracketed IPv6 URL would still pass here. As per coding guidelines, Unit test any code changes and additions.

Also applies to: 71-74, 99-99

🤖 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
`@control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go`
around lines 28 - 56, The LoginURL test table in config_test.go does not cover
the new IPv6 bracketing behavior introduced through pki.AddBracketsIfIPv6, so
add a case in the existing table-driven test that uses an IPv6 host and expects
the bracketed https URL. Update the relevant assertions in the login URL test
helper/setup so the new case exercises the same path as the current
kubeAPIServerDNS and annotation scenarios, ensuring the IPv6 formatting is
verified alongside the existing LoginURL logic.

Source: Coding guidelines

@chdeshpa-hue

Copy link
Copy Markdown
Contributor Author

Closing — this fix was already merged in commit 7404745 ("fix(cpo): use KubeAPIServerDNSName for OAuth LoginURL when set" by @amasolov, May 6 2026). The current main branch already contains the identical logic using net/url + net.JoinHostPort.

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

Labels

area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant