Skip to content

OCPBUGS-85151: Re-enable serviceaccount-pull-secrets controller when registry managementState changes from Removed#8522

Open
vsolanki12 wants to merge 1 commit into
openshift:mainfrom
vsolanki12:OCPBUGS-85151-hcco-re-enable-pull-secrets-controller
Open

OCPBUGS-85151: Re-enable serviceaccount-pull-secrets controller when registry managementState changes from Removed#8522
vsolanki12 wants to merge 1 commit into
openshift:mainfrom
vsolanki12:OCPBUGS-85151-hcco-re-enable-pull-secrets-controller

Conversation

@vsolanki12
Copy link
Copy Markdown
Contributor

@vsolanki12 vsolanki12 commented May 14, 2026

What this PR does / why we need it:

When the image registry managementState is set to Removed, HCCO disables the serviceaccount-pull-secrets controller in openshift-controller-manager by adding a -openshift.io/serviceaccount-pull-secrets override to the OCM ConfigMap. However, the logic was one-way — there was no code path to re-enable the controller when managementState changed back to Managed. Combined with CPO's preservation of existing controller overrides (PR #8072), this caused the controller to remain permanently disabled.

This change makes the logic bidirectional: when managementState is no longer Removed and the controller is currently disabled, it clears the controller override to re-enable it.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/OCPBUGS-85151

Special notes for your reviewer:

Tested manually on a self-managed HyperShift cluster (AWS, release 4.22.0-rc.3). Verified:

  1. Setting managementState: Removed disables the controller (log: "disabling serviceaccount-pull-secrets controller")
  2. Setting managementState: Managed re-enables the controller (log: "re-enabling serviceaccount-pull-secrets controller", controllers reset to null)
  3. CPO preservation logic correctly handles the cleared override

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

    • Service account pull-secrets controller is now toggled off/on precisely based on image registry management state using a disable-token, restores wildcard behavior when needed, skips unnecessary config writes, and preserves IBM Cloud/Azure behavior.
  • Tests

    • Added unit and reconciliation tests validating detection/removal of the disable-token and correct controller enable/disable behavior across state transitions and platforms.

@openshift-merge-bot
Copy link
Copy Markdown
Contributor

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

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

This repository is configured in: LGTM mode

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

openshift-ci Bot commented May 14, 2026

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

@openshift-ci-robot openshift-ci-robot added jira/severity-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. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels May 14, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@vsolanki12: This pull request references Jira Issue OCPBUGS-85151, 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 ASSIGNED, 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 the image registry managementState is set to Removed, HCCO disables the serviceaccount-pull-secrets controller in openshift-controller-manager by adding a -openshift.io/serviceaccount-pull-secrets override to the OCM ConfigMap. However, the logic was one-way — there was no code path to re-enable the controller when managementState changed back to Managed. Combined with CPO's preservation of existing controller overrides (PR #8072), this caused the controller to remain permanently disabled.

This change makes the logic bidirectional: when managementState is no longer Removed and the controller is currently disabled, it clears the controller override to re-enable it.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/OCPBUGS-85151

Special notes for your reviewer:

Tested manually on a self-managed HyperShift cluster (AWS, release 4.22.0-rc.3). Verified:

  1. Setting managementState: Removed disables the controller (log: "disabling serviceaccount-pull-secrets controller")
  2. Setting managementState: Managed re-enables the controller (log: "re-enabling serviceaccount-pull-secrets controller", controllers reset to null)
  3. CPO preservation logic correctly handles the cleared override

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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

reconcileRegistryAndIngress now reads the OpenShiftControllerManagerConfig only when needed and toggles the "-openshift.io/serviceaccount-pull-secrets" disable token: it adds that entry when ImageRegistry.Spec.ManagementState == Removed (for supported platforms), removes it when managementState is not Removed but the token was present (restoring ["*"] if controllers become empty), and otherwise leaves the config unchanged. A helper isServiceAccountPullSecretsControllerDisabled and tests were added; slices import and a disable-token variable were introduced.

Sequence Diagram(s)

sequenceDiagram
    participant H as HostedClusterConfigOperator
    participant R as ImageRegistry
    participant P as PlatformChecker
    participant CM as OpenShiftControllerManager ConfigMap
    participant K as Kubernetes API

    H->>R: Read registryConfig.Spec.ManagementState
    H->>P: Check platform (skip if IBMCloud/Azure)
    P-->>H: Platform allowed
    H->>CM: Get current controller-manager config
    CM-->>H: Return controllers list
    alt managementState == Removed
        H->>CM: Ensure "-openshift.io/serviceaccount-pull-secrets" present
    else managementState != Removed and controller disabled
        H->>CM: Remove "-openshift.io/serviceaccount-pull-secrets" (restore ["*"] if empty)
    else
        H-->>CM: No change
    end
    H->>K: Update ConfigMap if changed
    K-->>H: Acknowledge update
Loading

Suggested reviewers

  • csrwng
🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately summarizes the primary change: re-enabling the serviceaccount-pull-secrets controller when registry managementState changes from Removed. It is specific and directly reflects the main objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All 9 test cases use stable, static names with no dynamic content—no generated suffixes, timestamps, UUIDs, or variable references. Standard Go tests following best practices.
Test Structure And Quality ✅ Passed Check targets Ginkgo tests. PR uses Go standard testing (codebase pattern). Tests meet adapted criteria: single responsibility, no cluster ops, follow existing patterns.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests were added in this PR. The two new test functions are standard Go unit tests using the testing package and table-driven patterns, not Ginkgo tests. The custom check does not apply.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR adds standard Go unit tests, not Ginkgo e2e tests. The custom check applies only to Ginkgo tests with It/Describe/Context/When constructs. These tests use table-driven patterns with testing.T.
Topology-Aware Scheduling Compatibility ✅ Passed PR modifies controller configuration code, not deployment manifests or pod scheduling. No affinity, topology constraints, node selectors, or topology assumptions introduced.
Ote Binary Stdout Contract ✅ Passed This PR is not related to OTE binaries. It modifies only standard controller logic and unit tests with no Ginkgo/OTE setup or stdout operations. The check does not apply.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR adds only standard Go unit tests (testing package), not Ginkgo e2e tests. The custom check applies only to Ginkgo tests, so it does not apply to this PR.

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

✨ 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 and usage tips.

@openshift-ci openshift-ci Bot added do-not-merge/needs-area 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 May 14, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@vsolanki12: This pull request references Jira Issue OCPBUGS-85151, 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 the image registry managementState is set to Removed, HCCO disables the serviceaccount-pull-secrets controller in openshift-controller-manager by adding a -openshift.io/serviceaccount-pull-secrets override to the OCM ConfigMap. However, the logic was one-way — there was no code path to re-enable the controller when managementState changed back to Managed. Combined with CPO's preservation of existing controller overrides (PR #8072), this caused the controller to remain permanently disabled.

This change makes the logic bidirectional: when managementState is no longer Removed and the controller is currently disabled, it clears the controller override to re-enable it.

Which issue(s) this PR fixes:

Fixes https://issues.redhat.com/browse/OCPBUGS-85151

Special notes for your reviewer:

Tested manually on a self-managed HyperShift cluster (AWS, release 4.22.0-rc.3). Verified:

  1. Setting managementState: Removed disables the controller (log: "disabling serviceaccount-pull-secrets controller")
  2. Setting managementState: Managed re-enables the controller (log: "re-enabling serviceaccount-pull-secrets controller", controllers reset to null)
  3. CPO preservation logic correctly handles the cleared override

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
  • Service account pull secrets controller now properly manages state when image registry operator configuration changes, conditionally re-enabling when necessary.

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 65.62500% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 40.12%. Comparing base (241621f) to head (53df980).
⚠️ Report is 172 commits behind head on main.

Files with missing lines Patch % Lines
...rconfigoperator/controllers/resources/resources.go 65.62% 7 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8522      +/-   ##
==========================================
- Coverage   40.13%   40.12%   -0.01%     
==========================================
  Files         753      753              
  Lines       93045    93012      -33     
==========================================
- Hits        37345    37325      -20     
+ Misses      53003    52989      -14     
- Partials     2697     2698       +1     
Files with missing lines Coverage Δ
...rconfigoperator/controllers/resources/resources.go 56.13% <65.62%> (+0.75%) ⬆️

... and 19 files with indirect coverage changes

Flag Coverage Δ
cmd-support 34.28% <ø> (-0.05%) ⬇️
cpo-hostedcontrolplane 40.57% <ø> (ø)
cpo-other 40.36% <65.62%> (+0.04%) ⬆️
hypershift-operator 50.61% <ø> (ø)
other 31.54% <ø> (ø)

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.

Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go (1)

644-652: 💤 Low value

Consider selectively removing only the -serviceaccount-pull-secrets entry instead of clearing the entire Controllers slice.

When re-enabling the controller (line 649), config.Controllers = nil discards every entry in the slice. The codebase analysis shows that only HCCO and CPO write to this field, and CPO's logic preserves the state it previously set. In the current implementation, this is safe because no other code paths introduce additional disabled-controller entries.

However, for defensive programming, consider removing only the -openshift.io/serviceaccount-pull-secrets element to keep the operation symmetric with the targeted nature of the disable logic. This guards against future changes that might add other entries to the slice.

The CPO code (config.go line 41-44) includes explicit preservation logic with the comment "Preserve any existing Controllers configuration," suggesting the intent to allow modifications; selective removal would align better with that design.

