-
Notifications
You must be signed in to change notification settings - Fork 16
ESO-289: linter suggested fixes #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@bharath-b-rh: This pull request references ESO-289 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 "4.22.0" version, but no target version was set. DetailsIn response to this: 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. |
|
Warning
|
| Cohort / File(s) | Summary |
|---|---|
CRD API Type Definitions api/v1alpha1/external_secrets_config_types.go, api/v1alpha1/external_secrets_manager_types.go, api/v1alpha1/meta.go |
Convert concrete struct fields to optional pointers (e.g., ApplicationConfig, ControllerConfig, Mode, Labels, Tolerations, NodeSelector). Update field tags with +optional, +required, omitempty. Adjust optionality markers for nested config types and collections. |
DeepCopy Implementations api/v1alpha1/zz_generated.deepcopy.go |
Add nil-guarded allocations and deep-copy invocations for pointer fields. Handle conditional population of pointer-based containers (slices, maps). Replace direct assignments with per-element DeepCopyInto calls for nested structures. |
CRD Schema & Metadata config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml, api/v1alpha1/groupversion_info.go |
Normalize YAML description text capitalization (lowercase starting words). Add trailing periods to public comments. No structural schema or validation changes. |
Controller Nil-Safe Accessors pkg/controller/external_secrets/deployments.go, pkg/controller/external_secrets/utils.go, pkg/controller/external_secrets/certificate.go, pkg/controller/external_secrets/install_external_secrets.go, pkg/controller/external_secrets/networkpolicy.go |
Introduce explicit nil checks for optional config fields (ControllerConfig, ApplicationConfig, CertProvider). Use ptr.Deref for safe dereference of optional values. Replace manual map copies with maps.Copy. Update proxy and container handling for pointer-based fields. |
Controller Implementation Updates pkg/controller/external_secrets_manager/controller.go, pkg/controller/external_secrets/configmap.go, pkg/controller/crd_annotator/controller.go |
Add pointer dereferencing for status fields (Name, Type). Replace fmt.Sprintf with fmt.Appendf for patch construction. Add ctx field to Reconciler struct. Minor formatting adjustments. |
Common Utilities pkg/controller/common/errors.go, pkg/controller/common/utils.go, pkg/controller/common/validation_helpers_duplication.go |
Simplify error extraction in IsIrrecoverableError using errors.As. Add maps.Copy for label copying. Introduce atomic.Uint32 done field for reset capability. Add nil guards for optional config fields. Update comment punctuation. |
Controller Tests pkg/controller/external_secrets/*_test.go, pkg/controller/external_secrets_manager/*_test.go, pkg/controller/crd_annotator/*_test.go |
Update test struct initializations to use pointer-wrapped config types (\*ControllerConfig, \*ApplicationConfig, \*PluginsConfig). Replace bare enum values with ptr.To(...) wrappers. Add import of k8s.io/utils/ptr. Adjust nested field access patterns for pointer types. |
Test Utilities & E2E Tests test/apis/generator.go, test/apis/vars.go, test/e2e/e2e_test.go |
Replace interface{} with any type alias. Update JSON schema patch construction to use fmt.Appendf. Adjust CRD validation patch generation. Remove cert-controller pod readiness check from E2E verification. |
Configuration .coderabbit.yaml |
Add directive to consolidate unresolved nitpick suggestions into a single git-diff formatted comment on PR command @coderabbitai /nitpicks. |
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
Warning
There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.
🔧 golangci-lint (2.5.0)
Error: build linters: unable to load custom analyzer "kubeapilinter": bin/kube-api-linter.so, plugin: not implemented
The command is terminated due to an error: build linters: unable to load custom analyzer "kubeapilinter": bin/kube-api-linter.so, plugin: not implemented
Comment @coderabbitai help to get the list of available commands and usage tips.
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bharath-b-rh The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
@coderabbitai /nitpicks |
|
@bharath-b-rh: I'll review the PR with a focus on nitpicks, style issues, and minor improvements. Since this PR addresses linter-suggested fixes, I'll pay special attention to code quality, consistency, and best practices. ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
pkg/controller/common/utils.go (2)
244-266: Critical: InitContainers are not compared.The function checks the length of InitContainers (lines 244-247) and adds them to
fetchedContainers(lines 252-254), but the comparison loop (lines 255-264) only iterates overdesired.Spec.Template.Spec.Containers. This means modifications to InitContainers (e.g., image, args, env changes) will not be detected, preventing updates from being applied.🔎 Proposed fix to include InitContainers in the comparison
for i := range desired.Spec.Template.Spec.Containers { desiredContainer := &desired.Spec.Template.Spec.Containers[i] fetchedContainer, exists := fetchedContainers[desiredContainer.Name] if !exists { return true } if containerSpecModified(desiredContainer, fetchedContainer) { return true } } + for i := range desired.Spec.Template.Spec.InitContainers { + desiredContainer := &desired.Spec.Template.Spec.InitContainers[i] + fetchedContainer, exists := fetchedContainers[desiredContainer.Name] + if !exists { + return true + } + if containerSpecModified(desiredContainer, fetchedContainer) { + return true + } + } return false
555-566: Critical: Missing double-check pattern creates race condition.The function has two issues:
- Line 558 loads
donebut doesn't use the result (dead code).- The implementation lacks a double-check after acquiring the lock, allowing
f()to be called multiple times if multiple goroutines checkdone == 0before any of them sets it to 1.🔎 Proposed fix with double-check pattern
-// Do is same as sync.Once.Do, which calls the passed func f() only once -// until Now is reset. +// Do calls f() only once until Reset is called, similar to sync.Once.Do. func (n *Now) Do(f func()) { - n.done.Load() if n.done.Load() == 0 { n.Lock() defer n.Unlock() - - defer n.done.Store(1) - f() + if n.done.Load() == 0 { + defer n.done.Store(1) + f() + } } }pkg/controller/external_secrets/test_utils.go (1)
37-49: Minor typo in comments.The comments at lines 37 and 44 have trailing
,.instead of just.🔎 Proposed fix
-// testService returns a Service object decoded from the specified asset file,. +// testService returns a Service object decoded from the specified asset file. func testService(assetName string) *corev1.Service {-// testServiceAccount returns a ServiceAccount object decoded from the specified asset file,. +// testServiceAccount returns a ServiceAccount object decoded from the specified asset file. func testServiceAccount(assetName string) *corev1.ServiceAccount {pkg/controller/external_secrets_manager/controller_test.go (1)
295-307: Pointer comparison may not work as intended.At Line 297,
c1.Name != c2.Namecompares pointer addresses rather than the string values they point to. Sincec1.Namecomes from the reconciled object andc2.Namefrom the expected test data, they will have different memory addresses even if the string values are identical, causing the comparison to always evaluate totrue(not equal).This could lead to test logic bypassing the condition comparison. Consider using value comparison:
🔎 Proposed fix
for _, c1 := range esm.Status.ControllerStatuses { for _, c2 := range tt.expectedStatusCondition { - if c1.Name != c2.Name { + if ptr.Deref(c1.Name, "") != ptr.Deref(c2.Name, "") { continue }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (38)
.coderabbit.yamlapi/v1alpha1/external_secrets_config_types.goapi/v1alpha1/external_secrets_manager_types.goapi/v1alpha1/groupversion_info.goapi/v1alpha1/meta.goapi/v1alpha1/zz_generated.deepcopy.goconfig/crd/bases/operator.openshift.io_externalsecretsconfigs.yamlpkg/controller/common/errors.gopkg/controller/common/utils.gopkg/controller/common/validation_helpers_duplication.gopkg/controller/crd_annotator/controller.gopkg/controller/crd_annotator/controller_test.gopkg/controller/external_secrets/certificate.gopkg/controller/external_secrets/certificate_test.gopkg/controller/external_secrets/configmap.gopkg/controller/external_secrets/constants.gopkg/controller/external_secrets/controller.gopkg/controller/external_secrets/deployments.gopkg/controller/external_secrets/deployments_test.gopkg/controller/external_secrets/install_external_secrets.gopkg/controller/external_secrets/install_external_secrets_test.gopkg/controller/external_secrets/networkpolicy.gopkg/controller/external_secrets/networkpolicy_test.gopkg/controller/external_secrets/rbacs.gopkg/controller/external_secrets/rbacs_test.gopkg/controller/external_secrets/secret.gopkg/controller/external_secrets/secret_test.gopkg/controller/external_secrets/service_test.gopkg/controller/external_secrets/serviceaccounts_test.gopkg/controller/external_secrets/test_utils.gopkg/controller/external_secrets/utils.gopkg/controller/external_secrets/validatingwebhook.gopkg/controller/external_secrets/validatingwebhook_test.gopkg/controller/external_secrets_manager/controller.gopkg/controller/external_secrets_manager/controller_test.gotest/apis/generator.gotest/apis/vars.gotest/e2e/e2e_test.go
💤 Files with no reviewable changes (4)
- pkg/controller/external_secrets/secret.go
- pkg/controller/external_secrets/rbacs.go
- pkg/controller/external_secrets/validatingwebhook.go
- test/e2e/e2e_test.go
🧰 Additional context used
📓 Path-based instructions (1)
**
⚙️ CodeRabbit configuration file
-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.
Files:
pkg/controller/external_secrets/test_utils.gopkg/controller/external_secrets/configmap.gopkg/controller/common/validation_helpers_duplication.goapi/v1alpha1/groupversion_info.gopkg/controller/external_secrets/constants.gopkg/controller/external_secrets/rbacs_test.goapi/v1alpha1/zz_generated.deepcopy.goconfig/crd/bases/operator.openshift.io_externalsecretsconfigs.yamlpkg/controller/external_secrets/networkpolicy.gopkg/controller/external_secrets/install_external_secrets.gotest/apis/generator.gopkg/controller/external_secrets/networkpolicy_test.gopkg/controller/external_secrets/serviceaccounts_test.gopkg/controller/external_secrets/validatingwebhook_test.gotest/apis/vars.gopkg/controller/external_secrets/install_external_secrets_test.gopkg/controller/common/utils.gopkg/controller/external_secrets/deployments.gopkg/controller/external_secrets/controller.gopkg/controller/external_secrets_manager/controller_test.gopkg/controller/external_secrets/service_test.gopkg/controller/external_secrets/certificate_test.gopkg/controller/external_secrets/certificate.gopkg/controller/crd_annotator/controller.gopkg/controller/crd_annotator/controller_test.goapi/v1alpha1/external_secrets_manager_types.gopkg/controller/external_secrets/secret_test.gopkg/controller/common/errors.gopkg/controller/external_secrets_manager/controller.goapi/v1alpha1/meta.goapi/v1alpha1/external_secrets_config_types.gopkg/controller/external_secrets/deployments_test.gopkg/controller/external_secrets/utils.go
🧬 Code graph analysis (19)
pkg/controller/external_secrets/test_utils.go (2)
pkg/controller/common/utils.go (1)
DecodeServiceObjBytes(130-136)pkg/operator/assets/bindata.go (1)
MustAsset(1787-1794)
pkg/controller/external_secrets/rbacs_test.go (1)
api/v1alpha1/external_secrets_config_types.go (1)
ControllerConfig(108-138)
pkg/controller/external_secrets/networkpolicy.go (1)
api/v1alpha1/external_secrets_config_types.go (1)
ControllerConfig(108-138)
pkg/controller/external_secrets/install_external_secrets.go (4)
pkg/controller/common/utils.go (2)
IsESMSpecEmpty(494-496)ObjectMetadataModified(195-197)api/v1alpha1/external_secrets_manager_types.go (1)
GlobalConfig(66-76)api/v1alpha1/external_secrets_config_types.go (1)
ControllerConfig(108-138)pkg/controller/common/errors.go (1)
FromClientError(61-71)
pkg/controller/external_secrets/serviceaccounts_test.go (2)
api/v1alpha1/external_secrets_config_types.go (3)
PluginsConfig(207-211)BitwardenSecretManagerProvider(141-155)ControllerConfig(108-138)api/v1alpha1/meta.go (2)
Mode(117-117)Enabled(121-121)
pkg/controller/external_secrets/validatingwebhook_test.go (1)
api/v1alpha1/external_secrets_config_types.go (3)
ControllerConfig(108-138)CertProvidersConfig(214-218)CertManagerConfig(168-204)
pkg/controller/external_secrets/install_external_secrets_test.go (3)
pkg/controller/client/fakes/fake_ctrl_client.go (1)
FakeCtrlClient(12-135)pkg/controller/commontest/utils.go (3)
TestExternalSecretsNamespace(22-22)TestClientError(30-30)TestExternalSecretsConfig(34-40)pkg/controller/client/client.go (1)
CtrlClient(20-30)
pkg/controller/common/utils.go (1)
api/v1alpha1/external_secrets_config_types.go (1)
ControllerConfig(108-138)
pkg/controller/external_secrets/controller.go (1)
pkg/controller/client/client.go (1)
CtrlClient(20-30)
pkg/controller/external_secrets_manager/controller_test.go (2)
api/v1alpha1/external_secrets_manager_types.go (1)
Condition(113-123)api/v1alpha1/conditions.go (2)
Ready(20-20)Degraded(10-10)
pkg/controller/external_secrets/service_test.go (2)
api/v1alpha1/external_secrets_config_types.go (2)
PluginsConfig(207-211)BitwardenSecretManagerProvider(141-155)api/v1alpha1/meta.go (2)
Mode(117-117)Enabled(121-121)
pkg/controller/external_secrets/certificate_test.go (2)
api/v1alpha1/external_secrets_config_types.go (6)
ApplicationConfig(91-105)ControllerConfig(108-138)CertProvidersConfig(214-218)CertManagerConfig(168-204)PluginsConfig(207-211)BitwardenSecretManagerProvider(141-155)api/v1alpha1/meta.go (3)
Mode(117-117)Enabled(121-121)ObjectReference(20-38)
pkg/controller/external_secrets/certificate.go (1)
api/v1alpha1/external_secrets_config_types.go (1)
ControllerConfig(108-138)
pkg/controller/crd_annotator/controller_test.go (1)
api/v1alpha1/external_secrets_config_types.go (3)
ControllerConfig(108-138)CertProvidersConfig(214-218)CertManagerConfig(168-204)
pkg/controller/external_secrets/secret_test.go (2)
api/v1alpha1/external_secrets_config_types.go (3)
ApplicationConfig(91-105)ControllerConfig(108-138)CertProvidersConfig(214-218)api/v1alpha1/meta.go (2)
Mode(117-117)Disabled(124-124)
pkg/controller/external_secrets_manager/controller.go (1)
api/v1alpha1/external_secrets_manager_types.go (1)
ControllerStatus(96-111)
api/v1alpha1/external_secrets_config_types.go (1)
api/v1alpha1/meta.go (3)
Mode(117-117)SecretReference(41-47)ObjectReference(20-38)
pkg/controller/external_secrets/deployments_test.go (2)
api/v1alpha1/external_secrets_config_types.go (4)
ApplicationConfig(91-105)BitwardenSecretManagerProvider(141-155)PluginsConfig(207-211)CertManagerConfig(168-204)api/v1alpha1/meta.go (5)
CommonConfigs(50-90)Mode(117-117)Enabled(121-121)SecretReference(41-47)ProxyConfig(93-114)
pkg/controller/external_secrets/utils.go (3)
api/v1alpha1/external_secrets_config_types.go (2)
BitwardenSecretManagerProvider(141-155)ApplicationConfig(91-105)pkg/controller/common/utils.go (1)
EvalMode(489-491)api/v1alpha1/meta.go (2)
Mode(117-117)Disabled(124-124)
🪛 YAMLlint (1.37.1)
.coderabbit.yaml
[error] 1-1: syntax error: found character '@' that cannot start any token
(syntax)
🔇 Additional comments (46)
pkg/controller/common/validation_helpers_duplication.go (1)
18-18: Comment punctuation improvements align with Go conventions.The changes add terminal periods to comment headers, making them grammatically complete sentences per Go style guidelines. All utility functions remain correctly implemented with no behavioral changes.
Also applies to: 37-37, 53-53, 72-72, 91-91, 100-100, 117-117
pkg/controller/common/utils.go (5)
6-6: LGTM!Good use of the standard
mapspackage for themaps.Copyoperation below.
33-39: LGTM!Explicitly declaring the
donefield asatomic.Uint32is a good practice that improves code clarity.
65-72: LGTM!Using
maps.Copyis more idiomatic and clearer than a manual loop.
499-504: LGTM!The nil-safe checks are correctly implemented to handle the pointer-based fields in the updated type signature.
568-574: LGTM!The Reset implementation is correct, allowing
Doto callf()again after reset.api/v1alpha1/groupversion_info.go (1)
28-32: LGTM!Comment punctuation updates align with Go documentation standards.
pkg/controller/common/errors.go (1)
48-54: LGTM!The refactored
IsIrrecoverableErroruses idiomaticerrors.Aspattern for error unwrapping. This is cleaner than manual type assertions and correctly handles wrapped errors.pkg/controller/external_secrets/install_external_secrets.go (1)
34-52: LGTM!The nil-safe pointer dereference pattern and
maps.Copyusage are clean improvements that align with the pointer-based API field changes.pkg/controller/external_secrets/configmap.go (1)
84-89: LGTM!Clean refactor using
maps.Copyfrom the standard library instead of manual iteration.pkg/controller/external_secrets/controller.go (1)
84-95: LGTM!Comment punctuation and formatting improvements.
pkg/controller/external_secrets/certificate.go (1)
101-128: LGTM!The nil-safe access pattern for nested configuration and
ptr.Derefusage for optionalIssuerReffields are well-implemented. The fallback logic correctly applies defaults when values are nil or empty.pkg/controller/external_secrets/constants.go (1)
55-78: LGTM!The comment punctuation improvements enhance documentation consistency without affecting functionality.
pkg/controller/crd_annotator/controller.go (1)
249-250: LGTM!The change from
fmt.Sprintfwith a pre-sized buffer tofmt.Appendfwith a nil buffer is functionally equivalent and aligns with Go idioms for string formatting.pkg/controller/external_secrets/networkpolicy.go (1)
80-92: LGTM!The nil guards and pointer dereference correctly implement nil-safe access for the pointer-based
NetworkPoliciesfield, aligning with the API's pointer-based optionality pattern.test/apis/vars.go (1)
142-142: LGTM!The change from
*interface{}to*anyis a stylistic improvement using the Go 1.18+ type alias, with no functional impact.config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml (1)
1166-1167: LGTM!The description text changes improve consistency by using lowercase for field descriptions in the CRD schema. No functional changes to the CRD structure.
Also applies to: 1214-1226, 1541-1547, 1570-1571
pkg/controller/external_secrets/validatingwebhook_test.go (1)
10-10: LGTM!The test correctly updates to use pointer-based fields (
ControllerConfigas*ControllerConfigandInjectAnnotationsas*string) with proper use ofptr.Tohelper, aligning with the API's pointer-based optionality pattern.Also applies to: 123-129
pkg/controller/external_secrets/secret_test.go (1)
40-43: LGTM!The test updates correctly reflect the pointer-based API changes for
ApplicationConfigandControllerConfigfields inExternalSecretsConfigSpec.Also applies to: 51-54, 62-67, 214-222
pkg/controller/external_secrets/service_test.go (1)
9-9: LGTM!The test correctly updates to use pointer-based fields (
Pluginsas*PluginsConfigandModeas*Mode) with proper use ofptr.Tohelper, aligning with the API's pointer-based optionality pattern.Also applies to: 62-67
pkg/controller/external_secrets/rbacs_test.go (1)
34-42: LGTM!The test updates correctly adapt to the pointer-based
ControllerConfigfield change in the API. The use of&operatorv1alpha1.ControllerConfig{}properly initializes the pointer field.Also applies to: 268-278, 282-293
pkg/controller/external_secrets_manager/controller.go (2)
184-196: LGTM!The pointer handling for
ControllerStatus.Nameis correct. Usingptr.Dereffor nil-safe comparison and storing&controllerNameproperly handles the pointer-based API. SincecontrollerNameis a function parameter (passed by value), taking its address and appending the struct to the slice is safe.
198-227: LGTM!The
updateStatusConditionfunction correctly handles pointer-basedCondition.Typefield. The use ofptr.Deref(c.Type, "")provides nil-safe comparison, and&updCondition.Typecorrectly stores the type as a pointer.pkg/controller/external_secrets/utils.go (3)
91-101: LGTM!The nil-safety checks are properly ordered from outer to inner structures. The use of
ptr.Derefwithoperatorv1alpha1.Disabledas default inisBitwardenConfigEnabledcorrectly handles the optional Mode field.
103-124: LGTM!The
getLogLevelandgetOperatingNamespacefunctions properly handle the pointer-based configuration fields with appropriate nil checks before dereferencing.
131-159: LGTM!The proxy configuration handling correctly implements the precedence order (ESC > ESM > OLM env vars) with proper nil checks. The pointer assignments for OLM environment variable fallback are correct.
test/apis/generator.go (1)
160-187: LGTM!The changes appropriately modernize the codebase:
[]interface{}→[]anyaligns with Go 1.18+ type aliasfmt.Appendf(nil, ...)is more efficient than[]byte(fmt.Sprintf(...))as it avoids intermediate string allocationAlso applies to: 219-344
api/v1alpha1/zz_generated.deepcopy.go (1)
1-668: LGTM!This is auto-generated code by
controller-gen. The deepcopy implementations correctly handle the new pointer-based fields with appropriate nil checks and proper deep copy patterns for nested structures.pkg/controller/crd_annotator/controller_test.go (2)
32-43: LGTM!The test helper correctly adapts to the pointer-based
ControllerConfigfield and usesptr.To("true")for theInjectAnnotationsstring pointer field.
420-435: LGTM!Using
r.Getinstead ofr.CtrlClient.Getis appropriate since theReconcilerstruct embedsCtrlClient, makingGetdirectly accessible on the reconciler.pkg/controller/external_secrets/deployments_test.go (4)
140-213: LGTM!The test correctly adapts to the pointer-based
ApplicationConfigfield. The nested pointer fields (Tolerationsas*[]corev1.Toleration,NodeSelectoras*map[string]string) are properly initialized.
356-391: LGTM!The test cases for invalid configurations correctly use the pointer-based struct initialization pattern with
&v1alpha1.ApplicationConfig{}and properly initialize the embeddedCommonConfigswith pointer-to-slice/map fields.
516-536: LGTM!The Bitwarden configuration test correctly handles the conditional nil-safe initialization of
PluginsandControllerConfigwith proper pointer assignments. Usingptr.To(v1alpha1.Enabled)for the Mode field aligns with the API change to*Mode.
660-728: LGTM!The proxy configuration tests correctly use
ptr.To()for string pointer fields (HTTPProxy,HTTPSProxy,NoProxy) in theProxyConfigstruct, properly testing the precedence logic.pkg/controller/external_secrets/deployments.go (3)
1-159: LGTM on nil-safety patterns and maps.Copy usage.The nil-safe checks for
ApplicationConfigand nested fields are correctly implemented, and usingmaps.Copyis idiomatic Go 1.21+ for efficiently copying map entries.
181-273: Nil-safety patterns for resource configuration look correct.The pointer dereference patterns for
NodeSelectorandTolerations(lines 214, 216, 258, 260) correctly handle the new*map[string]stringand*[]corev1.Tolerationtypes.
482-518: Proxy configuration nil-safety is well implemented.The guard clause at line 483 correctly short-circuits when
proxyConfigis nil or when all proxy fields are nil. Theptr.Derefusage provides safe dereferencing with empty string defaults.pkg/controller/external_secrets/networkpolicy_test.go (2)
82-90: Test configuration correctly uses pointer types.The test properly initializes
Pluginsas a pointer and usesptr.To(operatorv1alpha1.Enabled)for theModefield, aligning with the API type changes.
243-262: Network policy test configuration is properly updated.The
NetworkPoliciesfield is correctly initialized as*[]operatorv1alpha1.NetworkPolicy, andintstr.FromInt32(443)is the appropriate function for explicit int32 port values.pkg/controller/external_secrets/serviceaccounts_test.go (1)
75-108: LGTM on service account test updates.Test configurations properly use pointer types for
PluginsandControllerConfig, consistent with the API type changes.pkg/controller/external_secrets/install_external_secrets_test.go (1)
16-254: Comprehensive test coverage for namespace handling.The test suite thoroughly covers namespace creation, update scenarios (label changes, label preservation, label override), and error paths. The use of
wantCreateandwantUpdateflags with call count verification is a good pattern.pkg/controller/external_secrets/certificate_test.go (1)
470-488: Test helper properly constructs pointer-based configuration.The
testExternalSecretsConfigForCertificatehelper correctly initializes all pointer fields (ControllerConfig,ApplicationConfig,Plugins) and usesptr.Tofor theOperatingNamespacestring pointer.api/v1alpha1/external_secrets_config_types.go (2)
64-74: LGTM on pointer-based optional fields.The conversion of
ApplicationConfig,Plugins, andControllerConfigto pointer types with+optionalannotations correctly implements optional semantics for the CRD spec.
251-255: Verify:+requiredwithomitemptyon Egress slice.The
Egressfield is marked+requiredbut hasomitempty. For slices, this may be intentional if an empty slice[]is considered valid for "required". However, verify this aligns with the intended validation behavior—omitemptywill omit the field entirely when empty rather than serializing as[].api/v1alpha1/meta.go (2)
50-90: LGTM on CommonConfigs pointer-based fields.The conversion to pointer types for optional configuration fields (
LogLevel,Tolerations,NodeSelector) properly enables distinguishing between "not set" (nil) and "set to zero/empty value".
92-114: ProxyConfig pointer fields are correctly implemented.Converting
HTTPProxy,HTTPSProxy, andNoProxyto*stringwith+optionalallows proper nil-checking in the controller code (as seen in deployments.go).
| @@ -0,0 +1 @@ | |||
| @coderabbitai When a comment "@coderabbitai /nitpicks" is added on PR, please consolidate all your unresolved nitpick suggestions from this PR into a single comment which is in git diff format, which author can easily apply using `git apply` command in the same PR or in a follow up PR. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid YAML syntax - file will not be parsed.
The content is plain text starting with @, which is not valid YAML. YAML configuration files must be structured documents. This directive will be ignored by CodeRabbit.
If you want to add custom instructions, use the proper YAML structure:
🔎 Example valid .coderabbit.yaml structure
# Example: To customize review behavior
reviews:
profile: "chill"
path_instructions:
- path: "**"
instructions: "Focus on major issues impacting performance, readability, maintainability and security."If this directive is meant as a one-time comment instruction rather than a permanent configuration, consider removing this file and using a PR comment instead.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 1-1: syntax error: found character '@' that cannot start any token
(syntax)
🤖 Prompt for AI Agents
.coderabbit.yaml around lines 1 to 1: the file currently contains a plain text
directive starting with "@" which is invalid YAML and will cause the config to
be ignored; replace this line with a valid YAML mapping (or remove the file if
you only intended a one‑time PR comment). To fix, convert the directive into a
proper YAML structure such as a top‑level "reviews:" mapping with keys like
"profile" and "path_instructions" or move the instruction into a PR comment;
ensure strings are quoted where needed and the file is syntactically valid YAML
so the tool can parse it.
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
| // +required | ||
| Name string `json:"name,omitempty"` | ||
|
|
||
| // componentName specifies which external-secrets component this network policy applies to. | ||
| // +kubebuilder:validation:Enum:=ExternalSecretsCoreController;BitwardenSDKServer | ||
| // +kubebuilder:validation:Required | ||
| ComponentName ComponentName `json:"componentName"` | ||
| // +required | ||
| ComponentName ComponentName `json:"componentName,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent annotation: +required with omitempty on NetworkPolicy fields.
Both Name (line 239) and ComponentName (line 244) are marked +required but have json:"...,omitempty" tags. For truly required fields, the omitempty tag should be removed to ensure the fields are always serialized and validated as present.
🔎 Suggested fix
// +kubebuilder:validation:MaxLength:=253
// +required
- Name string `json:"name,omitempty"`
+ Name string `json:"name"`
// componentName specifies which external-secrets component this network policy applies to.
// +kubebuilder:validation:Enum:=ExternalSecretsCoreController;BitwardenSDKServer
// +required
- ComponentName ComponentName `json:"componentName,omitempty"`
+ ComponentName ComponentName `json:"componentName"`📝 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.
| // +kubebuilder:validation:MinLength:=1 | |
| // +kubebuilder:validation:MaxLength:=253 | |
| // +kubebuilder:validation:Required | |
| Name string `json:"name"` | |
| // +required | |
| Name string `json:"name,omitempty"` | |
| // componentName specifies which external-secrets component this network policy applies to. | |
| // +kubebuilder:validation:Enum:=ExternalSecretsCoreController;BitwardenSDKServer | |
| // +kubebuilder:validation:Required | |
| ComponentName ComponentName `json:"componentName"` | |
| // +required | |
| ComponentName ComponentName `json:"componentName,omitempty"` | |
| // +kubebuilder:validation:MinLength:=1 | |
| // +kubebuilder:validation:MaxLength:=253 | |
| // +required | |
| Name string `json:"name"` | |
| // componentName specifies which external-secrets component this network policy applies to. | |
| // +kubebuilder:validation:Enum:=ExternalSecretsCoreController;BitwardenSDKServer | |
| // +required | |
| ComponentName ComponentName `json:"componentName"` |
🤖 Prompt for AI Agents
In api/v1alpha1/external_secrets_config_types.go around lines 236 to 244, the
struct fields Name and ComponentName are annotated with +required but their json
tags include ,omitempty which prevents required fields from being
serialized/validated; to fix, remove the ,omitempty from the json struct tags
for both Name and ComponentName so they become json:"name" and
json:"componentName" (or equivalent without omitempty), keeping the kubebuilder
validation tags intact so the fields are always present and validated.
| type ControllerStatus struct { | ||
| // name of the controller for which the observed condition is recorded. | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
| // +required | ||
| Name *string `json:"name,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent annotation: +required with pointer and omitempty.
The Name field is marked +required but uses a pointer type with omitempty. This is semantically contradictory—a required field should not be nullable/omittable. Consider either:
- Keep
+requiredand change toName string(non-pointer, no omitempty) - Keep the pointer with
omitemptyand change to+optional
🤖 Prompt for AI Agents
In api/v1alpha1/external_secrets_manager_types.go around lines 96 to 99, the
ControllerStatus.Name field is annotated `+required` but declared as a pointer
with `json:"name,omitempty"`, which is contradictory; change the declaration to
a non-pointer string and remove `omitempty` (e.g., Name string `json:"name"`) so
the field is truly required, and keep the `+required` annotation; alternatively,
if you intend the field to be optional, change the annotation to `+optional` and
keep the pointer+omitempty — pick one and make that consistent.
| type Condition struct { | ||
| // type of the condition | ||
| // +kubebuilder:validation:Required | ||
| Type string `json:"type"` | ||
| // +required | ||
| Type *string `json:"type,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same inconsistency: +required with pointer and omitempty on Type field.
The Type field has the same conflicting pattern as Name. A +required field should not use a pointer type with omitempty tag.
🤖 Prompt for AI Agents
In api/v1alpha1/external_secrets_manager_types.go around lines 113 to 116, the
Condition.Type field is marked `+required` but is defined as a pointer with
`omitempty`, which is inconsistent; change the field to a non-pointer string and
remove `omitempty` from the JSON tag (e.g., Type string `json:"type"`), ensuring
the required field is a plain string and the tag reflects it.
| // ObjectReference is a reference to an object with a given name, kind and group. | ||
| type ObjectReference struct { | ||
| // Name of the resource being referred to. | ||
| // name of the resource being referred to. | ||
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
| // +required | ||
| Name string `json:"name,omitempty"` | ||
|
|
||
| // Kind of the resource being referred to. | ||
| // kind of the resource being referred to. | ||
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:Optional | ||
| Kind string `json:"kind,omitempty"` | ||
| // +optional | ||
| Kind *string `json:"kind,omitempty"` | ||
|
|
||
| // Group of the resource being referred to. | ||
| // group of the resource being referred to. | ||
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:Optional | ||
| Group string `json:"group,omitempty"` | ||
| // +optional | ||
| Group *string `json:"group,omitempty"` | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjectReference field changes look correct except for Name annotation.
The conversion of Kind and Group to pointer types with +optional is correct. However, Name (line 25) has +required with omitempty, which is inconsistent—a required field should typically not have omitempty.
🤖 Prompt for AI Agents
In api/v1alpha1/meta.go around lines 19 to 38, the Name field is marked
+required but its struct tag uses `json:"name,omitempty"`, which is
inconsistent; remove the `omitempty` (or alternatively mark Name as +optional)
so the JSON tag matches the kubebuilder requirement—update the Name tag to
`json:"name"` and keep the existing validation annotations to enforce presence
and length.
| // SecretReference is a reference to the secret with the given name, which should exist in the same namespace where it will be utilized. | ||
| type SecretReference struct { | ||
| // Name of the secret resource being referred to. | ||
| // name of the secret resource being referred to. | ||
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
| // +required | ||
| Name string `json:"name,omitempty"` | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same pattern issue on SecretReference.Name.
The Name field has +required but uses omitempty tag. For consistency, consider removing omitempty from required fields.
🤖 Prompt for AI Agents
In api/v1alpha1/meta.go around lines 40 to 47, the SecretReference.Name field is
marked with +required but its struct tag uses `json:"name,omitempty"`, which
contradicts the required annotation; update the struct tag to remove `omitempty`
so the JSON tag is `json:"name"` (keeping validation kubebuilder comments
intact) to ensure required fields are not omitted during marshaling/validation.
|
|
||
| ctx context.Context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n pkg/controller/crd_annotator/controller.go | sed -n '50,120p'Repository: openshift/external-secrets-operator
Length of output: 3002
🏁 Script executed:
# Check how context is used in other reconciler implementations
rg -n -C3 'func \(r \*Reconciler\) Reconcile\(ctx context\.Context' --type=goRepository: openshift/external-secrets-operator
Length of output: 2186
🏁 Script executed:
# Also check the specific file for the context field definition and usage
rg -n 'ctx.*context\.' pkg/controller/crd_annotator/controller.go | head -20Repository: openshift/external-secrets-operator
Length of output: 430
🏁 Script executed:
cat -n pkg/controller/crd_annotator/controller.go | sed -n '189,220p'Repository: openshift/external-secrets-operator
Length of output: 1695
🏁 Script executed:
cat -n pkg/controller/crd_annotator/controller.go | sed -n '240,280p'Repository: openshift/external-secrets-operator
Length of output: 1735
🏁 Script executed:
cat -n pkg/controller/crd_annotator/controller.go | sed -n '298,320p'Repository: openshift/external-secrets-operator
Length of output: 1254
Fix context propagation in reconciliation methods.
The struct-level ctx initialized with context.Background() (line 85) is used in updateAnnotationsInAllCRDs (line 264) and updateAnnotations (line 252) instead of the per-request context. Additionally, updateStatus is called with r.ctx at line 298. This bypasses the per-request context's timeout and cancellation semantics, preventing proper request scoping.
The Reconcile method receives the per-request context but processReconcileRequest (line 215) has no parameter to accept and propagate it. Pass the per-request context through the call chain: modify processReconcileRequest to accept ctx context.Context as a parameter, update all callers to pass it, and use it in updateAnnotationsInAllCRDs and updateAnnotations instead of the struct-level background context.
| if exist { | ||
| // Merge labels: preserve existing, overlay with desired resourceLabels | ||
| desired.Labels = make(map[string]string) | ||
| maps.Copy(desired.Labels, fetched.Labels) | ||
| maps.Copy(desired.Labels, resourceLabels) | ||
|
|
||
| if common.ObjectMetadataModified(desired, fetched) { | ||
| if err := r.UpdateWithRetry(r.ctx, desired); err != nil { | ||
| return common.FromClientError(err, "failed to update namespace %s", namespace) | ||
| } | ||
| } | ||
| } else { | ||
| if err := r.Create(r.ctx, desired); err != nil { | ||
| return common.FromClientError(err, "failed to create namespace %s", namespace) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing ResourceVersion will cause update failures.
When updating an existing namespace, desired lacks the ResourceVersion from fetched. Kubernetes API requires ResourceVersion for updates to handle optimistic concurrency.
🔎 Proposed fix
if exist {
// Merge labels: preserve existing, overlay with desired resourceLabels
desired.Labels = make(map[string]string)
maps.Copy(desired.Labels, fetched.Labels)
maps.Copy(desired.Labels, resourceLabels)
+ desired.ResourceVersion = fetched.ResourceVersion
if common.ObjectMetadataModified(desired, fetched) {
if err := r.UpdateWithRetry(r.ctx, desired); err != nil {
return common.FromClientError(err, "failed to update namespace %s", namespace)
}
}Alternatively, update fetched.Labels directly and pass fetched to UpdateWithRetry:
if exist {
- // Merge labels: preserve existing, overlay with desired resourceLabels
- desired.Labels = make(map[string]string)
- maps.Copy(desired.Labels, fetched.Labels)
- maps.Copy(desired.Labels, resourceLabels)
-
- if common.ObjectMetadataModified(desired, fetched) {
- if err := r.UpdateWithRetry(r.ctx, desired); err != nil {
+ // Merge resourceLabels into fetched labels
+ if fetched.Labels == nil {
+ fetched.Labels = make(map[string]string)
+ }
+ maps.Copy(fetched.Labels, resourceLabels)
+
+ if common.ObjectMetadataModified(desired, fetched) {
+ if err := r.UpdateWithRetry(r.ctx, fetched); err != nil {
return common.FromClientError(err, "failed to update namespace %s", namespace)
}
}📝 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.
| if exist { | |
| // Merge labels: preserve existing, overlay with desired resourceLabels | |
| desired.Labels = make(map[string]string) | |
| maps.Copy(desired.Labels, fetched.Labels) | |
| maps.Copy(desired.Labels, resourceLabels) | |
| if common.ObjectMetadataModified(desired, fetched) { | |
| if err := r.UpdateWithRetry(r.ctx, desired); err != nil { | |
| return common.FromClientError(err, "failed to update namespace %s", namespace) | |
| } | |
| } | |
| } else { | |
| if err := r.Create(r.ctx, desired); err != nil { | |
| return common.FromClientError(err, "failed to create namespace %s", namespace) | |
| } | |
| if exist { | |
| // Merge labels: preserve existing, overlay with desired resourceLabels | |
| desired.Labels = make(map[string]string) | |
| maps.Copy(desired.Labels, fetched.Labels) | |
| maps.Copy(desired.Labels, resourceLabels) | |
| desired.ResourceVersion = fetched.ResourceVersion | |
| if common.ObjectMetadataModified(desired, fetched) { | |
| if err := r.UpdateWithRetry(r.ctx, desired); err != nil { | |
| return common.FromClientError(err, "failed to update namespace %s", namespace) | |
| } | |
| } | |
| } else { | |
| if err := r.Create(r.ctx, desired); err != nil { | |
| return common.FromClientError(err, "failed to create namespace %s", namespace) | |
| } |
🤖 Prompt for AI Agents
In pkg/controller/external_secrets/install_external_secrets.go around lines 131
to 145, the code copies fetched.Labels into a new desired object but does not
preserve fetched.ResourceVersion, causing Kubernetes update calls to fail; fix
by preserving the ResourceVersion before calling UpdateWithRetry (e.g., set
desired.ResourceVersion = fetched.ResourceVersion) or instead modify
fetched.Labels in-place (merge resourceLabels into fetched.Labels) and call
UpdateWithRetry with fetched so the ResourceVersion is retained.
|
@bharath-b-rh: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions 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. |
No description provided.