Skip to content

OCPBUGS-88312: use in-cluster service for oauth-server - #8772

Merged
openshift-merge-bot[bot] merged 2 commits into
openshift:mainfrom
mihivagyok:use-incluser-service-for-oauth
Jul 20, 2026
Merged

OCPBUGS-88312: use in-cluster service for oauth-server#8772
openshift-merge-bot[bot] merged 2 commits into
openshift:mainfrom
mihivagyok:use-incluser-service-for-oauth

Conversation

@mihivagyok

@mihivagyok mihivagyok commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

When a user clicks “Display Token”, the oauth-openshift service attempts to call itself using the cluster’s API endpoint.
This self-call fails depending on whether the oauth-server is configured a public or private service URL as MasterURL.

In case of a public URL and control plane outbound connecitivty is restricted, the call fails.
In case a private URL, it can happen that the DNS is also a private one, and DNS resolution fails.

Which issue(s) this PR fixes:

Fixes OCPBUGS-88312

Special notes for your reviewer:

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • Bug Fixes
    • Improved OAuth master URL generation by consistently using the in-cluster OAuth service address.
    • Expanded OAuth server certificate DNS Subject Alternative Names to include the internal oauth-openshift service when the external endpoint is DNS-based.
    • Updated NO_PROXY handling to ensure required internal endpoints are reliably bypassed, including IBM Cloud-specific exceptions.
  • Tests
    • Added/extended unit test coverage for in-cluster OAuth DNS resolution, deployment proxy behavior, and OAuth configuration values.

@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-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. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Jun 18, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@mihivagyok: This pull request references Jira Issue OCPBUGS-88312, which is valid. The bug has been moved to the POST state.

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 New, which is one of the valid states (NEW, ASSIGNED, POST)

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

Details

In response to this:

What this PR does / why we need it:

When a user clicks “Display Token”, the oauth-openshift service attempts to call itself using the cluster’s API endpoint.
This self-call fails depending on whether the oauth-server is configured a public or private service URL as MasterURL.

In case of a public URL and control plane outbound connecitivty is restricted, the call fails.
In case a private URL, it can happen that the DNS is also a private one, and DNS resolution fails.

Which issue(s) this PR fixes:

Fixes OCPBUGS-88312

Special notes for your reviewer:

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

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 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 Jun 18, 2026
@openshift-ci

openshift-ci Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

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

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: f4de772d-cd35-4177-8536-8d8456b4d71e

📥 Commits

Reviewing files that changed from the base of the PR and between 9482bde and 284c540.

📒 Files selected for processing (2)
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config_test.go

📝 Walkthrough

Walkthrough

The PR changes OAuth in-cluster DNS handling for config, certificate SANs, and deployment proxy settings. It adds a helper to derive the OAuth service DNS name from the hosted control plane namespace, uses that DNS name for MasterURL, adds it as a certificate SAN, and updates NO_PROXY construction in the OAuth deployment to include the in-cluster OAuth service plus IBM Cloud IAM hosts only on IBM Cloud. Tests were updated for the new DNS helper, URL values, and proxy behavior.

Sequence Diagram(s)

sequenceDiagram
  participant HostedControlPlane
  participant adaptOAuthConfig
  participant ReconcileOAuthServerCert
  participant adaptDeployment
  HostedControlPlane->>adaptOAuthConfig: namespace, OAuth host/port
  adaptOAuthConfig->>adaptOAuthConfig: build in-cluster MasterURL
  HostedControlPlane->>ReconcileOAuthServerCert: externalOAuthAddress
  ReconcileOAuthServerCert->>ReconcileOAuthServerCert: add in-cluster DNS SAN
  HostedControlPlane->>adaptDeployment: platform, namespace
  adaptDeployment->>adaptDeployment: upsert NO_PROXY entries
Loading