🤖 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/hostedclusterconfigoperator/controllers/resources/resources.go`
around lines 644 - 652, Instead of clearing the entire Controllers slice when
re-enabling, remove only the disabled entry for the serviceaccount-pull-secrets
controller: find and delete the string fmt.Sprintf("-%s",
openshiftcpv1.OpenShiftServiceAccountPullSecretsController) from
config.Controllers (preserving any other entries), and if the resulting slice is
empty set config.Controllers = nil; keep using
isServiceAccountPullSecretsControllerDisabled to detect the disabled state and
update the block that currently sets config.Controllers = nil to perform this
selective removal.
🤖 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.

Nitpick comments:
In
`@control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go`:
- Around line 644-652: Instead of clearing the entire Controllers slice when
re-enabling, remove only the disabled entry for the serviceaccount-pull-secrets
controller: find and delete the string fmt.Sprintf("-%s",
openshiftcpv1.OpenShiftServiceAccountPullSecretsController) from
config.Controllers (preserving any other entries), and if the resulting slice is
empty set config.Controllers = nil; keep using
isServiceAccountPullSecretsControllerDisabled to detect the disabled state and
update the block that currently sets config.Controllers = nil to perform this
selective removal.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 0f9764f4-0751-4d1f-8162-1f28226e6adf

📥 Commits

Reviewing files that changed from the base of the PR and between 7f1af37 and aa804b9.

📒 Files selected for processing (1)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go

@vsolanki12 vsolanki12 force-pushed the OCPBUGS-85151-hcco-re-enable-pull-secrets-controller branch from aa804b9 to e75b62a Compare May 14, 2026 15:29
Copy link
Copy Markdown
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.

🧹 Nitpick comments (2)
control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go (2)

3650-3650: ⚡ Quick win

Add t.Parallel() for consistent parallel test execution.

Other test functions in this file use t.Parallel() (e.g., TestReconcileOLM at line 237, TestReconcileKubeadminPasswordHashSecret at line 485). This pure unit test has no shared state or dependencies that would prevent parallel execution, so adding t.Parallel() would improve test performance and maintain consistency.

⚡ Suggested enhancement
 func TestIsServiceAccountPullSecretsControllerDisabled(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
🤖 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/hostedclusterconfigoperator/controllers/resources/resources_test.go`
at line 3650, The test function
TestIsServiceAccountPullSecretsControllerDisabled lacks t.Parallel(); add a call
to t.Parallel() as the first statement inside that function to allow it to run
concurrently with other unit tests (same pattern used in TestReconcileOLM and
TestReconcileKubeadminPasswordHashSecret), ensuring there is no shared state or
setup that would conflict with parallel execution.

3656-3681: 💤 Low value

Consider adding test case for disabled entry without wildcard.

The current test cases cover the disabled state with both wildcard and disabled entry (line 3668), but don't test the edge case where only the disabled entry exists without the wildcard: ["-openshift.io/serviceaccount-pull-secrets"]. While this scenario is unlikely in real-world OpenShift configurations, adding it would provide more thorough unit test coverage of the helper function's behavior.

📝 Optional test case
 		{
 			name:        "When only the wildcard is present, it should return false",
 			controllers: []string{"*"},
 			expected:    false,
 		},
+		{
+			name:        "When only the disabled entry is present without wildcard, it should return true",
+			controllers: []string{"-openshift.io/serviceaccount-pull-secrets"},
+			expected:    true,
+		},
 	}
🤖 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/hostedclusterconfigoperator/controllers/resources/resources_test.go`
around lines 3656 - 3681, Add a new table-driven test case to the existing tests
in resources_test.go: add an entry with name like "When only the disabled entry
is present, it should return true", controllers set to
[]string{"-openshift.io/serviceaccount-pull-secrets"}, and expected true; place
it alongside the other cases in the same test table so the helper that reads the
controllers slice is exercised for the scenario without a wildcard.
🤖 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.

Nitpick comments:
In
`@control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go`:
- Line 3650: The test function TestIsServiceAccountPullSecretsControllerDisabled
lacks t.Parallel(); add a call to t.Parallel() as the first statement inside
that function to allow it to run concurrently with other unit tests (same
pattern used in TestReconcileOLM and TestReconcileKubeadminPasswordHashSecret),
ensuring there is no shared state or setup that would conflict with parallel
execution.
- Around line 3656-3681: Add a new table-driven test case to the existing tests
in resources_test.go: add an entry with name like "When only the disabled entry
is present, it should return true", controllers set to
[]string{"-openshift.io/serviceaccount-pull-secrets"}, and expected true; place
it alongside the other cases in the same test table so the helper that reads the
controllers slice is exercised for the scenario without a wildcard.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: f07389d3-c64d-4d7f-84ce-3a9fef19fe36

📥 Commits

Reviewing files that changed from the base of the PR and between aa804b9 and e75b62a.

📒 Files selected for processing (2)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go

@vsolanki12 vsolanki12 force-pushed the OCPBUGS-85151-hcco-re-enable-pull-secrets-controller branch from e75b62a to b984ee2 Compare May 14, 2026 15:45
@vsolanki12 vsolanki12 marked this pull request as ready for review May 14, 2026 15:47
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 14, 2026
@openshift-ci openshift-ci Bot requested review from bryan-cox and csrwng May 14, 2026 15:47
Copy link
Copy Markdown
Member

@bryan-cox bryan-cox left a comment

Choose a reason for hiding this comment

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

Pre-commit review (Go + HyperShift profile). Overall: PASS WITH RECOMMENDATIONS — the fix is correct and does not introduce new architectural violations. See inline comments for specific suggestions.

} else if isServiceAccountPullSecretsControllerDisabled(config.Controllers) {
log.Info("imageregistry operator managementstate is no longer removed, re-enabling serviceaccount-pull-secrets controller")
config.Controllers = nil
} else {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[Medium] Consider using []string{"*"} instead of nil here.

The Controllers field is tagged json:"controllers" (no omitempty), so nil serializes to "controllers": null. Whether OCM interprets null as "use default (all controllers)" vs "empty list (run nothing)" is ambiguous.

Using []string{"*"} is explicit and unambiguous — it says "run all on-by-default controllers," which is the documented default and the intent here.

This also makes the CPO interaction in adaptConfig deterministic: with nil, CPO's len(existingControllers) > 0 is false so it enters neither branch and relies on the base config default. With ["*"], CPO explicitly preserves it via the else if branch.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @bryan-cox ,
Done. Changed to selective removal of the disabled entry, falling back to []string{"*"} when the remaining list is empty.

config.Controllers = nil
} else {
return nil
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[Low — readability] This return nil without mutation is correct — CreateOrUpdate deep-compares before/after and skips the API write when nothing changed. But the intent is non-obvious to readers unfamiliar with the upsert framework. A short comment would help:

} else {
	// No change needed; returning nil without mutation causes CreateOrUpdate to skip the update.
	return nil
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done added. // No change needed; returning nil without mutation causes CreateOrUpdate to skip the update.


// isServiceAccountPullSecretsControllerDisabled checks if the ServiceAccountPullSecretsController is disabled.
func isServiceAccountPullSecretsControllerDisabled(controllers []string) bool {
disabled := fmt.Sprintf("-%s", openshiftcpv1.OpenShiftServiceAccountPullSecretsController)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[Low — DRY] This fmt.Sprintf("-%s", openshiftcpv1.OpenShiftServiceAccountPullSecretsController) also appears at line ~647 in the reconcile logic. Consider extracting to a package-level var:

var disabledServiceAccountPullSecretsController = fmt.Sprintf("-%s", openshiftcpv1.OpenShiftServiceAccountPullSecretsController)

Then use it in both the slice literal and this helper. The duplication is low-risk since it's derived from a typed constant, but extracting it makes the relationship between the two usages explicit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Extracted var disabledServiceAccountPullSecretsController and used it in both the reconcile logic and the helper function.

@@ -3646,3 +3646,45 @@ func TestCleanupLegacyResources(t *testing.T) {
})
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[Medium — test gap] The helper function tests are well-structured (table-driven, Gherkin names, gomega) — nice work. However, the core behavioral change — the bidirectional toggling in reconcileRegistryAndIngress — has no test coverage. The re-enable path (RemovedManaged) is the entire point of this PR.

Consider adding a test that:

  1. Sets up a reconciler with a cpClient containing an OCM ConfigMap where the controller is already disabled (Controllers: ["*", "-openshift.io/serviceaccount-pull-secrets"])
  2. Sets registryConfig.Spec.ManagementState = Managed
  3. Calls the reconcile path
  4. Asserts config.Controllers is reset (to ["*"] or nil depending on chosen approach)

Also covers the idempotent no-op case: ManagementState = Managed with controller already enabled → no ConfigMap update.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Added TestReconcileRegistryAndIngress_ServiceAccountPullSecretsController with 4 test cases: disable when Removed, re-enable when Managed, no-op when already enabled, and platform exclusion for IBMCloud.


for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[Low] Nit: subtests are independent and could benefit from t.Parallel() inside each t.Run callback, consistent with Go best practices for table-driven tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Added t.Parallel() inside each t.Run callback.

Copy link
Copy Markdown
Contributor

@csrwng csrwng left a comment

Choose a reason for hiding this comment

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

Thanks for the fix — the bidirectional logic is a good improvement. Left a couple of comments.

config.Controllers = []string{"*", fmt.Sprintf("-%s", openshiftcpv1.OpenShiftServiceAccountPullSecretsController)}
} else if isServiceAccountPullSecretsControllerDisabled(config.Controllers) {
log.Info("imageregistry operator managementstate is no longer removed, re-enabling serviceaccount-pull-secrets controller")
config.Controllers = nil
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.

Setting config.Controllers = nil is fragile — it would wipe out any other controller overrides that might exist in the list, not just the -openshift.io/serviceaccount-pull-secrets entry. Instead, consider removing only the specific disable entry (e.g., -openshift.io/serviceaccount-pull-secrets) from the slice, and then set Controllers = nil only if the remaining list is just ["*"] (or empty).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you @csrwng,
Done. Now removes only the -openshift.io/serviceaccount-pull-secrets entry from the slice, preserving any other controller overrides. Falls back to []string{"*"} if the remaining list is empty.

}
}

func TestIsServiceAccountPullSecretsControllerDisabled(t *testing.T) {
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.

nit: The helper function is well-tested, but it would be good to also have reconciliation-level tests covering the full reconcileRegistryAndIngress flow — e.g., verifying that when managementState transitions from Removed to Managed, the OCM ConfigMap's Controllers field is correctly updated, and conversely that it stays untouched when the state hasn't changed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Added TestReconcileRegistryAndIngress_ServiceAccountPullSecretsController with 4 test cases: disable when Removed, re-enable when Managed, no-op when already enabled, and platform exclusion for IBMCloud.

@vsolanki12 vsolanki12 force-pushed the OCPBUGS-85151-hcco-re-enable-pull-secrets-controller branch from b984ee2 to 1259fec Compare May 19, 2026 03:03
Copy link
Copy Markdown
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: 1

🤖 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/hostedclusterconfigoperator/controllers/resources/resources.go`:
- Around line 647-650: The current branch that handles
registryConfig.Spec.ManagementState == operatorv1.Removed overwrites
config.Controllers with only "*" and
disabledServiceAccountPullSecretsController, dropping any existing overrides;
instead, modify the logic in the block that sets config.Controllers so it
preserves existing entries and only ensures the
disabledServiceAccountPullSecretsController
("-openshift.io/serviceaccount-pull-secrets") is present when absent: check
config.Controllers (using isServiceAccountPullSecretsControllerDisabled helper
or similar) and append disabledServiceAccountPullSecretsController if not
already present, keeping all other entries intact rather than replacing the
entire slice.
🪄 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: 0048244b-e3c4-45c4-8ec9-baaa0464b946

📥 Commits

Reviewing files that changed from the base of the PR and between b984ee2 and 1259fec.

📒 Files selected for processing (2)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go

@vsolanki12 vsolanki12 force-pushed the OCPBUGS-85151-hcco-re-enable-pull-secrets-controller branch from 1259fec to 9caba92 Compare May 19, 2026 03:16
Copy link
Copy Markdown
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.

♻️ Duplicate comments (1)
control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go (1)

647-650: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve existing OCM controller overrides when disabling pull-secrets.

This branch overwrites config.Controllers and drops unrelated existing overrides. Add only disabledServiceAccountPullSecretsController when absent.

Suggested fix
-					if registryConfig.Spec.ManagementState == operatorv1.Removed {
-						log.Info("imageregistry operator managementstate is removed, disabling serviceaccount-pull-secrets controller")
-						config.Controllers = []string{"*", disabledServiceAccountPullSecretsController}
+					if registryConfig.Spec.ManagementState == operatorv1.Removed {
+						if isServiceAccountPullSecretsControllerDisabled(config.Controllers) {
+							// No change needed; returning nil without mutation causes CreateOrUpdate to skip the update.
+							return nil
+						}
+						log.Info("imageregistry operator managementstate is removed, disabling serviceaccount-pull-secrets controller")
+						if len(config.Controllers) == 0 {
+							config.Controllers = []string{"*", disabledServiceAccountPullSecretsController}
+						} else {
+							config.Controllers = append(config.Controllers, disabledServiceAccountPullSecretsController)
+						}
🤖 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/hostedclusterconfigoperator/controllers/resources/resources.go`
around lines 647 - 650, When registryConfig.Spec.ManagementState ==
operatorv1.Removed we must not overwrite config.Controllers (which loses other
OCM overrides); instead check config.Controllers and if
disabledServiceAccountPullSecretsController is not present (use
isServiceAccountPullSecretsControllerDisabled or its inverse) append it to
config.Controllers (or create a new slice preserving existing entries) so only
the pull-secrets controller is disabled while keeping other controller overrides
intact; update the branch that currently sets config.Controllers = []string{"*",
disabledServiceAccountPullSecretsController} to perform this append/merge logic
using the existing symbols config.Controllers and
disabledServiceAccountPullSecretsController.
🤖 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.

Duplicate comments:
In
`@control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go`:
- Around line 647-650: When registryConfig.Spec.ManagementState ==
operatorv1.Removed we must not overwrite config.Controllers (which loses other
OCM overrides); instead check config.Controllers and if
disabledServiceAccountPullSecretsController is not present (use
isServiceAccountPullSecretsControllerDisabled or its inverse) append it to
config.Controllers (or create a new slice preserving existing entries) so only
the pull-secrets controller is disabled while keeping other controller overrides
intact; update the branch that currently sets config.Controllers = []string{"*",
disabledServiceAccountPullSecretsController} to perform this append/merge logic
using the existing symbols config.Controllers and
disabledServiceAccountPullSecretsController.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: af70d034-39ef-4a29-b03e-28c26b5e93e8

📥 Commits

Reviewing files that changed from the base of the PR and between 1259fec and 9caba92.

📒 Files selected for processing (2)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go

@vsolanki12 vsolanki12 force-pushed the OCPBUGS-85151-hcco-re-enable-pull-secrets-controller branch from 9caba92 to ce93fe0 Compare May 19, 2026 03:26
…stry managementState changes from Removed

The HCCO previously only disabled the serviceaccount-pull-secrets
controller in openshift-controller-manager when the image registry
managementState was set to Removed. It had no logic to re-enable
the controller when managementState changed back to Managed. Combined
with CPO's preservation of existing controller overrides, this caused
the controller to remain permanently disabled.

This change makes the logic bidirectional: when managementState is no
longer Removed and the controller is currently disabled, it clears the
controller override to re-enable it.

Signed-off-by: Vimal Solanki <vsolanki@redhat.com>
@vsolanki12 vsolanki12 force-pushed the OCPBUGS-85151-hcco-re-enable-pull-secrets-controller branch from ce93fe0 to 53df980 Compare May 19, 2026 03:51
@vsolanki12
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
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.

🧹 Nitpick comments (2)
control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go (2)

3803-3807: ⚡ Quick win

Make reconcile assertions strict to avoid false positives.

Filtering only one error substring can let unrelated regressions pass. This test should assert no reconcile errors for the scoped scenario.

♻️ Suggested tightening
 errs := r.reconcileRegistryAndIngress(t.Context(), hcp, log)
-for _, e := range errs {
-  g.Expect(e.Error()).ToNot(ContainSubstring("openshift-controller-manager config"), "unexpected OCM config error: %v", e)
-}
+g.Expect(errs).To(BeEmpty(), "unexpected reconcile errors")
🤖 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/hostedclusterconfigoperator/controllers/resources/resources_test.go`
around lines 3803 - 3807, The test currently calls
r.reconcileRegistryAndIngress(...) and only filters errors that contain
"openshift-controller-manager config", which can hide other regressions; replace
the loop and substring check on the returned errs with a strict assertion that
errs is empty (e.g., assert that errs has length 0 or use BeEmpty) after calling
r.reconcileRegistryAndIngress, referencing the same call site and the errs
variable so any unexpected reconcile errors will fail the test.

3713-3753: ⚡ Quick win

Add override-preservation test cases for controller list mutations.

The table currently validates basic enable/disable transitions, but it doesn’t lock in behavior for unrelated existing overrides. Add cases that verify -openshift.io/serviceaccount-pull-secrets is toggled without altering other entries.

♻️ Suggested test additions
 tests := []struct {
   name                   string
   platformType           hyperv1.PlatformType
   managementState        operatorv1.ManagementState
   existingOCMControllers []string
   hasExistingOCMConfig   bool
   expectedControllers    []string
 }{
+  {
+    name:                   "When managementState is Removed, it should preserve existing overrides while adding disable token",
+    platformType:           hyperv1.AWSPlatform,
+    managementState:        operatorv1.Removed,
+    existingOCMControllers: []string{"*", "-some-other-controller"},
+    hasExistingOCMConfig:   true,
+    expectedControllers:    []string{"*", "-some-other-controller", disabledServiceAccountPullSecretsController},
+  },
+  {
+    name:                   "When managementState is Managed, it should remove only the pull-secrets disable token",
+    platformType:           hyperv1.AWSPlatform,
+    managementState:        operatorv1.Managed,
+    existingOCMControllers: []string{"*", "-some-other-controller", disabledServiceAccountPullSecretsController},
+    hasExistingOCMConfig:   true,
+    expectedControllers:    []string{"*", "-some-other-controller"},
+  },

As per coding guidelines, "Unit test any code changes and additions, and include e2e tests when changes impact consumer behavior."

🤖 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/hostedclusterconfigoperator/controllers/resources/resources_test.go`
around lines 3713 - 3753, Add unit test rows to the existing tests table that
assert toggling of disabledServiceAccountPullSecretsController does not modify
unrelated controller entries: add one case where existingOCMControllers includes
another custom override (e.g., "custom-controller") plus
disabledServiceAccountPullSecretsController and managementState Managed
expecting expectedControllers to include "custom-controller" (and not the
disabled entry), and another case where existingOCMControllers includes
"custom-controller" without the disabled entry and managementState Removed
expecting expectedControllers to include both "custom-controller" and
disabledServiceAccountPullSecretsController; update the tests slice entries that
use platformType, managementState, existingOCMControllers, hasExistingOCMConfig
and expectedControllers so the controller-list mutation logic in the code paths
exercised by the test (the logic that reads/modifies OCM controller lists) is
validated for preservation of unrelated overrides.
🤖 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.

Nitpick comments:
In
`@control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go`:
- Around line 3803-3807: The test currently calls
r.reconcileRegistryAndIngress(...) and only filters errors that contain
"openshift-controller-manager config", which can hide other regressions; replace
the loop and substring check on the returned errs with a strict assertion that
errs is empty (e.g., assert that errs has length 0 or use BeEmpty) after calling
r.reconcileRegistryAndIngress, referencing the same call site and the errs
variable so any unexpected reconcile errors will fail the test.
- Around line 3713-3753: Add unit test rows to the existing tests table that
assert toggling of disabledServiceAccountPullSecretsController does not modify
unrelated controller entries: add one case where existingOCMControllers includes
another custom override (e.g., "custom-controller") plus
disabledServiceAccountPullSecretsController and managementState Managed
expecting expectedControllers to include "custom-controller" (and not the
disabled entry), and another case where existingOCMControllers includes
"custom-controller" without the disabled entry and managementState Removed
expecting expectedControllers to include both "custom-controller" and
disabledServiceAccountPullSecretsController; update the tests slice entries that
use platformType, managementState, existingOCMControllers, hasExistingOCMConfig
and expectedControllers so the controller-list mutation logic in the code paths
exercised by the test (the logic that reads/modifies OCM controller lists) is
validated for preservation of unrelated overrides.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: e364d9b7-1b2e-4fb1-9ce8-da89868c831c

📥 Commits

Reviewing files that changed from the base of the PR and between cf2b91f and 53df980.

📒 Files selected for processing (2)
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
  • control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go

@vsolanki12
Copy link
Copy Markdown
Contributor Author

/retest

@bryan-cox
Copy link
Copy Markdown
Member

/approve

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 19, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bryan-cox, vsolanki12

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 May 19, 2026
@vsolanki12
Copy link
Copy Markdown
Contributor Author

/retest

@csrwng
Copy link
Copy Markdown
Contributor

csrwng commented May 20, 2026

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 20, 2026
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-azure-self-managed
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws
/test e2e-v2-gke

@cwbotbot
Copy link
Copy Markdown

cwbotbot commented May 20, 2026

Test Results

e2e-aks

e2e-aws

@vsolanki12
Copy link
Copy Markdown
Contributor Author

/retest

@vsolanki12
Copy link
Copy Markdown
Contributor Author

/verified by me on local env

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label May 22, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@vsolanki12: This PR has been marked as verified by me on local env.

Details

In response to this:

/verified by me on local env

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.

@vsolanki12
Copy link
Copy Markdown
Contributor Author

Before fix:

$ oc get cm openshift-controller-manager-config -n clusters-vsolanki-hcp-test-2 -o jsonpath='{.data.config\.yaml}' | yq '.controllers'
- "*"
- "-openshift.io/serviceaccount-pull-secrets"

After fix:

$ oc get cm openshift-controller-manager-config -n clusters-vsolanki-hcp-test-2 -o jsonpath='{.data.config\.yaml}' | yq '.controllers'
- "*"

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 22, 2026

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

@vsolanki12
Copy link
Copy Markdown
Contributor Author

/retest

@hypershift-jira-solve-ci
Copy link
Copy Markdown

Test Failure Analysis Complete

Job Information

  • Prow Job: Red Hat Konflux / hypershift-operator-main-enterprise-contract / hypershift-operator-main
  • Build ID: hypershift-operator-main-enterprise-contract-vl6d8
  • Second Job: Red Hat Konflux / hypershift-operator-enterprise-contract / hypershift-operator-main
  • Second Build ID: hypershift-operator-enterprise-contract-2t7wc
  • PR: OCPBUGS-85151: Re-enable serviceaccount-pull-secrets controller when registry managementState changes from Removed #8522 (OCPBUGS-85151: Re-enable serviceaccount-pull-secrets controller when registry managementState changes from Removed)
  • Snapshot: hypershift-operator-20260525-033647-000

Test Failure Analysis

Error

Enterprise Contract verify task: 250 success(es), 22 warning(s), 6 failure(s)

Three build pipeline tasks have result=FAILURE in their TEST_OUTPUT:

1. ecosystem-cert-preflight-checks: FAILURE (successes=6, failures=2)
   "Task preflight is a FAILURE: Refer to Tekton task logs for more information"

2. coverity-availability-check: FAILURE (successes=0, failures=1)
   "No authentication token for downloading Coverity image detected.
    Please, create an imagePullSecret named 'auth-token-coverity-image'..."

3. sast-shell-check: FAILURE (successes=0, failures=38)
   "For details, check Tekton task log."

Summary

Both Enterprise Contract check failures are pre-existing infrastructure issues completely unrelated to PR #8522's code changes. The PR only modifies two Go source files in control-plane-operator/, yet the failures occur in the hypershift-operator Konflux component's build pipeline. Three build pipeline test tasks — ecosystem-cert-preflight-checks, coverity-availability-check, and sast-shell-check — persistently fail in every hypershift-operator build (both PR and main branch). On main branch pushes, the Enterprise Contract policy treats these as warnings (conclusion: neutral), but on PR builds, an EC policy change now treats them as failures (conclusion: failure), blocking merge. This is a Konflux/EC policy configuration issue at the tenant level, not a product code bug.

Root Cause

The root cause is a combination of two issues:

1. Pre-existing build pipeline test failures (persistent across ALL builds):

  • coverity-availability-check: Coverity license expired on April 13, 2026. On main branch builds, the message says "Coverity license expired on 2026-Apr-13 08:00:00 UTC". On PR builds, the imagePullSecret auth-token-coverity-image is not available, producing a slightly different error. Both result in FAILURE status.

  • ecosystem-cert-preflight-checks: 2 out of 8 container preflight checks persistently fail. This has been failing consistently in every hypershift-operator build examined (PR and push).

  • sast-shell-check: 38 ShellCheck findings exist in the repository's shell scripts. These are static analysis warnings that have been present across all builds.

2. EC policy change in treatment of test failures:

The Enterprise Contract policies evaluate these task TEST_OUTPUT results differently depending on the policy version:

Build Date EC Policy Result Same Task Failures Present
PR 8563 May 21 256 success, 8 warn, 0 failneutral ✅ Yes
PR 8522 May 25 250 success, 22 warn, 6 failfailure ✅ Yes
Main push May 24 512 success, 20 warn, 0 failneutral ✅ Yes

The same three task failures are treated as warnings in some EC evaluations but failures in others. The 6 EC policy failures correspond to 3 failing tasks × 2 EC policy rules each (likely test.no_failed_tests evaluated per-task and per-result).

The EC integration test scenarios (hypershift-operator-enterprise-contract and hypershift-operator-main-enterprise-contract) are defined as Konflux IntegrationTestScenario CRs in the crt-redhat-acm-tenant namespace, managed outside the git repository. A policy configuration change at the tenant level caused the severity escalation from warning to failure for PR builds.

Recommendations
  1. No action needed on PR OCPBUGS-85151: Re-enable serviceaccount-pull-secrets controller when registry managementState changes from Removed #8522 — The code changes are correct and unrelated to these failures. The control-plane-operator Enterprise Contract check passes successfully.

  2. Fix the expired Coverity license — The Coverity license expired on April 13, 2026. The crt-redhat-acm-tenant Konflux tenant needs the auth-token-coverity-image imagePullSecret updated with a valid license/token.

  3. Address ecosystem-cert-preflight-checks failures — Investigate the 2 persistent preflight check failures in the hypershift-operator container image (Tekton task logs in the Konflux pipeline run have details).

  4. Triage sast-shell-check findings — 38 ShellCheck findings exist in the repository. Either fix the shell script issues or configure the task to treat them as warnings if they are accepted risks.

  5. Investigate EC policy configuration — Contact the Konflux/EC team managing the crt-redhat-acm-tenant namespace to understand why the same task failures are treated as warnings on push builds but failures on PR builds. The IntegrationTestScenario CRs may need their policy configuration aligned.

  6. Workaround for immediate merge — Re-triggering the build may not help since the underlying task failures are persistent. The EC policy or integration test scenario configuration needs to be adjusted at the tenant level.

Evidence
Evidence Detail
PR changes Only control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go and resources_test.go — no build/CI/Containerfile changes
Image build status hypershift-operator-main-on-pull-request: SUCCESS — the image builds correctly
control-plane-operator EC control-plane-operator-enterprise-contract: SUCCESS — the component this PR changes passes EC
Failing task 1 ecosystem-cert-preflight-checks: FAILURE with 2/8 checks failing (persistent in all builds)
Failing task 2 coverity-availability-check: FAILURE — "No authentication token for downloading Coverity image" (PR) / "Coverity license expired on 2026-Apr-13" (main)
Failing task 3 sast-shell-check: FAILURE with 38 findings (persistent in all builds)
Main branch (May 24) Same 3 task failures → EC conclusion: neutral (512 success, 20 warn, 0 fail)
PR 8563 (May 21, merged) Same 3 task failures → EC conclusion: neutral (256 success, 8 warn, 0 fail)
PR 8522 (May 25, blocked) Same 3 task failures → EC conclusion: failure (250 success, 22 warn, 6 fail)
PR 8556 (May 20, blocked) Same 3 task failures → EC conclusion: failure (254 success, 24 warn, 2 fail)
Attestation source SLSA v0.2 provenance from quay.io/redhat-user-workloads/crt-redhat-acm-tenant/hypershift-operator/hypershift-operator-main:on-pr-53df980f
Image digest sha256:9e39e79b1c1d7964bca4823d54013086a1c1afdff3da8e91ad55af17f453c59a
Pipeline runs hypershift-operator-main-enterprise-contract-vl6d8, hypershift-operator-enterprise-contract-2t7wc

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-moderate Referenced Jira bug's severity is moderate 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.

5 participants