Skip to content

Improve API from kube-api-linter suggestions#329

Draft
swghosh wants to merge 3 commits into
openshift:masterfrom
swghosh:kube-api-lint-fixes
Draft

Improve API from kube-api-linter suggestions#329
swghosh wants to merge 3 commits into
openshift:masterfrom
swghosh:kube-api-lint-fixes

Conversation

@swghosh

@swghosh swghosh commented Mar 12, 2026

Copy link
Copy Markdown
Member

Running the kube-api-linter on the APIs provided by this operator suggested issues,

which were attempted to be fixed by the /golang:lint-fix Claude plugin.

/cc @shivprakashmuley @siddhibhor-56

Details
53 linter issues resolved                                                                                                                        
                                                                                                                                                          
  ┌──────────────────────────────────┬───────┬─────────────────────────────────────────────────────────────────────────────────────────────┐              
  │             Category             │ Count │                                             Fix                                             │              
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤              
  │ errcheck                         │ 3     │ Explicitly ignored Close() return values in validation.go                                   │              
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤              
  │ kubeapilinter/commentstart       │ ~20   │ Updated godoc comments to start with the JSON field name                                    │              
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤              
  │ kubeapilinter/optionalorrequired │ ~8    │ Replaced +kubebuilder:validation:Optional with +optional, added +optional/+required markers │              
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ kubeapilinter/defaults           │ 3     │ Added +optional marker alongside +default                                                   │              
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤              
  │ kubeapilinter/optionalfields     │ 4     │ Changed bool/string fields to *bool/*string pointers, added nolint for status fields        │              
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ kubeapilinter/ssatags            │ 2     │ Added +listType=atomic to Command and Args slices                                           │
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ kubeapilinter/requiredfields     │ 2     │ Changed omitempty to omitzero and removed unnecessary pointers                              │
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ kubeapilinter/conditions         │ 1     │ Moved Conditions to be the first field in MustGatherStatus                                  │
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ kubeapilinter/jsontags           │ 9     │ Added nolint:kubeapilinter for non-API structs (controller, test types)                     │
  ├──────────────────────────────────┼───────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ kubeapilinter/nodurations        │ 1     │ Added nolint (existing API field, can't change type)                                        │
  └──────────────────────────────────┴───────┴─────────────────────────────────────────────────────────────────────────────────────────────┘

swghosh and others added 3 commits March 12, 2026 17:10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Swarup Ghosh <swghosh@redhat.com>
* and other linter suggested fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Swarup Ghosh <swghosh@redhat.com>
Signed-off-by: Swarup Ghosh <swghosh@redhat.com>
@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 Mar 12, 2026
@openshift-ci

openshift-ci Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

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

coderabbitai Bot commented Mar 12, 2026

Copy link
Copy Markdown

Walkthrough

Refactors the MustGather API types from value to pointer-based fields, converting ServiceAccountName, ImageStreamRef.Name/Tag, Audit, and other optional fields to pointers with nil-safety checks. Updates reconciliation logic, templates, and tests to handle pointer dereferencing with appropriate defaults. Adds kubeapilinter configuration and updates dependency tracking.

Changes

Cohort / File(s) Summary
API Type Definitions
.golangci.yml, api/v1alpha1/mustgather_types.go
Adds kubeapilinter linter configuration and refactors MustGather types to convert multiple fields (ServiceAccountName, ImageStreamRef.Name/Tag, Audit, UploadTargetSpec.Type, Storage.Type, SubPath, Claim.Name) from value to pointer types; replaces MustGatherStatus primitive fields with Conditions slice while preserving legacy fields.
Reconciler Logic
controllers/mustgather/mustgather_controller.go
Updates ServiceAccountName handling to default to "default" when nil; adds SFTP host validation with default fallback; enhances getMustGatherImage to validate ImageStreamRef.Name and Tag existence with alias variables for improved consistency.
Reconciler Tests
controllers/mustgather/mustgather_controller_test.go
Converts test data construction to use pointer types via ToPtr for ServiceAccountName, CaseID, Host, and InternalUser fields; adds nolint annotations to non-API test helper types.
Template Generation & Tests
controllers/mustgather/template.go, controllers/mustgather/template_test.go
Updates template construction to handle nil-safe access for ServiceAccountName, Audit, CaseID, Host, SubPath, and Claim.Name with appropriate defaults; adjusts getUploadContainer signature to accept additional parameters; updates test assertions for pointer field comparisons.
Validation & Cleanup
controllers/mustgather/validation.go, controllers/mustgather/validation_test.go
Silences Close() error returns using blank identifier assignment; adds nolint comment to mockNetError type for test helpers.
Build Configuration
go.mod
Minor dependency changes (exact changes not detailed in summary).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Stable And Deterministic Test Names ✅ Passed All test names in modified test files are static and deterministic, containing no dynamic values like pod names, timestamps, UUIDs, or IP addresses.
Test Structure And Quality ✅ Passed Test suite demonstrates good quality across all five Ginkgo requirements: single responsibility maintained through table-driven patterns, setup/cleanup properly handled with defer statements, timeouts appropriately specified using context.WithTimeout(), all assertions include meaningful failure messages, and consistent table-driven testing patterns throughout.
Title check ✅ Passed The title accurately summarizes the primary objective of the changeset, which applies improvements to the API based on kube-api-linter suggestions across multiple files and type definitions.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@swghosh

swghosh commented Mar 12, 2026

Copy link
Copy Markdown
Member Author

/test all

@openshift-ci

openshift-ci Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: swghosh

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 Mar 12, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.00000% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.93%. Comparing base (654b7a4) to head (8dcaaca).

Files with missing lines Patch % Lines
controllers/mustgather/mustgather_controller.go 47.05% 9 Missing ⚠️
controllers/mustgather/validation.go 0.00% 3 Missing ⚠️
controllers/mustgather/template.go 90.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #329      +/-   ##
==========================================
+ Coverage   58.56%   58.93%   +0.36%     
==========================================
  Files           8        8              
  Lines         806      823      +17     
==========================================
+ Hits          472      485      +13     
- Misses        322      326       +4     
  Partials       12       12              
Files with missing lines Coverage Δ
api/v1alpha1/mustgather_types.go 100.00% <ø> (ø)
controllers/mustgather/template.go 90.14% <90.00%> (+0.43%) ⬆️
controllers/mustgather/validation.go 80.21% <0.00%> (ø)
controllers/mustgather/mustgather_controller.go 59.11% <47.05%> (-0.21%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@swghosh swghosh changed the title Improve API from kube-api-linter suggestions MG-91: Improve API from kube-api-linter suggestions Mar 12, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Mar 12, 2026
@openshift-ci-robot

openshift-ci-robot commented Mar 12, 2026

Copy link
Copy Markdown

@swghosh: This pull request references MG-91 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Running the kube-api-linter on the APIs provided by this operator suggested issues,

which were attempted to be fixed by the /golang:lint-fix Claude plugin.

/cc @shivprakashmuley @siddhibhor-56

Summary by CodeRabbit

  • New Features

  • MustGather status now uses Conditions for structured state tracking.

  • Changes

  • API fields restructured to properly designate optional and required parameters.

  • Enhanced default value handling for service account names and SFTP host configurations.

  • Improved field validation for required parameters.

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.

@swghosh swghosh changed the title MG-91: Improve API from kube-api-linter suggestions Improve API from kube-api-linter suggestions Mar 12, 2026
@openshift-ci-robot openshift-ci-robot removed the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Mar 12, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@swghosh: No Jira issue is referenced in the title of this pull request.
To reference a jira issue, add 'XYZ-NNN:' to the title of this pull request and request another refresh with /jira refresh.

Details

In response to this:

Running the kube-api-linter on the APIs provided by this operator suggested issues,

which were attempted to be fixed by the /golang:lint-fix Claude plugin.

/cc @shivprakashmuley @siddhibhor-56

Summary by CodeRabbit

  • New Features

  • MustGather status now uses Conditions for structured state tracking.

  • Changes

  • API fields restructured to properly designate optional and required parameters.

  • Enhanced default value handling for service account names and SFTP host configurations.

  • Improved field validation for required parameters.

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 coderabbitai Bot left a comment

Copy link
Copy Markdown

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 `@controllers/mustgather/mustgather_controller.go`:
- Around line 431-435: The guard only rejects nil pointers but allows empty
strings; update the pre-check around instance.Spec.ImageStreamRef to also reject
empty values by verifying Name and Tag are non-nil and non-empty before
dereferencing (e.g., ensure *instance.Spec.ImageStreamRef.Name != "" and
*instance.Spec.ImageStreamRef.Tag != ""); if either is nil or empty return the
same fmt.Errorf("imageStreamRef name and tag must be specified") error, then
continue to assign isName/isTag after the validated check.
- Around line 238-241: The sftp host handling currently treats a
present-but-empty Host as a valid value and passes an empty string into
validateSFTPWithRetry(); change the normalization so Host is treated as unset
when nil OR empty (same behavior as ServiceAccountName) — e.g., in the code that
sets sftpHost (and mirror the logic used in getJobTemplate()) check both
instance.Spec.UploadTarget.SFTP.Host != nil AND
*instance.Spec.UploadTarget.SFTP.Host != "" before using it, otherwise fall back
to "sftp.access.redhat.com"; ensure validateSFTPWithRetry() and getJobTemplate()
see the same normalized sftpHost value.

In `@controllers/mustgather/template.go`:
- Around line 134-137: The code currently falls back to EmptyDir when
storage.PersistentVolume.Claim.Name is nil; instead, in the function that
constructs outputVolume (referencing variables outputVolume, storage,
storage.Type, v1alpha1.StorageTypePersistentVolume, and
storage.PersistentVolume.Claim.Name) detect a nil or empty Claim.Name and return
or propagate a validation error immediately (rejecting the request) rather than
creating an EmptyDir; validate both nil and empty-string cases and include a
clear error message like "persistent volume claim name required" so callers can
surface the problem.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 37b2f3f3-f632-4ec5-8046-7efc4dda475b

📥 Commits

Reviewing files that changed from the base of the PR and between 654b7a4 and 8dcaaca.

📒 Files selected for processing (8)
  • .golangci.yml
  • api/v1alpha1/mustgather_types.go
  • controllers/mustgather/mustgather_controller.go
  • controllers/mustgather/mustgather_controller_test.go
  • controllers/mustgather/template.go
  • controllers/mustgather/template_test.go
  • controllers/mustgather/validation.go
  • controllers/mustgather/validation_test.go

Comment on lines +238 to +241
sftpHost := "sftp.access.redhat.com"
if instance.Spec.UploadTarget.SFTP.Host != nil {
sftpHost = *instance.Spec.UploadTarget.SFTP.Host
}

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

Treat Host: "" as unset.

If Host is present but empty, this bypasses the default and feeds an empty address into validateSFTPWithRetry(). That makes the preflight check fail instead of using sftp.access.redhat.com. Use the same nil-or-empty handling as ServiceAccountName, and keep getJobTemplate() aligned so both code paths normalize the host identically.

♻️ Suggested fix
 			sftpHost := "sftp.access.redhat.com"
-			if instance.Spec.UploadTarget.SFTP.Host != nil {
+			if instance.Spec.UploadTarget.SFTP.Host != nil && *instance.Spec.UploadTarget.SFTP.Host != "" {
 				sftpHost = *instance.Spec.UploadTarget.SFTP.Host
 			}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sftpHost := "sftp.access.redhat.com"
if instance.Spec.UploadTarget.SFTP.Host != nil {
sftpHost = *instance.Spec.UploadTarget.SFTP.Host
}
sftpHost := "sftp.access.redhat.com"
if instance.Spec.UploadTarget.SFTP.Host != nil && *instance.Spec.UploadTarget.SFTP.Host != "" {
sftpHost = *instance.Spec.UploadTarget.SFTP.Host
}
🤖 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 238 - 241, The
sftp host handling currently treats a present-but-empty Host as a valid value
and passes an empty string into validateSFTPWithRetry(); change the
normalization so Host is treated as unset when nil OR empty (same behavior as
ServiceAccountName) — e.g., in the code that sets sftpHost (and mirror the logic
used in getJobTemplate()) check both instance.Spec.UploadTarget.SFTP.Host != nil
AND *instance.Spec.UploadTarget.SFTP.Host != "" before using it, otherwise fall
back to "sftp.access.redhat.com"; ensure validateSFTPWithRetry() and
getJobTemplate() see the same normalized sftpHost value.

Comment on lines +431 to +435
if instance.Spec.ImageStreamRef.Name == nil || instance.Spec.ImageStreamRef.Tag == nil {
return "", fmt.Errorf("imageStreamRef name and tag must be specified")
}
isName := *instance.Spec.ImageStreamRef.Name
isTag := *instance.Spec.ImageStreamRef.Tag

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 | 🟡 Minor

Reject empty ImageStream ref values in the upfront guard.

This condition only rejects nil pointers. name: "" or tag: "" falls through to the later imagestream lookup/tag scan, so users get a low-level lookup error instead of the intended validation failure.

♻️ Suggested fix
-	if instance.Spec.ImageStreamRef.Name == nil || instance.Spec.ImageStreamRef.Tag == nil {
+	if instance.Spec.ImageStreamRef.Name == nil || *instance.Spec.ImageStreamRef.Name == "" ||
+		instance.Spec.ImageStreamRef.Tag == nil || *instance.Spec.ImageStreamRef.Tag == "" {
 		return "", fmt.Errorf("imageStreamRef name and tag must be specified")
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if instance.Spec.ImageStreamRef.Name == nil || instance.Spec.ImageStreamRef.Tag == nil {
return "", fmt.Errorf("imageStreamRef name and tag must be specified")
}
isName := *instance.Spec.ImageStreamRef.Name
isTag := *instance.Spec.ImageStreamRef.Tag
if instance.Spec.ImageStreamRef.Name == nil || *instance.Spec.ImageStreamRef.Name == "" ||
instance.Spec.ImageStreamRef.Tag == nil || *instance.Spec.ImageStreamRef.Tag == "" {
return "", fmt.Errorf("imageStreamRef name and tag must be specified")
}
isName := *instance.Spec.ImageStreamRef.Name
isTag := *instance.Spec.ImageStreamRef.Tag
🤖 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 431 - 435, The
guard only rejects nil pointers but allows empty strings; update the pre-check
around instance.Spec.ImageStreamRef to also reject empty values by verifying
Name and Tag are non-nil and non-empty before dereferencing (e.g., ensure
*instance.Spec.ImageStreamRef.Name != "" and *instance.Spec.ImageStreamRef.Tag
!= ""); if either is nil or empty return the same fmt.Errorf("imageStreamRef
name and tag must be specified") error, then continue to assign isName/isTag
after the validated check.

Comment on lines +134 to +137
if storage != nil && storage.Type == v1alpha1.StorageTypePersistentVolume && storage.PersistentVolume.Claim.Name != nil {
outputVolume.VolumeSource = corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: storage.PersistentVolume.Claim.Name,
ClaimName: *storage.PersistentVolume.Claim.Name,

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

Fail fast when PersistentVolume storage is missing claim.name.

This branch leaves outputVolume as EmptyDir whenever Claim.Name is nil. That silently turns a persistent-storage request into ephemeral storage and can drop the collected bundle instead of surfacing a validation error. Please reject a missing or empty claim name here rather than downgrading the storage mode.

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

In `@controllers/mustgather/template.go` around lines 134 - 137, The code
currently falls back to EmptyDir when storage.PersistentVolume.Claim.Name is
nil; instead, in the function that constructs outputVolume (referencing
variables outputVolume, storage, storage.Type,
v1alpha1.StorageTypePersistentVolume, and storage.PersistentVolume.Claim.Name)
detect a nil or empty Claim.Name and return or propagate a validation error
immediately (rejecting the request) rather than creating an EmptyDir; validate
both nil and empty-string cases and include a clear error message like
"persistent volume claim name required" so callers can surface the problem.

@openshift-ci

openshift-ci Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

@swghosh: 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 8dcaaca link false /test validate-boilerplate
ci/prow/e2e-gcp-operator 8dcaaca 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.

@openshift-ci

openshift-ci Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

PR needs rebase.

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.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 19, 2026
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. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants