Skip to content

Conversation

@celebdor
Copy link
Collaborator

What this PR does / why we need it:

Fix regression in 4.19 where HCP router LoadBalancer service was created unexpectedly for configurations using Route hostnames under the management cluster's apps domain.

After upgrading HCP clusters from 4.18 to 4.19, a router service of type LoadBalancer is created unexpectedly. On platforms with limited LoadBalancer IPs (e.g., BareMetal with exhausted MetalLB IPAddressPool), the service stays in <pending> state and blocks the upgrade.

The fix for OCPBUGS-56914 (PR #6780) changed the condition for creating the public router service from checking only if KAS uses Route to checking if ANY service uses Route with hostname. This caused the router service to be created for configurations that previously didn't need it.

This PR adds IsPublicWithExternalDNS() function that checks if any service uses a Route with a hostname that is external to the management cluster's default ingress domain. When hostnames are subdomains of the apps domain (e.g., oauth.apps.mgmt-cluster.example.com), the management cluster's default router can serve them via wildcard DNS, so no dedicated HCP router LoadBalancer service is needed.

This preserves the OCPBUGS-56914 fix for external DNS users while preventing unnecessary router service creation for apps-domain routes.

Which issue(s) this PR fixes:
Fixes OCPBUGS-69866

Checklist

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

🤖 Generated with Claude Code

@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Dec 19, 2025
@openshift-ci-robot
Copy link

@celebdor: This pull request references Jira Issue OCPBUGS-69866, which is invalid:

  • release note text must be set and not match the template OR release note type must be set to "Release Note Not Required". For more information you can reference the OpenShift Bug Process.
  • expected Jira Issue OCPBUGS-69866 to depend on a bug targeting a version in 4.20.0, 4.20.z and in one of the following states: VERIFIED, RELEASE PENDING, CLOSED (ERRATA), CLOSED (CURRENT RELEASE), CLOSED (DONE), CLOSED (DONE-ERRATA), but no dependents were found

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:

What this PR does / why we need it:

Fix regression in 4.19 where HCP router LoadBalancer service was created unexpectedly for configurations using Route hostnames under the management cluster's apps domain.

After upgrading HCP clusters from 4.18 to 4.19, a router service of type LoadBalancer is created unexpectedly. On platforms with limited LoadBalancer IPs (e.g., BareMetal with exhausted MetalLB IPAddressPool), the service stays in <pending> state and blocks the upgrade.

The fix for OCPBUGS-56914 (PR #6780) changed the condition for creating the public router service from checking only if KAS uses Route to checking if ANY service uses Route with hostname. This caused the router service to be created for configurations that previously didn't need it.

This PR adds IsPublicWithExternalDNS() function that checks if any service uses a Route with a hostname that is external to the management cluster's default ingress domain. When hostnames are subdomains of the apps domain (e.g., oauth.apps.mgmt-cluster.example.com), the management cluster's default router can serve them via wildcard DNS, so no dedicated HCP router LoadBalancer service is needed.

This preserves the OCPBUGS-56914 fix for external DNS users while preventing unnecessary router service creation for apps-domain routes.

Which issue(s) this PR fixes:
Fixes OCPBUGS-69866

Checklist

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

🤖 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.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • do-not-merge/work-in-progress

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This change introduces domain-aware DNS routing logic for hosted control planes. It adds utility functions to validate subdomain relationships and determine external DNS usage, enabling the router service creation to trigger only for hostnames outside the management cluster's default ingress domain rather than all public routes.

Changes

Cohort / File(s) Summary
Router Service Reconciliation Logic
control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go, control-plane-operator/controllers/hostedcontrolplane/v2/router/component.go
Updated router service creation logic to use domain-aware checks (IsPublicWithExternalDNS and useHCPRouter) instead of generic public route checks, triggering only when hostnames fall outside the default ingress domain.
Context and Domain Configuration
support/controlplane-component/controlplane-component.go
Added DefaultIngressDomain string field to both ControlPlaneContext and WorkloadContext, with propagation through the workloadContext() converter method.
DNS and Subdomain Utilities
support/util/expose.go, support/util/visibility.go
Added three new public functions: IsSubdomain() for validating hostname-domain relationships, UseDedicatedDNSWithDomain() and UseDedicatedDNSByHCWithDomain() for domain-aware router decisions, and IsPublicWithExternalDNS() to detect external DNS usage across multiple control plane services.
Test Coverage
support/util/expose_test.go, support/util/visibility_test.go
Added comprehensive test functions TestIsSubdomain(), TestUseDedicatedDNSWithDomain(), and TestIsPublicWithExternalDNS() covering subdomain matching logic, DNS decision scenarios, and external DNS detection with various hostname and domain configurations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Domain comparison logic in IsSubdomain(): Verify correctness of case-insensitive DNS label comparison and subdomain validation edge cases (empty inputs, boundary conditions, partial label matching)
  • Consistency of domain checks: Ensure DefaultIngressDomain is properly propagated through all context layers and used consistently across controller and utility functions
  • External DNS detection logic: Review IsPublicWithExternalDNS() implementation across multiple services (APIServer, OAuthServer, Konnectivity, Ignition) to confirm all relevant cases are covered
  • Router service reconciliation changes: Verify that the transition from IsPublicWithDNS to IsPublicWithExternalDNS correctly gates router service creation and doesn't break existing public route scenarios
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@openshift-ci openshift-ci bot requested review from hasueki and rtheis December 19, 2025 19:14
@openshift-ci openshift-ci bot added area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release and removed do-not-merge/needs-area labels Dec 19, 2025
@devguyio
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devguyio
Copy link
Contributor

/uncc @hasueki @rtheis
/cc @sjenning @csrwng @devguyio

@openshift-ci openshift-ci bot requested review from csrwng, devguyio and sjenning and removed request for hasueki and rtheis December 19, 2025 19:34
Copy link
Contributor

@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: 0

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

1947-1985: Align external-router infra status with new IsPublicWithExternalDNS gating

reconcileHCPRouterServices now only creates the public router LoadBalancer service when util.IsPublicWithExternalDNS(hcp, r.DefaultIngressDomain) is true, but reconcileExternalRouterServiceStatus still gates on util.IsPublicWithDNS(hcp). For public HCPs whose Route hostnames are all under the management apps domain:

  • IsPublicWithDNS(hcp) remains true, so reconcileExternalRouterServiceStatus reports needed == true even though no public router service is ever created.
  • reconcileRouterServiceStatus then runs against a non-existent Service, returning needed == true with an empty host.

If infra.InfrastructureStatus.IsReady() depends on NeedExternalRouter implying an actual external router host, this divergence can keep infrastructure perpetually “not ready” even though we intentionally skipped creating a public router LB for apps-domain routes, undermining the goal of this PR.

Consider gating the external router status on the same predicate used for LB creation:

Proposed change for external-router status gating
 func (r *HostedControlPlaneReconciler) reconcileExternalRouterServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, needed bool, message string, err error) {
-	if !util.IsPublicWithDNS(hcp) || sharedingress.UseSharedIngress() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
+	if !util.IsPublicWithExternalDNS(hcp, r.DefaultIngressDomain) || sharedingress.UseSharedIngress() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
 		return
 	}
 	return r.reconcileRouterServiceStatus(ctx, manifests.RouterPublicService(hcp.Namespace), events.NewMessageCollector(ctx, r.Client))
 }

This keeps infra status expectations consistent with when the public router LB is actually reconciled.

Also applies to: 2087-2092

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 58862c5 and c5320f9.

📒 Files selected for processing (7)
  • control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go (2 hunks)
  • control-plane-operator/controllers/hostedcontrolplane/v2/router/component.go (1 hunks)
  • support/controlplane-component/controlplane-component.go (3 hunks)
  • support/util/expose.go (3 hunks)
  • support/util/expose_test.go (1 hunks)
  • support/util/visibility.go (1 hunks)
  • support/util/visibility_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • support/controlplane-component/controlplane-component.go
  • control-plane-operator/controllers/hostedcontrolplane/v2/router/component.go
  • support/util/expose_test.go
  • support/util/expose.go
  • support/util/visibility.go
  • support/util/visibility_test.go
  • control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
🧬 Code graph analysis (6)
control-plane-operator/controllers/hostedcontrolplane/v2/router/component.go (3)
support/controlplane-component/controlplane-component.go (1)
  • WorkloadContext (68-87)
hypershift-operator/controllers/sharedingress/sharedingress_controller.go (1)
  • UseSharedIngress (227-230)
support/util/visibility.go (2)
  • IsPrivateHCP (9-14)
  • IsPublicWithExternalDNS (51-56)
support/util/expose_test.go (3)
support/util/expose.go (2)
  • IsSubdomain (60-78)
  • UseDedicatedDNSWithDomain (84-91)
