Skip to content

✨ Add ServiceAccount validation to ClusterExtension reconciliation - #2488

Merged
openshift-merge-bot[bot] merged 1 commit into
operator-framework:mainfrom
perdasilva:validation-stage
Feb 23, 2026
Merged

✨ Add ServiceAccount validation to ClusterExtension reconciliation#2488
openshift-merge-bot[bot] merged 1 commit into
operator-framework:mainfrom
perdasilva:validation-stage

Conversation

@perdasilva

@perdasilvaperdasilva commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Introduces an extensible validation framework for ClusterExtension reconciliation that validates configuration before attempting bundle installation. The first validator ensures the specified ServiceAccount exists.

Problem

Previously, ServiceAccount validation happened during revision state retrieval, which meant:

  • Configuration errors were discovered late in the reconciliation process
  • Error handling was mixed with business logic
  • No way to validate multiple aspects and report all errors at once

Solution

New Validation Framework

ValidateClusterExtension(validators ...ClusterExtensionValidator)

  • Orchestrates multiple validators in a single reconcile step
  • Executes ALL validators even if some fail (collects all errors)
  • Sets appropriate status conditions on failure:
    • Installed: Unknown
    • Progressing: True (Reason: Retrying)
  • Returns aggregated errors with clear user-facing messages

ServiceAccountValidator(saClient)

  • Validates ServiceAccount existence via direct CoreV1 API Get call
  • Returns friendly error: service account "name" not found in namespace "ns"

Integration Points

Added as a reconcile step (after finalizer handling, before revision state retrieval) in both:

  • Boxcutter runtime configuration
  • Helm runtime configuration

RBAC Changes

  • Added get permission for serviceaccounts resources to the operator-controller manager ClusterRole
  • Regenerated all deployment manifests (standard, experimental, e2e variants)

Cleanup

  • Removed ServiceAccount-specific error handling from RetrieveRevisionStates since validation now happens earlier in the pipeline
  • Removed authentication.ServiceAccountNotFoundError dependency from reconcile steps and tests

Testing

Unit Tests (clusterextension_controller_test.go)

TestValidateClusterExtension - 7 table-driven scenarios:

  • All validators pass
  • Single validator fails
  • Multiple validators collect all failures
  • Multiple validators all pass
  • Mixed pass/fail validators
  • ServiceAccount not found
  • ServiceAccount found

E2E Tests (test/e2e/features/install.feature)

  • New scenario: "Report validation error when ServiceAccount does not exist"

Files Changed

  • cmd/operator-controller/main.go - Added validation step with ServiceAccountValidator to both boxcutter and helm reconciler configurations
  • internal/operator-controller/controllers/clusterextension_reconcile_steps.go - New validation framework (ClusterExtensionValidator type, ValidateClusterExtension, ServiceAccountValidator), removed SA error handling from RetrieveRevisionStates
  • internal/operator-controller/controllers/clusterextension_controller_test.go - Replaced TestClusterExtensionServiceAccountNotFound with comprehensive TestValidateClusterExtension table-driven tests (7 scenarios)
  • internal/operator-controller/controllers/suite_test.go - Added Validators field to test deps and included ValidateClusterExtension in default reconcile steps
  • helm/olmv1/templates/rbac/clusterrole-operator-controller-manager-role.yml - Added get permission for serviceaccounts
  • manifests/*.yaml - Regenerated manifests reflecting RBAC changes
  • test/e2e/features/install.feature - E2E validation scenario for missing ServiceAccount

🤖 Generated with Claude Code

CopilotAI review requested due to automatic review settings February 5, 2026 14:19
@netlify

netlifyBot commented Feb 5, 2026

Copy link
Copy Markdown

Deploy Preview for olmv1 ready!

NameLink
🔨 Latest commit70e5028
🔍 Latest deploy loghttps://app.netlify.com/projects/olmv1/deploys/699c8038c66ee80008612e18
😎 Deploy Previewhttps://deploy-preview-2488--olmv1.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@perdasilvaperdasilva changed the title feat: Add ServiceAccount validation to ClusterExtension reconciliation✨ Add ServiceAccount validation to ClusterExtension reconciliationFeb 5, 2026
@perdasilva
perdasilva marked this pull request as draft February 5, 2026 14:20
@openshift-ciopenshift-ciBot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 5, 2026

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

Pull request overview

This PR adds ServiceAccount validation to the ClusterExtension reconciliation pipeline. The validation checks whether the ServiceAccount specified in .spec.serviceAccount exists on the cluster before proceeding with bundle installation, moving this check from RetrieveRevisionStates to an earlier validation stage.

Changes:

  • Introduces a new validation framework with ValidateClusterExtension orchestrator and ServiceAccountValidator implementation
  • Moves ServiceAccount existence checks earlier in the reconciliation pipeline (after finalizer handling)
  • Updates both Boxcutter and Helm reconciler configurations to include the validation step

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
FileDescription
internal/operator-controller/controllers/clusterextension_reconcile_steps.goAdds validation framework (ValidateClusterExtension, ClusterExtensionValidator, ServiceAccountValidator) and removes ServiceAccount error handling from RetrieveRevisionStates
internal/operator-controller/controllers/clusterextension_reconcile_steps_test.goAdds comprehensive unit tests for validator functions (10 test cases total)
internal/operator-controller/controllers/clusterextension_controller_test.goUpdates existing ServiceAccount test to use new validation approach with mock TokenGetter
cmd/operator-controller/main.goIntegrates validation step into both Boxcutter and Helm reconciler configurations
test/e2e/features/install.featureAdds E2E Gherkin scenario for ServiceAccount validation error case

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecovBot commented Feb 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.42857% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 73.24%. Comparing base (1ef820f) to head (70e5028).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
...er/controllers/clusterextension_reconcile_steps.go95.45%1 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #2488 +/- ##
==========================================
- Coverage 73.27% 73.24% -0.04% 
==========================================
Files 103 103 Lines 8516 8539 +23 ==========================================
+ Hits 6240 6254 +14 - Misses 1801 1808 +7 - Partials 475 477 +2 
FlagCoverage Δ
e2e45.43% <85.71%> (-0.39%)⬇️
experimental-e2e53.78% <85.71%> (+0.31%)⬆️
unit57.98% <75.00%> (+0.03%)⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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

CopilotAI review requested due to automatic review settings February 5, 2026 16:54

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

revisionStates, err := r.GetRevisionStates(ctx, ext)
if err != nil {
setInstallStatus(ext, nil)
var saerr *authentication.ServiceAccountNotFoundError

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

this got split between the service account validator and the cluster extension validator

CopilotAI review requested due to automatic review settings February 9, 2026 09:31
@perdasilva
perdasilva marked this pull request as ready for review February 9, 2026 09:33
@openshift-ciopenshift-ciBot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 9, 2026
@openshift-ci
openshift-ciBot requested a review from pedjakFebruary 9, 2026 09:33

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

CopilotAI review requested due to automatic review settings February 9, 2026 14:09

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcmd/operator-controller/main.go
CopilotAI review requested due to automatic review settings February 19, 2026 15:27

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

CopilotAI review requested due to automatic review settings February 23, 2026 09:36

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

I am OK with.
Until we go with easy mode makes sense to me, to validate it in the code.

/approved

return func(ctx context.Context, state *reconcileState, ext *ocv1.ClusterExtension) (*ctrl.Result, error) {
l := log.FromContext(ctx)

l.Info("validating cluster extension")

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.

I think we should lower this do debug level.

}

// Set status conditions with the validation errors
err := fmt.Errorf("installation cannot proceed due to the following validation error(s): %w", errors.Join(validationErrors...))

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.

can we make a bit more focused or generic message, because we cannot proceed with the installation or an update, right?

if apierrors.IsNotFound(err) {
return fmt.Errorf("service account %q not found in namespace %q", ext.Spec.ServiceAccount.Name, ext.Spec.Namespace)
}
return fmt.Errorf("error validating service account: %w", err)

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.

given that we just try to access the service accound at the line 105, the error message error validating service account is confusing because we did not perform any validation, just tried to access it.

…erExtension
Introduces an extensible validation framework that runs early in the
ClusterExtension reconciliation pipeline (after finalizer handling,
before revision state retrieval) to catch configuration errors before
expensive operations begin.
Key changes:
- New ClusterExtensionValidator type and ValidateClusterExtension
reconcile step that executes all validators and collects all errors
(no fail-fast behavior)
- ServiceAccountValidator checks SA existence via direct CoreV1 API
Get call, providing clear "not found" feedback
- Sets Installed=Unknown and Progressing=Retrying conditions on
validation failure
- Removed SA-specific error handling from RetrieveRevisionStates,
since validation now catches these errors earlier
- Added RBAC permission (get serviceaccounts) to the operator-controller
manager ClusterRole and regenerated manifests
Testing:
- Table-driven unit tests covering 7 scenarios (all pass, single
fail, multiple fail, mixed, SA not found, SA found)
- E2E scenario for missing ServiceAccount validation error
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Per Goncalves da Silva <pegoncal@redhat.com>
Signed-off-by: Per G. da Silva <pegoncal@redhat.com>
CopilotAI review requested due to automatic review settings February 23, 2026 16:28

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

/approved

@pedjak WDYT? Could you LGTM this one?

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

/lgtm

@openshift-ciopenshift-ciBot added the lgtm Indicates that a PR is ready to be merged. label Feb 23, 2026

@rashmigottipatirashmigottipati left a comment

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.

/lgtm

@tmshort

Copy link
Copy Markdown
Contributor

/approve

@openshift-ci

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: rashmigottipati, tmshort

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-ciopenshift-ciBot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 23, 2026
@openshift-merge-bot
openshift-merge-botBot merged commit ddf921f into operator-framework:mainFeb 23, 2026
32 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approvedIndicates a PR has been approved by an approver from all required OWNERS files.lgtmIndicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@perdasilva@tmshort@pedjak@rashmigottipati@camilamacedo86