Skip to content

MG-265: Mandate ServiceAccount for MustGather CR for all users#347

Open
neha037 wants to merge 7 commits into
openshift:masterfrom
neha037:fix-MG-265
Open

MG-265: Mandate ServiceAccount for MustGather CR for all users#347
neha037 wants to merge 7 commits into
openshift:masterfrom
neha037:fix-MG-265

Conversation

@neha037
Copy link
Copy Markdown
Contributor

@neha037 neha037 commented May 4, 2026

Summary

  • Make serviceAccountName a required field on the MustGather CR with minLength: 1, removing the default value of "default".
  • Remove controller fallback logic that silently defaulted to the "default" ServiceAccount when the field was empty.
  • Add two new CEL validation rules for the audit field (rejected with custom image, rejected with custom command without imageStreamRef). The original command/args CEL rule is intentionally retained as it serves a different purpose.

Why

Previously, the operator silently fell back to the default ServiceAccount, which often lacks the permissions needed for must-gather jobs, causing jobs to hang or fail in confusing ways. Making the field required forces users to be intentional about which SA they use, eliminating ambiguity for both admin and non-admin users.

Changes

Area Change
api/v1alpha1/mustgather_types.go Replaced +kubebuilder:validation:Optional and +kubebuilder:default:="default" with +kubebuilder:validation:Required and +kubebuilder:validation:MinLength=1. Removed omitempty from JSON tag. Added two new CEL rules for audit field validation (retained existing command/args rule).
controllers/mustgather/mustgather_controller.go Removed the if saName == "" fallback block. Controller now uses instance.Spec.ServiceAccountName directly since it's guaranteed non-empty at admission.
controllers/mustgather/mustgather_controller_test.go Removed two tests for empty SA defaulting. Updated all test objects to explicitly set ServiceAccountName.
test/e2e/must_gather_operator_test.go Added negative E2E test verifying that a CR without serviceAccountName is rejected at admission.
deploy/crds/ and bundle/manifests/ Regenerated CRD manifests reflecting the new required field, minLength, and CEL rules.

Test plan

  • All existing unit tests pass with updated SA field
  • go vet ./... passes
  • go build ./... compiles cleanly
  • E2E test added: CR without serviceAccountName is rejected at admission
  • E2E tests verify existing behavior is unaffected when a valid SA is provided