Possibly related PRs

  • openshift/hypershift#8433: Also changes control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go in adaptOAuthConfig, but for OAuthConfig.LoginURL derivation.

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: switching oauth-server communication to an in-cluster service endpoint.
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 The added test titles are static, descriptive strings; none embed generated suffixes, timestamps, IPs, namespaces, or other runtime values.
Test Structure And Quality ✅ Passed The added tests are plain unit tests with no cluster resources or Eventually waits, and they match existing repo style.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: The touched files only change OAuth URLs, NO_PROXY, and cert SANs; no new nodeSelector, affinity, tolerations, spread constraints, or replica changes were added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the new unit tests use fake clients and in-cluster DNS, with IPv6 bracket coverage and no external connectivity.
No-Weak-Crypto ✅ Passed No weak crypto primitives, custom crypto, or secret comparisons were added; the changes only adjust OAuth URLs, NO_PROXY, and cert SANs.
Container-Privileges ✅ Passed No touched manifest or controller code adds privileged, host* namespace, SYS_ADMIN, allowPrivilegeEscalation, or root settings.
No-Sensitive-Data-In-Logs ✅ Passed Modified files add URL/DNS logic and tests, but searches found no logging calls or log statements exposing secrets/PII/hostnames.
✨ 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-robot

Copy link
Copy Markdown

@mihivagyok: This pull request references Jira Issue OCPBUGS-88312, 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)
Details

In response to this:

What this PR does / why we need it:

When a user clicks “Display Token”, the oauth-openshift service attempts to call itself using the cluster’s API endpoint.
This self-call fails depending on whether the oauth-server is configured a public or private service URL as MasterURL.

In case of a public URL and control plane outbound connecitivty is restricted, the call fails.
In case a private URL, it can happen that the DNS is also a private one, and DNS resolution fails.

Which issue(s) this PR fixes:

Fixes OCPBUGS-88312

Special notes for your reviewer:

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
  • Fixed OAuth server configuration to use consistent in-cluster service endpoints.
  • Corrected proxy settings to be applied consistently for OAuth operations across all platforms.
  • Improved service connectivity and discovery for OAuth server within hosted control planes.

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 openshift-ci Bot added area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release and removed do-not-merge/needs-area labels Jun 18, 2026
@mihivagyok
mihivagyok force-pushed the use-incluser-service-for-oauth branch 2 times, most recently from d31dfac to 36f1992 Compare June 18, 2026 12:17

@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.go (1)

73-73: ⚡ Quick win

Centralize OAuth service DNS construction to avoid cross-file drift.

Line 73 hardcodes the same namespace-scoped DNS contract that is also repeated in params.go and deployment.go. A shared helper/constant for oauth-openshift.<ns>.svc.cluster.local (and port where needed) will keep MasterURL/NO_PROXY paths consistent over time.

🤖 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.go` at
line 73, Extract the hardcoded OAuth service DNS construction pattern
(oauth-openshift.<namespace>.svc.cluster.local) from line 73 in config.go where
it's used to set cfg.OAuthConfig.MasterURL, and create a shared helper function
or constant in a common location that constructs this DNS name given a namespace
parameter. Then replace the inline string concatenation in config.go with a call
to this helper, and apply the same helper function to params.go and
deployment.go where this same pattern is repeated to ensure consistency across
all three files.
🤖 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/deployment.go`:
- Around line 55-63: Add unit tests to verify the NO_PROXY environment variable
configuration logic in the deployment setup. The tests should validate that the
noProxy list includes the namespace-scoped oauth-openshift service name, verify
that IBM Cloud entries (iam.cloud.ibm.com and iam.test.cloud.ibm.com) are only
appended when the platform type is hyperv1.IBMCloudPlatform (not for other
platform types), and confirm that the NO_PROXY environment variable is correctly
set via UpsertEnvVar with the comma-joined noProxy values. Include both positive
cases (when IBM Cloud platform is used) and negative cases (when other platforms
are used) to ensure the conditional logic works as intended.

---

Nitpick comments:
In `@control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go`:
- Line 73: Extract the hardcoded OAuth service DNS construction pattern
(oauth-openshift.<namespace>.svc.cluster.local) from line 73 in config.go where
it's used to set cfg.OAuthConfig.MasterURL, and create a shared helper function
or constant in a common location that constructs this DNS name given a namespace
parameter. Then replace the inline string concatenation in config.go with a call
to this helper, and apply the same helper function to params.go and
deployment.go where this same pattern is repeated to ensure consistency across
all three files.
🪄 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: 24758d2f-26ec-471a-983d-a60a8fa10823

📥 Commits

Reviewing files that changed from the base of the PR and between 7f7d696 and fbf9712.

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

Comment thread control-plane-operator/controllers/hostedcontrolplane/v2/oauth/deployment.go Outdated
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 43.13%. Comparing base (64f5e4e) to head (284c540).
⚠️ Report is 242 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8772      +/-   ##
==========================================
+ Coverage   43.12%   43.13%   +0.01%     
==========================================
  Files         766      766              
  Lines       94872    94873       +1     
==========================================
+ Hits        40909    40927      +18     
+ Misses      51115    51093      -22     
- Partials     2848     2853       +5     
Files with missing lines Coverage Δ
...erator/controllers/hostedcontrolplane/pki/oauth.go 40.90% <100.00%> (ø)
.../controllers/hostedcontrolplane/v2/oauth/config.go 49.43% <100.00%> (+3.00%) ⬆️
...trollers/hostedcontrolplane/v2/oauth/deployment.go 16.85% <100.00%> (+16.85%) ⬆️

... and 1 file with indirect coverage changes

Flag Coverage Δ
cmd-support 36.42% <ø> (ø)
cpo-hostedcontrolplane 45.38% <100.00%> (+0.10%) ⬆️
cpo-other 45.10% <ø> (ø)
hypershift-operator 53.28% <ø> (ø)
other 31.69% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
control-plane-operator/controllers/hostedcontrolplane/oauth/params.go (1)

41-43: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the comment to reflect broader usage.

The comment states the OAuthNoProxy field is "Currently only used for IBM Cloud specific addresses," but line 68 now seeds it with kube-apiserver, audit webhook service, and the OAuth service for all platforms. IBM Cloud-specific domains are conditionally appended later at line 98.

📝 Proposed fix
 // OAuthNoProxy is a list of hosts or IPs that should not be routed through
-// konnectivity. Currently only used for IBM Cloud specific addresses.
+// konnectivity. Includes in-cluster service endpoints and platform-specific addresses.
 OAuthNoProxy    []string
🤖 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/oauth/params.go` around
lines 41 - 43, The comment for the `OAuthNoProxy` field incorrectly states it is
"Currently only used for IBM Cloud specific addresses" when in fact the field is
seeded with addresses for kube-apiserver, audit webhook service, and OAuth
service for all platforms (as referenced in line 68), with IBM Cloud-specific
domains only conditionally appended later. Update the comment to accurately
describe that OAuthNoProxy contains hosts or IPs across multiple platforms that
should not be routed through konnectivity, noting that platform-specific
addresses like IBM Cloud domains may be conditionally included as needed.
🤖 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/oauth/params.go`:
- Line 68: In the OAuthNoProxy slice assignment in params.go, replace the
hardcoded service name "oauth-openshift" with the helper function
manifests.OauthServerService("").Name. This should be done in the FQDN
construction where the service name is concatenated with the namespace,
following the same pattern already established on the same line where
manifests.KubeAPIServerService("").Name is used. This change improves
consistency and maintainability by using the provided service name helper
function instead of hardcoding the string.

---

Outside diff comments:
In `@control-plane-operator/controllers/hostedcontrolplane/oauth/params.go`:
- Around line 41-43: The comment for the `OAuthNoProxy` field incorrectly states
it is "Currently only used for IBM Cloud specific addresses" when in fact the
field is seeded with addresses for kube-apiserver, audit webhook service, and
OAuth service for all platforms (as referenced in line 68), with IBM
Cloud-specific domains only conditionally appended later. Update the comment to
accurately describe that OAuthNoProxy contains hosts or IPs across multiple
platforms that should not be routed through konnectivity, noting that
platform-specific addresses like IBM Cloud domains may be conditionally included
as needed.
🪄 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: 9043bd14-706b-40f3-9ae8-545c17df2010