api/hypershift/v1beta1/hostedcluster_types.go (5)
  • ServiceType (845-845)
  • OAuthServer (855-855)
  • Route (836-836)
  • APIServer (849-849)
  • LoadBalancer (832-832)
hypershift-operator/controllers/sharedingress/sharedingress_controller.go (1)
  • Hostname (232-238)
support/util/expose.go (2)
api/hypershift/v1beta1/hostedcluster_types.go (2)
  • ServiceType (845-845)
  • Route (836-836)
hypershift-operator/controllers/sharedingress/sharedingress_controller.go (1)
  • Hostname (232-238)
support/util/visibility.go (2)
support/util/expose.go (1)
  • UseDedicatedDNSWithDomain (84-91)
api/hypershift/v1beta1/hostedcluster_types.go (4)
  • APIServer (849-849)
  • OAuthServer (855-855)
  • Konnectivity (852-852)
  • Ignition (858-858)
support/util/visibility_test.go (2)
hypershift-operator/controllers/sharedingress/sharedingress_controller.go (1)
  • Hostname (232-238)
support/util/visibility.go (1)
  • IsPublicWithExternalDNS (51-56)
control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go (1)
support/util/visibility.go (1)
  • IsPublicWithExternalDNS (51-56)
🔇 Additional comments (10)
support/controlplane-component/controlplane-component.go (1)

58-66: DefaultIngressDomain propagation into workload context looks correct

Adding DefaultIngressDomain to both ControlPlaneContext and WorkloadContext and wiring it through workloadContext() cleanly exposes the management cluster ingress domain to v2 components without affecting existing behavior when the field is unset.

Also applies to: 82-87, 89-103

control-plane-operator/controllers/hostedcontrolplane/v2/router/component.go (1)

49-62: v2 router predicate correctly narrows public LB usage to external-DNS hostnames

Using util.IsPrivateHCP(cpContext.HCP) || util.IsPublicWithExternalDNS(cpContext.HCP, cpContext.DefaultIngressDomain) aligns the router component with the new “apps-domain vs external-domain” semantics while still honoring shared-ingress and private-HCP behavior.

support/util/visibility_test.go (1)

89-238: IsPublicWithExternalDNS tests cover key domain and platform scenarios

The table-driven TestIsPublicWithExternalDNS exercises external vs apps-domain hostnames, mixed cases, private AWS, and no-hostname routes, matching the intended semantics of IsPublicWithExternalDNS and giving solid regression coverage.

control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go (1)

1047-1060: Passing DefaultIngressDomain into CPO v2 components is appropriate

Propagating r.DefaultIngressDomain into component.ControlPlaneContext ensures v2 components (like the router) can make domain-aware decisions without altering existing callers. If DefaultIngressDomain can legitimately be empty on some management clusters, please confirm IsPublicWithExternalDNS/UseDedicatedDNSWithDomain handle that case as intended (e.g., whether an empty domain should cause all hostnames to be treated as “external” or not).

support/util/visibility.go (1)

47-56: IsPublicWithExternalDNS provides a clean domain-aware variant of IsPublicWithDNS

The new IsPublicWithExternalDNS helper correctly reuses IsPublicHCP and UseDedicatedDNSWithDomain across all relevant service types, matching the documented intent of only treating hostnames outside the management cluster’s default ingress domain as requiring a dedicated HCP router LoadBalancer.

support/util/expose_test.go (2)

9-84: Excellent test coverage for IsSubdomain.

The test cases comprehensively cover:

  • Valid subdomain relationships (single and multi-level)
  • Boundary conditions (exact match, empty inputs, shorter hostname)
  • Edge cases (partial label matches, suffix matches, case sensitivity)

The test structure follows Go best practices with clear test names and expected outcomes.


86-209: Thorough test coverage for UseDedicatedDNSWithDomain.

The test cases validate the core logic for determining when a dedicated DNS router is needed:

  • Routes with hostnames under the apps domain correctly return false (no dedicated router needed)
  • Routes with external hostnames correctly return true (dedicated router needed)
  • Edge cases (empty hostname, LoadBalancer type, empty domain, missing service) are properly handled

This aligns well with the PR objective to prevent unnecessary router LoadBalancer creation for apps-domain routes.

support/util/expose.go (3)

56-78: Clean implementation of subdomain validation.

The function correctly:

  • Handles empty inputs by returning false
  • Performs case-insensitive comparison using strings.ToLower
  • Validates proper subdomain relationship (hostname must have more labels than domain)
  • Compares labels from right to left, ensuring full domain suffix match

The documentation clearly explains the expected behavior with an example.


80-91: Correct implementation of domain-aware DNS routing logic.

The function properly implements the logic to determine when a dedicated HCP router is needed:

  • Returns false for non-Route services, nil Route, or empty hostname (correctly avoiding unnecessary router creation)
  • Returns true only when the route hostname is external to the management cluster's default ingress domain
  • Short-circuit evaluation (||) safely prevents nil pointer access

This aligns perfectly with the PR objective: preventing unnecessary router LoadBalancer creation when routes use the apps domain.


124-133: Consistent implementation for HostedCluster.

The function mirrors UseDedicatedDNSWithDomain but operates on HostedCluster instead of HostedControlPlane. The implementation follows the same pattern:

  • Uses IsRouteByHC and ServicePublishingStrategyByTypeByHC (HC-specific helpers)
  • Applies the same domain-aware logic via IsSubdomain

This consistency ensures uniform behavior across both HCP and HC code paths.

@celebdor celebdor force-pushed the fix/OCPBUGS-69866-skip-router-lb-apps-domain branch from c5320f9 to 4963a89 Compare December 19, 2025 19:52
@celebdor
Copy link
Collaborator Author

Thanks for the review feedback @coderabbitai! I've addressed your concern about the inconsistency between reconcileHCPRouterServices and reconcileExternalRouterServiceStatus.

Changes made:

  1. Updated reconcileExternalRouterServiceStatus to use IsPublicWithExternalDNS(hcp, r.DefaultIngressDomain) instead of IsPublicWithDNS(hcp)
  2. Also updated the v1 useHCPRouter function to use IsPublicWithExternalDNS for consistency - this ensures the router deployment is only created when actually needed (private HCP or public with external DNS hostnames)

This keeps infra status expectations consistent with when the public router LB is actually reconciled.


AI-assisted response via Claude Code

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Tip

For best results, initiate chat on the files or code changes.

@celebdor: Thank you for addressing the consistency concern! The changes look good:

✅ Both reconcileExternalRouterServiceStatus and the router service creation logic now use IsPublicWithExternalDNS with the DefaultIngressDomain parameter
✅ The v1 useHCPRouter function is also updated for consistency
✅ This ensures the router deployment, service creation, and infrastructure status reporting all follow the same decision logic

The consistency across these components is important for avoiding the exact issue this PR fixes - ensuring that when we decide not to create a router LoadBalancer service (because routes use the apps domain), we don't report expectations for it in the infrastructure status either.

// Otherwise, the Routes use the management cluster Domain and resolve through the default ingress controller.
// Note: For public HCPs, we only need the HCP router if routes use hostnames external to the management cluster's
// apps domain. Hostnames under the apps domain are served by the management cluster's default router.
func useHCPRouter(cpContext component.WorkloadContext) (bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

let's export this function and reuse it in hostedcontrolpl;ane_contgroller.go instead of duplicating it twice.

Copy link
Contributor

Choose a reason for hiding this comment

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

you would need to change the parameters to take hcp and ingressDomain directly,

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Created shared util.UseHCPRouter(hcp, defaultIngressDomain, useSharedIngress) function in support/util/visibility.go and updated both v2 router component and v1 controller to use it.


AI-assisted response via Claude Code

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. The shared function takes hcp, defaultIngressDomain, and useSharedIngress as parameters.


AI-assisted response via Claude Code

}