🤖 Generated with Claude Code via /jira:solve [MG-265](https://redhat.atlassian.net/browse/MG-265)

Summary by CodeRabbit

  • Breaking Changes
    • spec.serviceAccountName is now required (non-empty) and no longer defaults to "default".
    • New validations: gatherSpec.command/args may only be set with a custom image; gatherSpec.audit: true is forbidden when using a custom image or a custom command without a custom image.
  • Bug Fixes
    • Pre-flight service-account validation now uses the provided serviceAccountName (no implicit default).
  • Tests
    • Added e2e tests ensuring creation without a valid spec.serviceAccountName is rejected; unit tests updated to include serviceAccountName.

neha037 and others added 2 commits May 4, 2026 20:30
Remove the default value and optional marker from serviceAccountName,
replacing them with Required and MinLength=1 validators. This forces
users to explicitly specify a ServiceAccount, eliminating the silent
fallback to "default" which often lacks must-gather permissions.

Also adds two CEL validation rules:
- audit cannot be used with a custom image (imageStreamRef)
- audit cannot be used when gatherSpec.command is set without imageStreamRef

The controller fallback logic that defaulted to "default" SA is removed
since the field is now guaranteed to be populated at admission.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tName

Regenerated after API changes to reflect the new required field,
minLength validator, and CEL validation rules for audit constraints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 4, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented May 4, 2026

@neha037: This pull request references MG-265 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Make serviceAccountName a required field on the MustGather CR with minLength: 1, removing the default value of "default".
  • Remove controller fallback logic that silently defaulted to the "default" ServiceAccount when the field was empty.
  • Add CEL validation rules: audit is rejected when imageStreamRef is set (custom image) and when gatherSpec.command is set without imageStreamRef.

Why

Previously, the operator silently fell back to the default ServiceAccount, which often lacks the permissions needed for must-gather jobs, causing jobs to hang or fail in confusing ways. Making the field required forces users to be intentional about which SA they use, eliminating ambiguity for both admin and non-admin users.

Changes

Area Change
api/v1alpha1/mustgather_types.go Replaced +kubebuilder:validation:Optional and +kubebuilder:default:="default" with +kubebuilder:validation:Required and +kubebuilder:validation:MinLength=1. Removed omitempty from JSON tag. Added two CEL rules for audit field validation.
controllers/mustgather/mustgather_controller.go Removed the if saName == "" fallback block. Controller now uses instance.Spec.ServiceAccountName directly since it's guaranteed non-empty at admission.
controllers/mustgather/mustgather_controller_test.go Removed two tests for empty SA defaulting. Updated all test objects to explicitly set ServiceAccountName.
deploy/crds/ and bundle/manifests/ Regenerated CRD manifests reflecting the new required field, minLength, and CEL rules.

Test plan

  • All existing unit tests pass with updated SA field
  • go vet ./... passes
  • go build ./... compiles cleanly
  • E2E tests verify existing behavior is unaffected when a valid SA is provided
  • E2E test verifies that a CR without serviceAccountName is rejected at admission

🤖 Generated with Claude Code via /jira:solve [MG-265](https://redhat.atlassian.net/browse/MG-265)

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

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

openshift-ci Bot commented May 4, 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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 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

Made spec.serviceAccountName required and non-empty; added CRD cross-field validations that (1) forbid gatherSpec.command/args unless imageStreamRef is set and (2) forbid gatherSpec.audit: true when imageStreamRef is set or when gatherSpec.command is non-empty; controller no longer defaults an empty ServiceAccountName; updated unit and e2e tests and generated CRDs.

Changes

MustGather: API, CRD, Controller, Tests

Layer / File(s) Summary
Type Definition & Validation
api/v1alpha1/mustgather_types.go
MustGatherSpec.ServiceAccountName made required (json:"serviceAccountName", +kubebuilder:validation:Required, MinLength=1, removed omitempty). XValidation rules updated: require imageStreamRef when gatherSpec.command/gatherSpec.args are set; disallow gatherSpec.audit: true when imageStreamRef is set or when gatherSpec.command is non-empty.
CRD Schema
bundle/manifests/...operator.openshift.io_mustgathers.yaml, deploy/crds/...operator.openshift.io_mustgathers.yaml
serviceAccountName added to spec.required, minLength: 1 and description updated. spec.x-kubernetes-validations rewritten to enforce command/args → imageStreamRef gating and the combined audit constraint. CRD controller-gen metadata updated.
Controller Logic
controllers/mustgather/mustgather_controller.go
ServiceAccount pre-flight lookup now always queries instance.Spec.ServiceAccountName (no implicit defaulting to "default"); error logging/handling references the provided name.
Test Fixtures & Cases
controllers/mustgather/mustgather_controller_test.go, test/e2e/must_gather_operator_test.go
Unit test fixtures updated to set Spec.ServiceAccountName: "default"; removed unit tests that relied on empty-name defaulting. Added e2e tests asserting admission rejects missing or empty spec.serviceAccountName.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Sequence Diagram

sequenceDiagram
  participant User
  participant API_Server
  participant Admission as "Admission (CRD Validation)"
  participant Controller
  participant K8s_API as "Kubernetes API"

  User->>API_Server: Create MustGather CR
  API_Server->>Admission: Validate CRD schema and XValidation rules
  Admission-->>API_Server: Accept or Reject (422 Invalid)
  API_Server-->>User: Return result
  alt Accepted
    Controller->>K8s_API: Get ServiceAccount(instance.Spec.ServiceAccountName)
    K8s_API-->>Controller: ServiceAccount found / not found
    Controller->>Controller: Reconcile using provided ServiceAccountName (no defaulting)
  end
Loading
🚥 Pre-merge checks | ✅ 9 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Microshift Test Compatibility ⚠️ Warning Two new e2e tests use MustGather CRD from operator.openshift.io API group without protection mechanisms, causing failures in MicroShift CI jobs. Add [apigroup:operator.openshift.io] tags to both test names to allow MicroShift CI to automatically skip them.
Single Node Openshift (Sno) Test Compatibility ❓ Inconclusive Ginkgo tests reviewed for multi-node assumptions and skip logic implementation. Provide the actual verification output or test code to assess skip logic and multi-node handling.
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: mandating ServiceAccount as a required field for MustGather CR.
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 Ginkgo test names are static, descriptive strings with no dynamic information embedded in titles.
Test Structure And Quality ✅ Passed The Ginkgo tests demonstrate good quality with proper single responsibility, setup/cleanup handling, meaningful assertions, and alignment with codebase patterns.
Topology-Aware Scheduling Compatibility ✅ Passed PR MG-265 makes ServiceAccountName field required on MustGather CR without introducing topology-breaking scheduling constraints.
Ote Binary Stdout Contract ✅ Passed All process-level entrypoints show no direct fmt.Print* or log/klog calls writing to stdout. All logging uses GinkgoWriter or Ginkgo's By/Expect, preventing non-JSON stdout corruption.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The two new Ginkgo e2e tests are admission validation tests operating through local Kubernetes client API calls with no external connectivity requirements, compatible with IPv6-only disconnected CI environments.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 4, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 4, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: neha037
Once this PR has been reviewed and has the lgtm label, please assign typeid 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

Copy link
Copy Markdown

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@api/v1alpha1/mustgather_types.go`:
- Around line 29-30: The comments for the MustGather API are out of sync with
the CEL XValidation rules: update the doc comments on the audit field and
related gatherSpec to state that audit cannot be used with a custom image
(ImageStreamRef) and also cannot be enabled when gatherSpec.command is set
unless ImageStreamRef is present; specifically edit the comment text that
mentions audit applying regardless of ImageStreamRef and that custom images can
respect audit so it matches the XValidation rules referencing audit,
imageStreamRef, and gatherSpec.command.
- Around line 34-36: The ServiceAccountName field's validation is too lax;
update the struct tag for ServiceAccountName to include the same DNS-1123
validation pattern used by the resource Name field to prevent invalid Kubernetes
names (e.g., enforce lowercase alphanumerics, hyphens, start/end with
alphanumeric). Modify the kubebuilder markers on ServiceAccountName (the
ServiceAccountName string `json:"serviceAccountName"`) to add the DNS-1123 regex
pattern (matching the pattern applied to Name) and any length constraints so
admission rejects invalid names instead of failing later in reconciliation.

In `@controllers/mustgather/mustgather_controller.go`:
- Around line 182-193: Before calling r.GetClient().Get for the service account,
validate that instance.Spec.ServiceAccountName is not empty and, if it is empty,
call r.setValidationFailureStatus(ctx, reqLogger, instance,
ValidationServiceAccount, <an appropriate error>) and return (matching the SFTP
secret pattern); only perform the Get when Name != "" and keep the existing
NotFound and transient-error handling for the Get call (references:
instance.Spec.ServiceAccountName, r.GetClient().Get,
r.setValidationFailureStatus, ValidationServiceAccount, reconcile.Result).
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 74d13004-dbbb-4ccc-a202-a0865f354109

📥 Commits

Reviewing files that changed from the base of the PR and between 59b15a1 and 623b19d.

📒 Files selected for processing (5)
  • api/v1alpha1/mustgather_types.go
  • bundle/manifests/tech-preview/operator.openshift.io_mustgathers.yaml
  • controllers/mustgather/mustgather_controller.go
  • controllers/mustgather/mustgather_controller_test.go
  • deploy/crds/operator.openshift.io_mustgathers.yaml

Comment thread api/v1alpha1/mustgather_types.go Outdated
Comment on lines +34 to +36
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
ServiceAccountName string `json:"serviceAccountName"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify current ServiceAccountName schema constraints
rg -n "ServiceAccountName|serviceAccountName|MinLength|MaxLength|dns1123Subdomain|Pattern" api/v1alpha1/mustgather_types.go -C2

# Verify reconcile path uses the value directly (no pre-validation)
rg -n "Name:\\s+instance.Spec.ServiceAccountName|service account not found|transient error" controllers/mustgather/mustgather_controller.go -C3

Repository: openshift/must-gather-operator

Length of output: 2073


🏁 Script executed:

# Check for other ServiceAccountName field definitions to see if any have stricter validation
fd -e go -type f | xargs rg -l "ServiceAccountName" | head -20

# Look for all ServiceAccountName field definitions and their validation
rg -A3 "ServiceAccountName\s*string.*json" --type go

# Check if there are any tests that validate ServiceAccountName input
rg -n "ServiceAccountName.*test|test.*ServiceAccountName" --type go -i

# Verify the CEL validation rule format matches Kubernetes conventions
rg "dns1123Subdomain|dns1123Label" --type go

Repository: openshift/must-gather-operator

Length of output: 9708


🏁 Script executed:

# Check tests to see if ServiceAccountName validation is tested
rg -n "ServiceAccountName" test/e2e/must_gather_operator_test.go controllers/mustgather/mustgather_controller_test.go -B2 -A2

# Check the exact CEL syntax used at line 207 to ensure proposed syntax is correct
sed -n '204,210p' api/v1alpha1/mustgather_types.go

# Verify if there are any integration tests that would catch invalid ServiceAccount names
rg -n "setValidationFailureStatus|ValidationServiceAccount" controllers/mustgather/mustgather_controller.go -B3 -A3

Repository: openshift/must-gather-operator

Length of output: 27634


Strengthen serviceAccountName validation to enforce DNS-1123 format.

Lines 34–36 enforce only non-empty input. Invalid Kubernetes names (e.g., uppercase, spaces, special characters) are accepted at admission and fail later during reconciliation. Add DNS-1123 validation matching the pattern already used for the Name field in this file (lines 206–207).

Proposed validation
 	// +kubebuilder:validation:Required
 	// +kubebuilder:validation:MinLength=1
+	// +kubebuilder:validation:MaxLength=253
+	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="serviceAccountName must be a lowercase RFC 1123 subdomain"
 	ServiceAccountName string `json:"serviceAccountName"`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/v1alpha1/mustgather_types.go` around lines 34 - 36, The
ServiceAccountName field's validation is too lax; update the struct tag for
ServiceAccountName to include the same DNS-1123 validation pattern used by the
resource Name field to prevent invalid Kubernetes names (e.g., enforce lowercase
alphanumerics, hyphens, start/end with alphanumeric). Modify the kubebuilder
markers on ServiceAccountName (the ServiceAccountName string
`json:"serviceAccountName"`) to add the DNS-1123 regex pattern (matching the
pattern applied to Name) and any length constraints so admission rejects invalid
names instead of failing later in reconciliation.

Comment on lines 182 to 193
err = r.GetClient().Get(ctx, types.NamespacedName{
Namespace: instance.Namespace,
Name: saName,
Name: instance.Spec.ServiceAccountName,
}, serviceAccount)
if err != nil {
if errors.IsNotFound(err) {
log.Error(err, "service account not found", "name", saName, "namespace", instance.Namespace)
log.Error(err, "service account not found", "name", instance.Spec.ServiceAccountName, "namespace", instance.Namespace)
return r.setValidationFailureStatus(ctx, reqLogger, instance, ValidationServiceAccount, err)
}

log.Error(err, "failed to get service account (transient error, will retry)", "name", saName, "namespace", instance.Namespace)
log.Error(err, "failed to get service account (transient error, will retry)", "name", instance.Spec.ServiceAccountName, "namespace", instance.Namespace)
return reconcile.Result{Requeue: true}, err
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify current SA lookup path and error branching
rg -n "Name:\\s+instance.Spec.ServiceAccountName|service account not found|transient error, will retry|setValidationFailureStatus\\(" controllers/mustgather/mustgather_controller.go -C3

# Verify test coverage around SA failure scenarios
rg -n "service_account|ServiceAccountName|requeue|validation failed" controllers/mustgather/mustgather_controller_test.go -C2

Repository: openshift/must-gather-operator

Length of output: 15401


🏁 Script executed:

# Check if there are any existing validations for empty/invalid object names in the codebase
rg -n "TrimSpace|len.*==.*0|empty" controllers/mustgather/mustgather_controller.go -B2 -A2

# Check what validation pattern is used for other fields (like the SFTP secret name)
rg -n "secretName|Secret.*not.*found|validation.*fail" controllers/mustgather/mustgather_controller.go -B2 -A2

Repository: openshift/must-gather-operator

Length of output: 3848


Add validation for empty ServiceAccountName before lookup to prevent endless requeue.

The ServiceAccount lookup at line 182 uses instance.Spec.ServiceAccountName directly without prior validation. If the field is empty or invalid, the Kubernetes client returns a non-NotFound error, which is incorrectly handled as a transient failure (line 193: requeue) rather than a validation failure. This differs from the pattern used for SFTP secret lookup above (line 197), which validates Name != "" before attempting the Get.

Add an explicit empty check before the lookup to match the existing validation pattern in this file:

Suggested fix
+	saName := instance.Spec.ServiceAccountName
+	if strings.TrimSpace(saName) == "" {
+		validationErr := fmt.Errorf("spec.serviceAccountName must be non-empty")
+		return r.setValidationFailureStatus(ctx, reqLogger, instance, ValidationServiceAccount, validationErr)
+	}
+
 	serviceAccount := &corev1.ServiceAccount{}
 	err = r.GetClient().Get(ctx, types.NamespacedName{
 		Namespace: instance.Namespace,
-		Name:      instance.Spec.ServiceAccountName,
+		Name:      saName,
 	}, serviceAccount)
 	if err != nil {
 		if errors.IsNotFound(err) {
-			log.Error(err, "service account not found", "name", instance.Spec.ServiceAccountName, "namespace", instance.Namespace)
+			log.Error(err, "service account not found", "name", saName, "namespace", instance.Namespace)
 			return r.setValidationFailureStatus(ctx, reqLogger, instance, ValidationServiceAccount, err)
 		}
-		log.Error(err, "failed to get service account (transient error, will retry)", "name", instance.Spec.ServiceAccountName, "namespace", instance.Namespace)
+		log.Error(err, "failed to get service account (transient error, will retry)", "name", saName, "namespace", instance.Namespace)
 		return reconcile.Result{Requeue: true}, err
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controllers/mustgather/mustgather_controller.go` around lines 182 - 193,
Before calling r.GetClient().Get for the service account, validate that
instance.Spec.ServiceAccountName is not empty and, if it is empty, call
r.setValidationFailureStatus(ctx, reqLogger, instance, ValidationServiceAccount,
<an appropriate error>) and return (matching the SFTP secret pattern); only
perform the Get when Name != "" and keep the existing NotFound and
transient-error handling for the Get call (references:
instance.Spec.ServiceAccountName, r.GetClient().Get,
r.setValidationFailureStatus, ValidationServiceAccount, reconcile.Result).

Verify that the API server rejects MustGather CRs submitted without a
serviceAccountName field, confirming the CRD admission validation works
as expected after making the field required.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@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)
test/e2e/must_gather_operator_test.go (1)

864-866: ⚡ Quick win

Tighten validation assertion to the exact missing field

At Line 864, checking only IsInvalid can pass on unrelated schema failures. Assert the error cause includes spec.serviceAccountName so this test only passes for the intended admission rejection.

Suggested diff
 			err := nonAdminClient.Create(testCtx, mg)
 			Expect(err).To(HaveOccurred(), "CR without serviceAccountName should be rejected at admission")
 			Expect(apierrors.IsInvalid(err)).To(BeTrue(),
 				"Error should be a validation error for missing required field")
+			statusErr, ok := err.(*apierrors.StatusError)
+			Expect(ok).To(BeTrue(), "Expected StatusError for schema validation failure")
+			Expect(statusErr.ErrStatus.Details).NotTo(BeNil())
+			Expect(statusErr.ErrStatus.Details.Causes).To(ContainElement(
+				HaveField("Field", "spec.serviceAccountName"),
+			))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/must_gather_operator_test.go` around lines 864 - 866, The test
currently only checks apierrors.IsInvalid(err); tighten it by casting err to
*apierrors.StatusError (e.g., statusErr := err.(*apierrors.StatusError)) and
assert that statusErr.ErrStatus.Details.Causes contains a cause whose Field
equals "spec.serviceAccountName" so the failure is specifically for the missing
serviceAccountName field (use the existing err variable and check
ErrStatus.Details.Causes for the field match).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/e2e/must_gather_operator_test.go`:
- Around line 864-866: The test currently only checks apierrors.IsInvalid(err);
tighten it by casting err to *apierrors.StatusError (e.g., statusErr :=
err.(*apierrors.StatusError)) and assert that statusErr.ErrStatus.Details.Causes
contains a cause whose Field equals "spec.serviceAccountName" so the failure is
specifically for the missing serviceAccountName field (use the existing err
variable and check ErrStatus.Details.Causes for the field match).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c911f884-a54e-41cb-b43c-0b798c3822f9

📥 Commits

Reviewing files that changed from the base of the PR and between 623b19d and 71fb869.

📒 Files selected for processing (1)
  • test/e2e/must_gather_operator_test.go

@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 4, 2026
Copy link
Copy Markdown

@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)
test/e2e/must_gather_operator_test.go (1)

850-869: ⚡ Quick win

Add a case for serviceAccountName: "" too.

This validates the Required path, but the API change also adds MinLength=1. A second negative case for an explicit empty string would cover the non-empty constraint you just introduced.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/must_gather_operator_test.go` around lines 850 - 869, Add a second
negative test in test/e2e/must_gather_operator_test.go that mirrors the existing
"should reject MustGather CR without serviceAccountName" scenario but sets
Spec.ServiceAccountName = "" explicitly to exercise the MinLength=1 validation;
create the MustGather object (same pattern using mustgatherv1alpha1.MustGather
and nonAdminClient.Create(testCtx, mg)), assert that err is returned and
apierrors.IsInvalid(err) is true, and print the rejection like the existing test
(ginkgo.GinkgoWriter.Printf), then nil out mg. This can be a separate ginkgo.It
case or appended as an additional check in the same test.
api/v1alpha1/mustgather_types.go (1)

29-30: ⚡ Quick win

Remove the duplicate audit CEL rules.

These two predicates overlap with the existing validations on Lines 31-32, so one invalid CR can fail twice for the same invariant. Keep a single rule and a single message per condition to avoid noisy admission errors.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/v1alpha1/mustgather_types.go` around lines 29 - 30, The two CEL
XValidation rules repeating the same audit predicates should be consolidated so
a single rule and message exist for each invariant; remove the duplicate rule
that checks combinations of imageStreamRef, gatherSpec.audit (audit) and
gatherSpec.command so each condition appears only once. Locate the duplicated
annotations referencing has(self.imageStreamRef), has(self.gatherSpec),
self.gatherSpec.audit, and has(self.gatherSpec.command) and delete the redundant
line while keeping one canonical XValidation rule and its message for the audit
vs. custom image and audit vs. command constraints.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@api/v1alpha1/mustgather_types.go`:
- Around line 29-30: The two CEL XValidation rules repeating the same audit
predicates should be consolidated so a single rule and message exist for each
invariant; remove the duplicate rule that checks combinations of imageStreamRef,
gatherSpec.audit (audit) and gatherSpec.command so each condition appears only
once. Locate the duplicated annotations referencing has(self.imageStreamRef),
has(self.gatherSpec), self.gatherSpec.audit, and has(self.gatherSpec.command)
and delete the redundant line while keeping one canonical XValidation rule and
its message for the audit vs. custom image and audit vs. command constraints.

In `@test/e2e/must_gather_operator_test.go`:
- Around line 850-869: Add a second negative test in
test/e2e/must_gather_operator_test.go that mirrors the existing "should reject
MustGather CR without serviceAccountName" scenario but sets
Spec.ServiceAccountName = "" explicitly to exercise the MinLength=1 validation;
create the MustGather object (same pattern using mustgatherv1alpha1.MustGather
and nonAdminClient.Create(testCtx, mg)), assert that err is returned and
apierrors.IsInvalid(err) is true, and print the rejection like the existing test
(ginkgo.GinkgoWriter.Printf), then nil out mg. This can be a separate ginkgo.It
case or appended as an additional check in the same test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cb55399b-d1c3-493d-8db0-3fd5afc6b23d

📥 Commits

Reviewing files that changed from the base of the PR and between 71fb869 and 2e0c4b4.

📒 Files selected for processing (4)
  • api/v1alpha1/mustgather_types.go
  • bundle/manifests/tech-preview/operator.openshift.io_mustgathers.yaml
  • deploy/crds/operator.openshift.io_mustgathers.yaml
  • test/e2e/must_gather_operator_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • deploy/crds/operator.openshift.io_mustgathers.yaml
  • bundle/manifests/tech-preview/operator.openshift.io_mustgathers.yaml

@neha037
Copy link
Copy Markdown
Contributor Author

neha037 commented May 4, 2026

/retest all

@neha037
Copy link
Copy Markdown
Contributor Author

neha037 commented May 4, 2026

/test all

Copy link
Copy Markdown

@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 `@test/e2e/must_gather_operator_test.go`:
- Around line 850-869: The test currently constructs a typed MustGather
(mustgatherv1alpha1.MustGather with Spec: mustgatherv1alpha1.MustGatherSpec{})
which serializes ServiceAccountName as an empty string, so it doesn't exercise a
truly missing field; replace the "should reject MustGather CR without
serviceAccountName" case to create and submit an unstructured.Unstructured
payload instead (set GVK to the MustGather API group/version/kind, set
metadata.name/namespace to mustGatherName/ns.Name and include a spec map that
omits serviceAccountName entirely) and use nonAdminClient.Create(testCtx,
<unstructured>) to assert admission rejects it; leave the existing empty-string
test unchanged. Ensure you reference the MustGather GVK and the same metadata
used by the other tests so the admission path is identical.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 063bad32-db8b-48b6-9676-ab661f48f674

📥 Commits

Reviewing files that changed from the base of the PR and between 2e0c4b4 and 28790e7.

📒 Files selected for processing (4)
  • api/v1alpha1/mustgather_types.go
  • bundle/manifests/tech-preview/operator.openshift.io_mustgathers.yaml
  • deploy/crds/operator.openshift.io_mustgathers.yaml
  • test/e2e/must_gather_operator_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • deploy/crds/operator.openshift.io_mustgathers.yaml
  • bundle/manifests/tech-preview/operator.openshift.io_mustgathers.yaml
  • api/v1alpha1/mustgather_types.go

Comment thread test/e2e/must_gather_operator_test.go
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.71%. Comparing base (59b15a1) to head (5f8c287).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #347      +/-   ##
==========================================
- Coverage   62.89%   62.71%   -0.18%     
==========================================
  Files           8        8              
  Lines         830      826       -4     
==========================================
- Hits          522      518       -4     
  Misses        302      302              
  Partials        6        6              
Files with missing lines Coverage Δ
api/v1alpha1/mustgather_types.go 100.00% <ø> (ø)
controllers/mustgather/mustgather_controller.go 58.13% <100.00%> (-0.50%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@neha037 neha037 marked this pull request as ready for review May 4, 2026 19:38
@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 4, 2026
@neha037
Copy link
Copy Markdown
Contributor Author

neha037 commented May 12, 2026

/test e2e-gcp-operator

2 similar comments
@neha037
Copy link
Copy Markdown
Contributor Author

neha037 commented May 18, 2026

/test e2e-gcp-operator

@neha037
Copy link
Copy Markdown
Contributor Author

neha037 commented May 21, 2026

/test e2e-gcp-operator

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 21, 2026

@neha037: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/validate-boilerplate 5f8c287 link false /test validate-boilerplate
ci/prow/e2e-gcp-operator 5f8c287 link true /test e2e-gcp-operator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

3 participants