📥 Commits

Reviewing files that changed from the base of the PR and between fbf9712 and 36f1992.

📒 Files selected for processing (3)
  • control-plane-operator/controllers/hostedcontrolplane/oauth/params.go
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/deployment.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/config.go
  • control-plane-operator/controllers/hostedcontrolplane/v2/oauth/deployment.go

Comment thread control-plane-operator/controllers/hostedcontrolplane/oauth/params.go Outdated
@mihivagyok
mihivagyok force-pushed the use-incluser-service-for-oauth branch 8 times, most recently from 51ef123 to fa6e463 Compare June 18, 2026 13:59

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

Review Findings

Blockers

1. TLS SAN mismatch — oauth serving cert doesn't include the in-cluster FQDN

ReconcileOAuthServerCert (pki/oauth.go) generates the oauth serving cert with only the external OAuth hostname as a SAN. The new MasterURL (https://oauth-openshift.<ns>.svc.cluster.local:6443) is not in the cert's SANs. When the oauth process connects to that URL (bypassing konnectivity via NO_PROXY), TLS hostname verification should fail.

Either:

  • Add oauth-openshift.<ns>.svc.cluster.local to the SANs in ReconcileOAuthServerCert, or
  • Confirm that TLS hostname verification is skipped/disabled for MasterURL connections

2. params.goOAuthNoProxy is dead code

The OAuthNoProxy field is set in params.go but never consumed outside that file. NewOAuthServerParams is only called from reconcileValidIDPConfigurationCondition which checks IDP validity — it doesn't drive deployment reconciliation. This change has no runtime effect and should be removed or wired up.

Required

3. Use OAuthServerPort constant instead of hardcoded 6443

The port is hardcoded in v2/oauth/config.go. There's already oauth.OAuthServerPort = 6443 in oauth/service.go — use it instead of the magic number.

4. Tests for adaptOAuthConfig and adaptDeployment

No unit tests added (checklist item unchecked). Given the connectivity fix and the behavioral change to NO_PROXY for all platforms, table-driven tests verifying MasterURL, MasterPublicURL, and NO_PROXY contents per platform would make this safer to maintain.

@mihivagyok
mihivagyok force-pushed the use-incluser-service-for-oauth branch 2 times, most recently from 236271e to 0760e98 Compare June 24, 2026 11:19
@mihivagyok
mihivagyok requested a review from muraee June 24, 2026 12:23
@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mihivagyok, muraee, rtheis

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

The pull request process is described 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

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aks | Build: 2072676229412032512 | Cost: $3.3525889500000017 | Failed step: hypershift-azure-run-e2e

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@mihivagyok

Copy link
Copy Markdown
Contributor Author

/test e2e-aks

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aks | Build: 2072989141439614976 | Cost: $2.3232284999999995 | Failed step: hypershift-azure-run-e2e

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@mihivagyok

Copy link
Copy Markdown
Contributor Author

/retest

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aws | Build: 2074044369580593152 | Cost: $2.7119555 | Failed step: hypershift-aws-run-e2e-nested

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@mihivagyok

Copy link
Copy Markdown
Contributor Author

/retest

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aks | Build: 2074474219978100736 | Cost: $2.6314225 | Failed step: hypershift-azure-run-e2e

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@mihivagyok

Copy link
Copy Markdown
Contributor Author

/retest

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

Now I have all the evidence needed. Let me synthesize the analysis. The key findings are:

  1. PR OCPBUGS-88312: use in-cluster service for oauth-server #8772 changes are strictly limited to oauth-server configuration (masterURL, NO_PROXY, TLS SANs) — none of which touch DaemonSets, pull-secret syncing, node lifecycle, or Karpenter
  2. TestCreateCluster/EnsureGlobalPullSecret: global-pull-secret-syncer DaemonSet stuck at 2/3 pods ready for 20+ minutes → timeout. This is a data-plane DaemonSet issue unrelated to oauth-server changes.
  3. TestKarpenterUpgradeControlPlane: After control plane upgrade and drift detection, the old node (RHCOS 9.8.20260702-0) was never replaced with one running the new version (9.8.20260708-0 or 10.2.20260708-0). The node remained Ready but with the old OS image. This is a Karpenter node replacement issue unrelated to oauth changes.
  4. Previous runs: Jul 6 failed with NatGatewayLimitExceeded, Jul 7 with VpcLimitExceeded — both AWS quota exhaustion, confirming CI infrastructure instability.

Test Failure Analysis Complete

Job Information

  • Prow Job: pull-ci-openshift-hypershift-main-e2e-aws
  • Build ID: 2075207732704579584
  • Target: e2e-aws
  • PR: OCPBUGS-88312: use in-cluster service for oauth-server #8772 (OCPBUGS-88312: use in-cluster service for oauth-server)
  • Result: 599 tests run, 30 skipped, 7 failures (2 root-cause failures, 5 cascading)

Test Failure Analysis

Error

TestCreateCluster/Main/EnsureGlobalPullSecret: failed to wait for DaemonSet global-pull-secret-syncer
to be ready: context deadline exceeded (2/3 pods ready for 20+ minutes)

TestKarpenterUpgradeControlPlane/Main: Failed to wait for 1 nodes to become ready in 45m0s:
context deadline exceeded — expected node OS image to contain one of [9.8.20260708-0 10.2.20260708-0]
but got "Red Hat Enterprise Linux CoreOS 9.8.20260702-0 (Plow)"

Summary

Two independent test failures occurred, neither caused by PR #8772's changes. The PR modifies only the oauth-server's masterURL (switching to in-cluster service DNS), NO_PROXY environment variable, and TLS certificate SANs — all strictly control-plane oauth-server configuration. The failing tests involve data-plane DaemonSet readiness (global-pull-secret-syncer stuck at 2/3 pods) and Karpenter node replacement after drift detection (old RHCOS node never replaced despite being marked drifted). Prior runs of this PR failed due to AWS quota exhaustion (VpcLimitExceeded on Jul 7, NatGatewayLimitExceeded on Jul 6), confirming persistent CI infrastructure instability on the e2e-aws job for this PR.

Root Cause

Failure 1 — TestCreateCluster/EnsureGlobalPullSecret (cascade: 5 test failures)

The global-pull-secret-syncer DaemonSet in the hosted cluster was stuck at 2/3 pods ready. The test waited 20+ minutes (logged 100+ times "DaemonSet global-pull-secret-syncer not ready: 2/3 pods ready") before the context deadline exceeded. One pod on one of the 3 nodes failed to become ready. A secondary failure (Check_if_the_config.json_is_correct_in_all_of_the_nodes) then failed because the kubelet-config-verifier DaemonSet from the preceding subtest was still present (AlreadyExists error code 409).

This is a transient data-plane issue — one node's global-pull-secret-syncer pod did not reach Ready state. PR #8772 does not touch DaemonSets, pull-secret syncing, or any node-level components. The PR's scope is entirely within the oauth-openshift control-plane pod configuration (config.go, deployment.go, pki/oauth.go).

Failure 2 — TestKarpenterUpgradeControlPlane (1 test failure)

The test flow was:

  1. Created hosted cluster with initial release (RHCOS 9.8.20260702-0) ✓
  2. Created Karpenter NodePool and workloads ✓
  3. Nodes became ready, NodeClaims ready ✓
  4. Upgraded cluster image to latest release (containing RHCOS 9.8.20260708-0 / 10.2.20260708-0) ✓
  5. NodeClaim on-demand-6627p detected as drifted ✓
  6. HostedCluster rollout completed in 17m36s ✓
  7. Waited 45 minutes for node replacement — timed out. The old node ip-10-0-143-157.ec2.internal remained Ready with RHCOS 9.8.20260702-0 and was never replaced.

Karpenter detected the drift but failed to complete the node replacement cycle within 45 minutes. The old node was healthy (Ready=True, no resource pressure) but running the pre-upgrade OS version. This is a Karpenter node lifecycle issue — either the replacement node failed to launch, or Karpenter did not cordon/drain/terminate the old node. PR #8772 does not modify anything related to node lifecycle, machine management, or Karpenter integration.

CI Infrastructure Pattern:
All 3 runs of this PR's e2e-aws job failed:

  • Jul 6: NatGatewayLimitExceeded (AWS quota)
  • Jul 7: VpcLimitExceeded (AWS quota)
  • Jul 9: The two test failures described above

This pattern of different failure modes across retests, combined with AWS quota exhaustion in prior runs, strongly indicates CI environment instability rather than a PR-induced regression.

Recommendations
  1. Retest the PR — Both test failures are unrelated to the PR's oauth-server changes. Use /retest to trigger a new run, ideally during a lower-contention CI window.

  2. TestKarpenterUpgradeControlPlane flakiness — The Karpenter drift-and-replace cycle timing out at 45 minutes may indicate a race condition or AWS capacity issue in the CI environment. If this recurs, file a tracking issue for the test's reliability and consider increasing the timeout or adding diagnostic logging for the Karpenter node replacement flow.

  3. TestCreateCluster/EnsureGlobalPullSecret cleanup — The cascading failure (kubelet-config-verifier AlreadyExists) suggests the test's cleanup between subtests is incomplete. The verifier DaemonSet should be deleted before the next subtest attempts to create it. This is a pre-existing test robustness issue.

  4. AWS quota monitoring — Two of three runs hit AWS resource limits (VPC, NAT Gateway). The CI infrastructure team should monitor quota utilization for the hypershift-aws-quota-slice lease pool to prevent repeated quota-related failures.

Evidence
Evidence Detail
PR #8772 scope Only modifies config.go, deployment.go, pki/oauth.go — oauth-server masterURL, NO_PROXY, TLS SANs. 259 additions, 83 deletions across 16 files (including tests).
Failure 1: global-pull-secret-syncer DaemonSet stuck at 2/3 pods ready for 20+ minutes (100+ log lines). One pod on one node failed to reach Ready. Context deadline exceeded at util.go:2270.
Failure 1: cascade kubelet-config-verifier DaemonSet AlreadyExists (409) because previous subtest's cleanup didn't remove it.
Failure 2: Karpenter node drift NodeClaim on-demand-6627p detected as drifted in 3s. HostedCluster rollout completed in 17m36s. But node ip-10-0-143-157.ec2.internal kept RHCOS 9.8.20260702-0 instead of updating to 9.8.20260708-0 or 10.2.20260708-0. 45-minute timeout hit.
Failure 2: node health Old node was healthy: Ready=True, no MemoryPressure, no DiskPressure, no PIDPressure.
Jul 7 run (build 2074474220024238080) Failed in pre phase: VpcLimitExceeded: The maximum number of VPCs has been reached — pure AWS quota issue.
Jul 6 run (build 2074044369580593152) TestKarpenter failed: NatGatewayLimitExceeded: limit of 100 NAT gateways — pure AWS quota issue. TestKarpenterUpgradeControlPlane passed (3778s).
Test results summary 599 tests run, 30 skipped, 7 failures. 592 tests passed including ValidateHostedCluster, EnsureNoCrashingPods, EnsureNodeCommunication, all oauth-related tests.
PR change relevance oauth-server control-plane config ≠ data-plane DaemonSets or Karpenter node lifecycle. No code path overlap between PR changes and failing tests.

@rtheis

rtheis commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

/retest-required

1 similar comment
@rtheis

rtheis commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

/retest-required

@bryan-cox

Copy link
Copy Markdown
Member

/uncc @bryan-cox

@openshift-ci
openshift-ci Bot removed the request for review from bryan-cox July 16, 2026 12:58
@TwoDCube

Copy link
Copy Markdown
Member

/retest

@openshift-ci-robot

Copy link
Copy Markdown

@mihivagyok: The /verified command must be used with one of the following actions: by, later, remove, or bypass. See https://docs.ci.openshift.org/docs/architecture/jira/#premerge-verification for more information.

Details

In response to this:

/verified @mihivagyok

Environment: IBM Cloud, Openshift 5

With the change:

➜ kubectl get cm -n master-d9bk1jp30qm1jaentcl0 oauth-openshift -o yaml | grep master
     masterCA: /etc/kubernetes/certs/master-ca/ca.crt
     masterPublicURL: https://d9bk1jp30qm1jaentcl0.api.dev-us-south.containers.dev.cloud.ibm.com:30696
     masterURL: https://oauth-openshift.master-d9bk1jp30qm1jaentcl0.svc.cluster.local:6443

-> masterURL is using in-cluster service (before it was equal with masterPublicURL)

➜ kubectl get deployment -n master-d9bk1jp30qm1jaentcl0 oauth-openshift -o yaml | grep -A 1 NO_PROXY
       - name: NO_PROXY
         value: kube-apiserver,audit-webhook,oauth-openshift.master-d9bk1jp30qm1jaentcl0.svc.cluster.local,iam.cloud.ibm.com,iam.test.cloud.ibm.com

-> oauth-openshift deployment's NO_PROXY variable is extended with the internal service URL

Copy login command and request token is successful without any external connectivity requirement:

token_display

Thanks!

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.

@mihivagyok

Copy link
Copy Markdown
Contributor Author

/verified by @mihivagyok

Environment: IBM Cloud, Openshift 5

With the change:

➜ kubectl get cm -n master-d9bk1jp30qm1jaentcl0 oauth-openshift -o yaml | grep master
      masterCA: /etc/kubernetes/certs/master-ca/ca.crt
      masterPublicURL: https://d9bk1jp30qm1jaentcl0.api.dev-us-south.containers.dev.cloud.ibm.com:30696
      masterURL: https://oauth-openshift.master-d9bk1jp30qm1jaentcl0.svc.cluster.local:6443

-> masterURL is using in-cluster service (before it was equal with masterPublicURL)

➜ kubectl get deployment -n master-d9bk1jp30qm1jaentcl0 oauth-openshift -o yaml | grep -A 1 NO_PROXY
        - name: NO_PROXY
          value: kube-apiserver,audit-webhook,oauth-openshift.master-d9bk1jp30qm1jaentcl0.svc.cluster.local,iam.cloud.ibm.com,iam.test.cloud.ibm.com

-> oauth-openshift deployment's NO_PROXY variable is extended with the internal service URL

Copy login command and request token is successful without any external connectivity requirement:

token_display

Thanks!

@openshift-ci-robot

Copy link
Copy Markdown

@mihivagyok: Jira verification commands are restricted to collaborators for this repo.

Details

In response to this:

/verified by @mihivagyok

Environment: IBM Cloud, Openshift 5

With the change:

➜ kubectl get cm -n master-d9bk1jp30qm1jaentcl0 oauth-openshift -o yaml | grep master
     masterCA: /etc/kubernetes/certs/master-ca/ca.crt
     masterPublicURL: https://d9bk1jp30qm1jaentcl0.api.dev-us-south.containers.dev.cloud.ibm.com:30696
     masterURL: https://oauth-openshift.master-d9bk1jp30qm1jaentcl0.svc.cluster.local:6443

-> masterURL is using in-cluster service (before it was equal with masterPublicURL)

➜ kubectl get deployment -n master-d9bk1jp30qm1jaentcl0 oauth-openshift -o yaml | grep -A 1 NO_PROXY
       - name: NO_PROXY
         value: kube-apiserver,audit-webhook,oauth-openshift.master-d9bk1jp30qm1jaentcl0.svc.cluster.local,iam.cloud.ibm.com,iam.test.cloud.ibm.com

-> oauth-openshift deployment's NO_PROXY variable is extended with the internal service URL

Copy login command and request token is successful without any external connectivity requirement:

token_display

Thanks!

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.

@TwoDCube

Copy link
Copy Markdown
Member

/verified by @mihivagyok

#8772 (comment)

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Jul 16, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@TwoDCube: This PR has been marked as verified by @mihivagyok.

Details

In response to this:

/verified by @mihivagyok

#8772 (comment)

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.

@TwoDCube

Copy link
Copy Markdown
Member

/retest-required

@openshift-ci

openshift-ci Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@mihivagyok: all tests passed!

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-merge-bot
openshift-merge-bot Bot merged commit 999ff66 into openshift:main Jul 20, 2026
41 checks passed
@openshift-ci-robot

Copy link
Copy Markdown

@mihivagyok: Jira Issue Verification Checks: Jira Issue OCPBUGS-88312
✔️ This pull request was pre-merge verified.
✔️ All associated pull requests have merged.
✔️ All associated, merged pull requests were pre-merge verified.

Jira Issue OCPBUGS-88312 has been moved to the MODIFIED state and will move to the VERIFIED state when the change is available in an accepted nightly payload. 🕓

Details

In response to this:

What this PR does / why we need it:

When a user clicks “Display Token”, the oauth-openshift service attempts to call itself using the cluster’s API endpoint.
This self-call fails depending on whether the oauth-server is configured a public or private service URL as MasterURL.

In case of a public URL and control plane outbound connecitivty is restricted, the call fails.
In case a private URL, it can happen that the DNS is also a private one, and DNS resolution fails.

Which issue(s) this PR fixes:

Fixes OCPBUGS-88312

Special notes for your reviewer:

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • Bug Fixes
  • Improved OAuth master URL generation by consistently using the in-cluster OAuth service address.
  • Expanded OAuth server certificate DNS Subject Alternative Names to include the internal oauth-openshift service when the external endpoint is DNS-based.
  • Updated NO_PROXY handling to ensure required internal endpoints are reliably bypassed, including IBM Cloud-specific exceptions.
  • Tests
  • Added/extended unit test coverage for in-cluster OAuth DNS resolution, deployment proxy behavior, and OAuth configuration values.

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-merge-robot

Copy link
Copy Markdown
Contributor

Fix included in release 5.0.0-0.nightly-2026-07-21-023721

devguyio added a commit to devguyio/hypershift that referenced this pull request Jul 21, 2026
ModernTLS fixtures from openshift#8871 landed stale due to Tide merge skew.
GHA tested against a base that predated openshift#8772, openshift#8940, openshift#8971, openshift#8705
which changed oauth masterURL, wait-for-etcd init container, router
ordering, and etcd job label regex respectively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ahmed Abdalla <aabdelre@redhat.com>
vsolanki12 pushed a commit to vsolanki12/hypershift that referenced this pull request Aug 25, 2026
ModernTLS fixtures from openshift#8871 landed stale due to Tide merge skew.
GHA tested against a base that predated openshift#8772, openshift#8940, openshift#8971, openshift#8705
which changed oauth masterURL, wait-for-etcd init container, router
ordering, and etcd job label regex respectively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ahmed Abdalla <aabdelre@redhat.com>
rutvik23 pushed a commit to rutvik23/hypershift that referenced this pull request Aug 26, 2026
ModernTLS fixtures from openshift#8871 landed stale due to Tide merge skew.
GHA tested against a base that predated openshift#8772, openshift#8940, openshift#8971, openshift#8705
which changed oauth masterURL, wait-for-etcd init container, router
ordering, and etcd job label regex respectively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ahmed Abdalla <aabdelre@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release 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. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants