Skip to content

OCPBUGS-49691: Include named cert CAs in root-ca ConfigMap#9064

Open
hypershift-jira-solve-ci[bot] wants to merge 2 commits into
openshift:mainfrom
hypershift-community:fix-OCPBUGS-49691
Open

OCPBUGS-49691: Include named cert CAs in root-ca ConfigMap#9064
hypershift-jira-solve-ci[bot] wants to merge 2 commits into
openshift:mainfrom
hypershift-community:fix-OCPBUGS-49691

Conversation

@hypershift-jira-solve-ci

@hypershift-jira-solve-ci hypershift-jira-solve-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

When named certificates are configured for KAS via
spec.configuration.apiServer.servingCerts.namedCertificates, the CA
certificates that signed them were not included in the root-ca
ConfigMap. This caused TLS verification failures for in-cluster
clients connecting to the KAS external endpoint using the in-cluster
CA bundle (e.g., ArgoCD running with a service account).

This PR fixes the issue by:

  • Extending ReconcileRootCAConfigMap to accept the named certificate secrets
    and append their tls.crt content to the CA bundle.
  • Adding a getRootCATrustSources helper to reconcilePKI that retrieves both
    the observed default ingress cert and named certificate secrets.
  • Removing the previously dead includeServingCertificates function, which was
    written for this purpose but never wired in, since the logic is now properly
    integrated into the reconciliation flow.
  • Adding error wrapping, empty-name guards, and warning logs for edge cases.
  • Adding unit tests with t.Parallel() and Gomega assertions for consistency.

Which issue(s) this PR fixes:

Fixes https://redhat.atlassian.net/browse/OCPBUGS-49691

Special notes for your reviewer:

The includeServingCertificates function that was removed was dead code — it existed but was never called. The new implementation integrates the same logic directly into the reconciliation flow.

Checklist:

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

Always review AI generated responses prior to use.
Generated with Claude Code via openshift-developer plugin


Note: This PR was auto-generated by the jira-agent periodic CI job in response to OCPBUGS-49691. See the full report for token usage, cost breakdown, and detailed phase output.

Summary by CodeRabbit

  • Enhancements

    • Root CA trust bundles now include certificates from configured named certificates.
    • Default ingress certificates continue to be included when ingress is enabled.
    • Empty or unavailable named certificate entries are safely skipped.
  • Bug Fixes

    • Improved PKI reconciliation to consistently combine root, ingress, and configured certificate authorities into the trust bundle.

OpenShift CI Bot and others added 2 commits July 22, 2026 18:03
When named certificates are configured for KAS via
spec.configuration.apiServer.servingCerts.namedCertificates, the CA
certificates that signed them were not included in the root-ca
ConfigMap. This caused TLS verification failures for in-cluster
clients connecting to the KAS external endpoint using the in-cluster
CA bundle (e.g., ArgoCD running with a service account).

ReconcileRootCAConfigMap now accepts the named certificate secrets and
appends their tls.crt content to the CA bundle. The reconcilePKI
method delegates trust source fetching to a new getRootCATrustSources
helper that retrieves both the observed default ingress cert and
named certificate secrets.

The previously dead includeServingCertificates function, which was
written for this purpose but never wired in, is removed since the
logic is now properly integrated into the reconciliation flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add error wrapping in reconcilePKI for getRootCATrustSources error
- Add empty-name guard for named certificates (matching OAuth path)
- Add warning log when skipping NotFound named cert secrets
- Add t.Parallel() to TestReconcileRootCAConfigMap and subtests
- Switch test assertions to Gomega for pki package consistency
- Add test case for named cert secret with no tls.crt key

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.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-robot openshift-ci-robot added jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. labels Jul 22, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@hypershift-jira-solve-ci[bot]: This pull request references Jira Issue OCPBUGS-49691, 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:

What this PR does / why we need it:

When named certificates are configured for KAS via
spec.configuration.apiServer.servingCerts.namedCertificates, the CA
certificates that signed them were not included in the root-ca
ConfigMap. This caused TLS verification failures for in-cluster
clients connecting to the KAS external endpoint using the in-cluster
CA bundle (e.g., ArgoCD running with a service account).

This PR fixes the issue by:

  • Extending ReconcileRootCAConfigMap to accept the named certificate secrets
    and append their tls.crt content to the CA bundle.
  • Adding a getRootCATrustSources helper to reconcilePKI that retrieves both
    the observed default ingress cert and named certificate secrets.
  • Removing the previously dead includeServingCertificates function, which was
    written for this purpose but never wired in, since the logic is now properly
    integrated into the reconciliation flow.
  • Adding error wrapping, empty-name guards, and warning logs for edge cases.
  • Adding unit tests with t.Parallel() and Gomega assertions for consistency.

Which issue(s) this PR fixes:

Fixes https://redhat.atlassian.net/browse/OCPBUGS-49691

Special notes for your reviewer:

The includeServingCertificates function that was removed was dead code — it existed but was never called. The new implementation integrates the same logic directly into the reconciliation flow.

Checklist:

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

Always review AI generated responses prior to use.
Generated with Claude Code via openshift-developer plugin

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 Jul 22, 2026
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The controller now collects the observed default ingress certificate and configured named certificate Secrets for PKI reconciliation. ReconcileRootCAConfigMap accepts these sources, builds the aggregate CA bundle, and appends non-empty named certificate data. New table-driven tests cover certificate combination and skipped empty or missing TLS data.

Sequence Diagram(s)

sequenceDiagram
  participant HostedControlPlaneReconciler
  participant KubernetesAPI
  participant ReconcileRootCAConfigMap
  participant RootCAConfigMap
  HostedControlPlaneReconciler->>KubernetesAPI: Retrieve ingress ConfigMap and named certificate Secrets
  HostedControlPlaneReconciler->>ReconcileRootCAConfigMap: Provide trust sources
  ReconcileRootCAConfigMap->>RootCAConfigMap: Build and append CA certificates
Loading

Suggested reviewers: bryan-cox

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
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 changed tests use only static, descriptive names; no dynamic values or generated identifiers appear in titles.
Test Structure And Quality ✅ Passed The new unit test is table-driven, each subtest covers one behavior, uses isolated data, and has no cluster waits or cleanup concerns.
Topology-Aware Scheduling Compatibility ✅ Passed The PR only changes root-CA PKI reconciliation and tests; it adds no pod affinity, node selectors, replicas, or topology logic.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PASS: PR adds only unit tests (testing.T/Gomega), not Ginkgo e2e tests; no IPv4-only literals or external connectivity in the new test files.
No-Weak-Crypto ✅ Passed Touched files only manipulate TLS cert bundles; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret comparisons found.
Container-Privileges ✅ Passed PR only changes Go PKI logic/tests; no container manifests or privilege settings (privileged/hostPID/allowPrivilegeEscalation/etc.) appear in the changed files.
No-Sensitive-Data-In-Logs ✅ Passed PASS: The only new log records a missing named-cert secret name; no passwords, tokens, cert contents, hostnames, or customer data are logged.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: including named certificate CAs in the root-ca ConfigMap.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci
openshift-ci Bot requested review from enxebre and muraee July 22, 2026 18:28
@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: hypershift-jira-solve-ci[bot]
Once this PR has been reviewed and has the lgtm label, please assign muraee 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 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 Jul 22, 2026

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

118-120: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Wrap the aggregate-CA error with context.

The new branch propagates the error bare, which loses the failing reconciliation step for callers other than the current controller. Use %w when rethrowing.

Based on coding guidelines, “Wrap errors with context when rethrowing.”

Proposed fix
 if err := reconcileAggregateCA(cm, ownerRef, sources...); err != nil {
-	return err
+	return fmt.Errorf("failed to reconcile aggregate CA: %w", err)
 }
🤖 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/pki/ca.go` around lines
118 - 120, Update the error return in the reconcileAggregateCA call to wrap the
underlying error with context using %w, identifying the aggregate-CA
reconciliation step while preserving error unwrapping for callers.

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/hostedcontrolplane_controller.go`:
- Around line 1904-1918: The named certificate Secret lookup in the
HostedControlPlane reconciliation flow does not establish watches for
user-managed Secrets. Update the controller setup and the named-certificate
handling around GetNamedCertificates to watch referenced Secrets and enqueue the
owning HostedControlPlane when those Secrets are created, updated, or deleted,
while preserving the existing not-found and error behavior.

---

Nitpick comments:
In `@control-plane-operator/controllers/hostedcontrolplane/pki/ca.go`:
- Around line 118-120: Update the error return in the reconcileAggregateCA call
to wrap the underlying error with context using %w, identifying the aggregate-CA
reconciliation step while preserving error unwrapping for callers.
🪄 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: eddfa1fc-40be-4f29-a7d6-94085e518a0d

📥 Commits

Reviewing files that changed from the base of the PR and between 09265ac and 991af7c.

📒 Files selected for processing (4)
  • control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
  • control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go
  • control-plane-operator/controllers/hostedcontrolplane/pki/ca.go
  • control-plane-operator/controllers/hostedcontrolplane/pki/ca_test.go
💤 Files with no reviewable changes (1)
  • control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go

Comment on lines +1904 to +1918
var namedCertSecrets []*corev1.Secret
for _, namedCert := range hcp.Spec.Configuration.GetNamedCertificates() {
if namedCert.ServingCertificate.Name == "" {
continue
}
secret := &corev1.Secret{}
if err := r.Get(ctx, client.ObjectKey{Namespace: hcp.Namespace, Name: namedCert.ServingCertificate.Name}, secret); err != nil {
if !apierrors.IsNotFound(err) {
return nil, nil, fmt.Errorf("failed to get named certificate secret %s: %w", namedCert.ServingCertificate.Name, err)
}
log := ctrl.LoggerFrom(ctx)
log.Info("Named certificate secret not found, skipping for root CA trust bundle", "secret", namedCert.ServingCertificate.Name)
continue
}
namedCertSecrets = append(namedCertSecrets, secret)

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C 4 'SetupWithManager|Watches\(|Owns\(|EnqueueRequestsFromMapFunc|NamedCertificates|ServingCertificate' control-plane-operator/controllers/hostedcontrolplane

Repository: openshift/hypershift

Length of output: 33300


Watch the named certificate Secrets here. This code only reads them during HCP reconcile, and the Secret watch in this controller only enqueues owner refs. If these are user-managed Secrets, create/update/delete events won’t trigger a reconcile, so root-ca can stay stale until some unrelated HCP change.

🤖 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/hostedcontrolplane_controller.go`
around lines 1904 - 1918, The named certificate Secret lookup in the
HostedControlPlane reconciliation flow does not establish watches for
user-managed Secrets. Update the controller setup and the named-certificate
handling around GetNamedCertificates to watch referenced Secrets and enqueue the
owning HostedControlPlane when those Secrets are created, updated, or deleted,
while preserving the existing not-found and error behavior.

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@hypershift-jira-solve-ci[bot]: 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.

@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 44.44444% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.51%. Comparing base (09265ac) to head (991af7c).

Files with missing lines Patch % Lines
...ostedcontrolplane/hostedcontrolplane_controller.go 37.03% 14 Missing and 3 partials ⚠️
...-operator/controllers/hostedcontrolplane/pki/ca.go 66.66% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9064   +/-   ##
=======================================
  Coverage   44.50%   44.51%           
=======================================
  Files         774      774           
  Lines       96980    96988    +8     
=======================================
+ Hits        43164    43175   +11     
+ Misses      50828    50821    -7     
- Partials     2988     2992    +4     
Files with missing lines Coverage Δ
...-operator/controllers/hostedcontrolplane/pki/ca.go 39.24% <66.66%> (+30.90%) ⬆️
...ostedcontrolplane/hostedcontrolplane_controller.go 45.45% <37.03%> (-0.57%) ⬇️
Flag Coverage Δ
cmd-support 38.39% <ø> (ø)
cpo-hostedcontrolplane 47.23% <44.44%> (+0.04%) ⬆️
cpo-other 45.25% <ø> (ø)
hypershift-operator 54.44% <ø> (ø)
other 32.64% <ø> (ø)

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.

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 jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. jira/severity-moderate Referenced Jira bug's severity is moderate 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.

1 participant