func (r *HostedControlPlaneReconciler) reconcileHCPRouterServices(ctx context.Context, hcp *hyperv1.HostedControlPlane, createOrUpdate upsert.CreateOrUpdateFN) error {
if sharedingress.UseSharedIngress() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we please replace those inline checks with UseHCPRouter() func for consistency

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Updated reconcileHCPRouterServices to use util.UseHCPRouter() for the entry guard check, consolidating the logic.


AI-assisted response via Claude Code

// UseDedicatedDNSByHCWithDomain checks if a service uses external DNS that requires a dedicated HCP router.
// It returns true only if the service uses a Route with a hostname that is NOT a subdomain of the
// management cluster's default ingress domain.
func UseDedicatedDNSByHCWithDomain(hc *hyperv1.HostedCluster, svcType hyperv1.ServiceType, defaultIngressDomain string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func UseDedicatedDNSByHCWithDomain(hc *hyperv1.HostedCluster, svcType hyperv1.ServiceType, defaultIngressDomain string) bool {
func UseDedicatedDNSByHCWithExternalDomain(hc *hyperv1.HostedCluster, svcType hyperv1.ServiceType, defaultIngressDomain string) bool {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Renamed to UseDedicatedDNSByHCWithExternalDomain.


AI-assisted response via Claude Code

@celebdor celebdor force-pushed the fix/OCPBUGS-69866-skip-router-lb-apps-domain branch from 4963a89 to ccec1fa Compare December 22, 2025 17:06
// useHCPRouterPredicate is the component predicate wrapper for util.UseHCPRouter.
// See util.UseHCPRouter for full documentation on when a dedicated HCP router is needed.
func useHCPRouterPredicate(cpContext component.WorkloadContext) (bool, error) {
return util.UseHCPRouter(cpContext.HCP, cpContext.DefaultIngressDomain, sharedingress.UseSharedIngress()), nil
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer if we keep the exported function in this package. This should container all router related functionalities

@celebdor celebdor force-pushed the fix/OCPBUGS-69866-skip-router-lb-apps-domain branch 2 times, most recently from b15e3bc to b88f9a1 Compare December 22, 2025 18:31
@@ -0,0 +1,143 @@
# OCPBUGS-69866: HCP cluster upgrade to 4.19 creates unexpected router LoadBalancer service
Copy link
Contributor

Choose a reason for hiding this comment

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

this file needs to be removed from the PR

// It returns true only if the service uses a Route with a hostname that is NOT a subdomain of the
// management cluster's default ingress domain. Hostnames under the apps domain are served by the
// management cluster's default router and don't require a separate HCP router LoadBalancer service.
func UseDedicatedDNSWithDomain(hcp *hyperv1.HostedControlPlane, svcType hyperv1.ServiceType, defaultIngressDomain string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func UseDedicatedDNSWithDomain(hcp *hyperv1.HostedControlPlane, svcType hyperv1.ServiceType, defaultIngressDomain string) bool {
func UseDedicatedDNSWithExternalDomain(hcp *hyperv1.HostedControlPlane, svcType hyperv1.ServiceType, defaultIngressDomain string) bool {

thought the AI would be smart enough to change both :D

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Rename done. Thanks!

@muraee
Copy link
Contributor

muraee commented Dec 22, 2025

/approve

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 22, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: celebdor, muraee

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

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Dec 22, 2025
When upgrading HCP clusters from 4.18 to 4.19, the router LoadBalancer
service was created unexpectedly for configurations where services use
Route with hostnames under the management cluster's apps domain. This
caused upgrade failures on platforms with limited LoadBalancer IPs.

The fix adds DNS label-based subdomain checking to determine if route
hostnames are within the management cluster's default ingress domain.
When hostnames are subdomains of the apps domain (e.g.,
oauth.apps.mgmt-cluster.example.com), they can be served by the
management cluster's default router via wildcard DNS, so no dedicated
HCP router LoadBalancer service is needed.

This preserves the OCPBUGS-56914 fix for external DNS users while
preventing unnecessary router service creation for apps-domain routes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@celebdor celebdor force-pushed the fix/OCPBUGS-69866-skip-router-lb-apps-domain branch from b88f9a1 to ee45d1b Compare December 23, 2025 03:17
@celebdor celebdor 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 Dec 23, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 23, 2025

@celebdor: 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.

@heliubj18
Copy link
Contributor

I’ve posted my test results in the Jira issue. The router LB service was not created in 4.19, and the cluster was successfully upgraded from 4.18 to 4.19. No more LB svc is created any more.

@heliubj18
Copy link
Contributor

/verified by @heliubj18

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Dec 23, 2025
@openshift-ci-robot
Copy link

@heliubj18: This PR has been marked as verified by @heliubj18.

Details

In response to this:

/verified by @heliubj18

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.

@devguyio
Copy link
Contributor

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Dec 23, 2025
@bertinatto
Copy link
Member

/label backport-risk-assessed

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 26, 2025

@bertinatto: Can not set label backport-risk-assessed: Must be member in one of these teams: [openshift-patch-managers openshift-staff-engineers openshift-release-oversight openshift-sustaining-engineers]

Details

In response to this:

/label backport-risk-assessed

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.

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 area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release 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.

6 participants