Skip to content

CM-1040: Extract shared ApplyResource helper and migrate istiocsr to SSA#420

Open
sebrandon1 wants to merge 2 commits into
openshift:masterfrom
sebrandon1:extract-apply-resource
Open

CM-1040: Extract shared ApplyResource helper and migrate istiocsr to SSA#420
sebrandon1 wants to merge 2 commits into
openshift:masterfrom
sebrandon1:extract-apply-resource

Conversation

@sebrandon1

@sebrandon1 sebrandon1 commented May 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds a generic common.ApplyResource[T]() helper for SSA-based reconciliation with pluggable drift detection callbacks
  • Migrates trustmanager's 11 createOrApply methods to use the shared helper
  • Migrates istiocsr's 8 simple createOrApply methods from Create/UpdateWithRetry to SSA via the shared helper
  • Keeps istiocsr's complex ClusterRole/ClusterRoleBinding methods unchanged (they use GenerateName + List fallback + Delete for immutable RoleRef)
  • Drops istioCSRCreateRecon warning events from migrated methods (SSA is inherently idempotent)
  • Net -501 lines of duplicated boilerplate

Test plan

  • go test ./pkg/controller/common/... passes
  • go test ./pkg/controller/istiocsr/... passes
  • go test ./pkg/controller/trustmanager/... passes
  • go build ./... succeeds
  • make lint shows only pre-existing issues (9 total, none introduced)

Summary by CodeRabbit

  • Refactoring

    • Added a shared Server-Side Apply helper to standardize idempotent reconciliation and drift detection across controllers.
    • Migrated IstioCSR and TrustManager reconciliation for Services, ServiceAccounts, Certificates, RBAC resources, Deployments, and webhook configurations to the shared SSA flow.
    • Improved consistency of reconciliation behavior, including more uniform “check exists” vs “apply” handling and messaging.
  • Tests

    • Updated unit tests to reflect the new apply/patch behavior and revised expected error text.

@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 6, 2026
@openshift-ci-robot

openshift-ci-robot commented May 6, 2026

Copy link
Copy Markdown

@sebrandon1: This pull request references CM-1040 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 task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds a generic common.ApplyResource[T]() helper for SSA-based reconciliation with pluggable drift detection callbacks
  • Migrates trustmanager's 11 createOrApply methods to use the shared helper
  • Migrates istiocsr's 8 simple createOrApply methods from Create/UpdateWithRetry to SSA via the shared helper
  • Keeps istiocsr's complex ClusterRole/ClusterRoleBinding methods unchanged (they use GenerateName + List fallback + Delete for immutable RoleRef)
  • Drops istioCSRCreateRecon warning events from migrated methods (SSA is inherently idempotent)
  • Net -501 lines of duplicated boilerplate

Test plan

  • go test ./pkg/controller/common/... passes
  • go test ./pkg/controller/istiocsr/... passes
  • go test ./pkg/controller/trustmanager/... passes
  • go build ./... succeeds
  • make lint shows only pre-existing issues (9 total, none introduced)

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 commented May 6, 2026

Copy link
Copy Markdown

Walkthrough

This PR adds a shared Server-Side Apply helper and routes IstioCSR and TrustManager reconciliation for services, certificates, RBAC, deployments, service accounts, network policies, and webhooks through it. Tests now validate patch-based behavior and standardized errors.

Changes

Server-Side Apply reconciliation

Layer / File(s) Summary
Shared apply helper and ownership
pkg/controller/common/applier.go, pkg/controller/istiocsr/constants.go
Adds generic ApplyResource SSA reconciliation and the IstioCSR field-owner constant.
IstioCSR resource reconciliation
pkg/controller/istiocsr/install_istiocsr.go, pkg/controller/istiocsr/networkpolicies.go, pkg/controller/istiocsr/certificates.go, pkg/controller/istiocsr/serviceaccounts.go, pkg/controller/istiocsr/services.go
Routes IstioCSR services, service accounts, certificates, and network policies through ApplyResource; network policy metadata is finalized before apply.
IstioCSR RBAC reconciliation
pkg/controller/istiocsr/rbacs.go
Routes Role and RoleBinding variants through SSA and deletes existing RoleBindings when immutable roleRef changes.
TrustManager reconciliation
pkg/controller/trustmanager/*.go
Routes certificates, deployments, RBAC resources, service accounts, services, and webhook configurations through the shared helper.
Validation updates
pkg/controller/istiocsr/*_test.go, pkg/controller/trustmanager/*_test.go
Updates mocks from create/update calls to patch calls and aligns error expectations with shared apply wording.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: mytreya-rh, swghosh, chiragkyal

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a shared ApplyResource helper and migrating istiocsr to SSA reconciliation.
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 No modified tests use Ginkgo titles, and the added/updated t.Run names are static, descriptive strings without dynamic data.
Test Structure And Quality ✅ Passed PASS: The modified tests are table-driven unit tests using fake clients; no Ginkgo/Eventually/live-cluster setup was introduced, and assertions include diagnostic messages.
Microshift Test Compatibility ✅ Passed The PR only changes controller unit tests; no new Ginkgo e2e specs or MicroShift-unsupported OpenShift APIs/features were added.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; touched tests are unit tests (Test*) with no multi-node assumptions or SNO-specific skips needed.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: The PR only refactors reconciliation to SSA helpers; touched manifests keep only generic kubernetes.io/os=linux nodeSelectors and no new anti-affinity, spread, or CP-node targeting.
Ote Binary Stdout Contract ✅ Passed The only touched file is a helper-only RBAC reconciler; no main/init/TestMain/BeforeSuite stdout writes were added or found.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The only changed file is pkg/controller/istiocsr/rbacs.go; no new Ginkgo/e2e tests or network assumptions were added.
No-Weak-Crypto ✅ Passed Changed files had no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or crypto imports; only ordinary reflect.DeepEqual drift checks on Kubernetes objects.
Container-Privileges ✅ Passed No changed files add privileged/host* settings; inspected workload manifests use allowPrivilegeEscalation:false and runAsNonRoot:true.
No-Sensitive-Data-In-Logs ✅ Passed New logger calls only emit resource kind/name or namespace; no passwords, tokens, PII, or object specs are logged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci Bot requested review from mytreya-rh and swghosh May 6, 2026 18:32
@openshift-ci

openshift-ci Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

🧹 Nitpick comments (2)
pkg/controller/istiocsr/install_instiocsr_test.go (1)

68-84: ⚡ Quick win

Preserve generated-name simulation for ClusterRole in these fakes.

createOrApplyClusterRoles() still depends on Create mutating the object with a generated name before status is written and before the ClusterRoleBinding gets its RoleRef.Name. These stubs only backfill ClusterRoleBinding, so the test can still pass even if the role name is left empty. I'd add a *rbacv1.ClusterRole branch in each CreateCalls block as well.

Representative tweak
m.CreateCalls(func(ctx context.Context, obj client.Object, option ...client.CreateOption) error {
	switch o := obj.(type) {
+	case *rbacv1.ClusterRole:
+		role := testClusterRole()
+		role.DeepCopyInto(o)
 	case *appsv1.Deployment:
 		if !reflect.DeepEqual(o.GetLabels(), labels) {
 			return fmt.Errorf("labels mismatch in %v resource; got: %v, want: %v", o, o.GetLabels(), labels)
 		}

Also applies to: 110-117, 131-138

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/istiocsr/install_instiocsr_test.go` around lines 68 - 84, The
CreateCalls test stubs need to simulate Create mutating a ClusterRole with a
generated name so createOrApplyClusterRoles() sees a non-empty Role.Name; update
the CreateCalls handlers (the ones that currently switch over *appsv1.Deployment
and *rbacv1.ClusterRoleBinding) to also include a case for *rbacv1.ClusterRole
that sets o.Name to a generated value (e.g., append "-generated" or a
deterministic string) and preserves labels so subsequent logic that reads the
ClusterRole's name (and the ClusterRoleBinding RoleRef.Name) behaves as in real
Create; apply this same addition to the other CreateCalls blocks mentioned.
pkg/controller/trustmanager/webhooks_test.go (1)

207-221: ⚡ Quick win

Keep the error assertion specific to the webhook config.

ApplyResource still includes the resource name in the returned error, so shortening these expectations to just failed to ... resource makes this table much less discriminating. A wrong object name or an extra apply call in this path would still satisfy the assertion. I'd keep the expected substring specific to trustManagerWebhookConfigName here, and mirror that in the other migrated reconciliation tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/trustmanager/webhooks_test.go` around lines 207 - 221, The
test's error expectation is too generic; update the table entries (the case with
name "patch error propagates" and similar migrated reconciliation tests) to
assert the error message includes the specific webhook resource name by matching
the substring that contains trustManagerWebhookConfigName (the Reconciler's
ApplyResource error includes the resource name), e.g. expect the returned error
to contain trustManagerWebhookConfigName along with "failed to apply resource",
and adjust other tests that assert "failed to check if resource" / "failed to
apply resource" to similarly include trustManagerWebhookConfigName so the
assertions target the specific webhook config rather than any resource.
🤖 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 `@pkg/controller/common/applier.go`:
- Around line 33-36: The resourceName construction in applier.go currently uses
fmt.Sprintf("%s/%s", desired.GetNamespace(), desired.GetName()) which yields
"/name" for cluster-scoped objects; change the logic to detect an empty
namespace (desired.GetNamespace() == "") and build resourceName as just
desired.GetName(), otherwise build it as namespace + "/" + name so
cluster-scoped resources do not get a leading slash; update any use of the
existing resourceName variable accordingly.

---

Nitpick comments:
In `@pkg/controller/istiocsr/install_instiocsr_test.go`:
- Around line 68-84: The CreateCalls test stubs need to simulate Create mutating
a ClusterRole with a generated name so createOrApplyClusterRoles() sees a
non-empty Role.Name; update the CreateCalls handlers (the ones that currently
switch over *appsv1.Deployment and *rbacv1.ClusterRoleBinding) to also include a
case for *rbacv1.ClusterRole that sets o.Name to a generated value (e.g., append
"-generated" or a deterministic string) and preserves labels so subsequent logic
that reads the ClusterRole's name (and the ClusterRoleBinding RoleRef.Name)
behaves as in real Create; apply this same addition to the other CreateCalls
blocks mentioned.

In `@pkg/controller/trustmanager/webhooks_test.go`:
- Around line 207-221: The test's error expectation is too generic; update the
table entries (the case with name "patch error propagates" and similar migrated
reconciliation tests) to assert the error message includes the specific webhook
resource name by matching the substring that contains
trustManagerWebhookConfigName (the Reconciler's ApplyResource error includes the
resource name), e.g. expect the returned error to contain
trustManagerWebhookConfigName along with "failed to apply resource", and adjust
other tests that assert "failed to check if resource" / "failed to apply
resource" to similarly include trustManagerWebhookConfigName so the assertions
target the specific webhook config rather than any resource.
🪄 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: 683e1b36-07c6-463b-8cd3-d29a46add8d5

📥 Commits

Reviewing files that changed from the base of the PR and between a2e7514 and f8b7c81.

📒 Files selected for processing (26)
  • pkg/controller/common/applier.go
  • pkg/controller/istiocsr/certificates.go
  • pkg/controller/istiocsr/certificates_test.go
  • pkg/controller/istiocsr/constants.go
  • pkg/controller/istiocsr/install_instiocsr_test.go
  • pkg/controller/istiocsr/install_istiocsr.go
  • pkg/controller/istiocsr/networkpolicies.go
  • pkg/controller/istiocsr/rbacs.go
  • pkg/controller/istiocsr/rbacs_test.go
  • pkg/controller/istiocsr/serviceaccounts.go
  • pkg/controller/istiocsr/serviceaccounts_test.go
  • pkg/controller/istiocsr/services.go
  • pkg/controller/istiocsr/services_test.go
  • pkg/controller/trustmanager/certificates.go
  • pkg/controller/trustmanager/certificates_test.go
  • pkg/controller/trustmanager/controller_test.go
  • pkg/controller/trustmanager/deployments.go
  • pkg/controller/trustmanager/deployments_test.go
  • pkg/controller/trustmanager/rbacs.go
  • pkg/controller/trustmanager/rbacs_test.go
  • pkg/controller/trustmanager/serviceaccounts.go
  • pkg/controller/trustmanager/serviceaccounts_test.go
  • pkg/controller/trustmanager/services.go
  • pkg/controller/trustmanager/services_test.go
  • pkg/controller/trustmanager/webhooks.go
  • pkg/controller/trustmanager/webhooks_test.go

Comment thread pkg/controller/common/applier.go Outdated
@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from ca8b171 to fdd735e Compare May 6, 2026 18:48

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

🧹 Nitpick comments (1)
pkg/controller/istiocsr/serviceaccounts_test.go (1)

22-25: ⚡ Quick win

Cover the no-op branch explicitly.

Now that this table has assertCalls, the "serviceaccount reconciliation successful" case should also assert PatchCallCount() == 0. Right now that case still passes if ApplyResource starts patching unchanged ServiceAccounts on every reconcile, which is one of the main regression risks in this SSA migration.

Suggested assertion
 		{
 			name: "serviceaccount reconciliation successful",
 			preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
 				m.ExistsCalls(func(ctx context.Context, ns types.NamespacedName, obj client.Object) (bool, error) {
 					switch o := obj.(type) {
 					case *corev1.ServiceAccount:
 						serviceaccount := testServiceAccount()
 						serviceaccount.DeepCopyInto(o)
 					}
 					return true, nil
 				})
 			},
+			assertCalls: func(t *testing.T, mock *fakes.FakeCtrlClient) {
+				if mock.PatchCallCount() != 0 {
+					t.Errorf("createOrApplyServiceAccounts() Patch call count: %d, want 0", mock.PatchCallCount())
+				}
+			},
 		},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/istiocsr/serviceaccounts_test.go` around lines 22 - 25, Update
the "serviceaccount reconciliation successful" testcase in the table-driven test
in serviceaccounts_test.go to explicitly assert that no patch operations
occurred: inside its assertCalls function, call mock.PatchCallCount() and
require it equals 0 (on the provided *fakes.FakeCtrlClient) to ensure
ApplyResource did not issue patches for unchanged ServiceAccounts; keep other
existing assertions and reference the Reconciler and ApplyResource behavior as
context.
🤖 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 `@pkg/controller/istiocsr/rbacs.go`:
- Around line 265-269: createOrApplyRoleBindings and
createOrApplyRoleBindingForLeases currently always call common.ApplyResource
(Server-Side Apply) but RoleBinding.roleRef is immutable—mirror the
ClusterRoleBinding handler's pattern: after calling common.ApplyResource (with
hasObjectChanged from getRoleBindingObject/hasObjectChanged), detect when the
failure or diff indicates only a roleRef drift (compare desired.RoleRef to the
live object.RoleRef), then delete the existing rbacv1.RoleBinding and recreate
the desired object (preserving owner refs/events/fieldOwner) as a fallback;
implement this delete-then-create flow in both createOrApplyRoleBindings and
createOrApplyRoleBindingForLeases using the same logic used in the
ClusterRoleBinding handler to avoid permanent SSA validation errors.

---

Nitpick comments:
In `@pkg/controller/istiocsr/serviceaccounts_test.go`:
- Around line 22-25: Update the "serviceaccount reconciliation successful"
testcase in the table-driven test in serviceaccounts_test.go to explicitly
assert that no patch operations occurred: inside its assertCalls function, call
mock.PatchCallCount() and require it equals 0 (on the provided
*fakes.FakeCtrlClient) to ensure ApplyResource did not issue patches for
unchanged ServiceAccounts; keep other existing assertions and reference the
Reconciler and ApplyResource behavior as context.
🪄 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: 3367fe15-60ea-4966-a17e-6222e23128a6

📥 Commits

Reviewing files that changed from the base of the PR and between f8b7c81 and fdd735e.

📒 Files selected for processing (26)
  • pkg/controller/common/applier.go
  • pkg/controller/istiocsr/certificates.go
  • pkg/controller/istiocsr/certificates_test.go
  • pkg/controller/istiocsr/constants.go
  • pkg/controller/istiocsr/install_instiocsr_test.go
  • pkg/controller/istiocsr/install_istiocsr.go
  • pkg/controller/istiocsr/networkpolicies.go
  • pkg/controller/istiocsr/rbacs.go
  • pkg/controller/istiocsr/rbacs_test.go
  • pkg/controller/istiocsr/serviceaccounts.go
  • pkg/controller/istiocsr/serviceaccounts_test.go
  • pkg/controller/istiocsr/services.go
  • pkg/controller/istiocsr/services_test.go
  • pkg/controller/trustmanager/certificates.go
  • pkg/controller/trustmanager/certificates_test.go
  • pkg/controller/trustmanager/controller_test.go
  • pkg/controller/trustmanager/deployments.go
  • pkg/controller/trustmanager/deployments_test.go
  • pkg/controller/trustmanager/rbacs.go
  • pkg/controller/trustmanager/rbacs_test.go
  • pkg/controller/trustmanager/serviceaccounts.go
  • pkg/controller/trustmanager/serviceaccounts_test.go
  • pkg/controller/trustmanager/services.go
  • pkg/controller/trustmanager/services_test.go
  • pkg/controller/trustmanager/webhooks.go
  • pkg/controller/trustmanager/webhooks_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/controller/trustmanager/certificates.go
  • pkg/controller/trustmanager/certificates_test.go

Comment thread pkg/controller/istiocsr/rbacs.go
@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from fdd735e to 26c1bb6 Compare May 14, 2026 19:07
@sebrandon1

Copy link
Copy Markdown
Member Author

/retest

@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from 26c1bb6 to 8b48aaa Compare May 29, 2026 15:51
@sebrandon1

Copy link
Copy Markdown
Member Author

/retest

@sebrandon1

Copy link
Copy Markdown
Member Author

/retest-required

@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from 8b48aaa to 4442995 Compare June 15, 2026 16:25
@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from 4442995 to 786945d Compare June 24, 2026 19:51
@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from 786945d to 81c1b58 Compare July 6, 2026 16:17
@sebrandon1

Copy link
Copy Markdown
Member Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@sebrandon1

Copy link
Copy Markdown
Member Author

Addressed CodeRabbit feedback on RoleBinding.roleRef immutability:

  • Added roleRef drift detection to createOrApplyRoleBindings and createOrApplyRoleBindingForLeases
  • If roleRef has changed, the existing binding is deleted before ApplyResource is called
  • This prevents SSA validation errors when roleRef changes (roleRef is immutable)
  • Mirrors the pattern already used in handleClusterRoleBindingModification

All tests pass with 85.2% coverage on istiocsr package.

@sebrandon1

Copy link
Copy Markdown
Member Author

/retest

Both istiocsr and trustmanager had 8-10 nearly identical createOrApply
methods with duplicated reconciliation boilerplate. trustmanager used
Server-Side Apply while istiocsr used Create/UpdateWithRetry.

Add a generic common.ApplyResource[T]() helper that handles the common
Exists/drift-check/Patch pattern with a pluggable hasChanged callback.
The helper derives the Kubernetes kind from the type parameter for
clear error messages and uses client.ObjectKeyFromObject for consistent
resource name formatting.

Migrate all trustmanager methods and istiocsr simple methods to use it.
ClusterRole/ClusterRoleBinding methods in istiocsr are kept as-is since
they use GenerateName with List fallback and Delete for immutable RoleRef
changes.

The istioCSRCreateRecon warning events are dropped from the migrated
methods since SSA is inherently idempotent.
RoleBinding.roleRef is an immutable field in Kubernetes. When it changes,
the binding must be deleted and recreated. Added roleRef drift detection
to createOrApplyRoleBindings and createOrApplyRoleBindingForLeases to
delete the existing binding before calling ApplyResource if roleRef has
changed, preventing SSA validation errors.

This mirrors the pattern already used in handleClusterRoleBindingModification.
@sebrandon1 sebrandon1 force-pushed the extract-apply-resource branch from d4919c6 to edaac18 Compare July 13, 2026 17:58

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

🧹 Nitpick comments (1)
pkg/controller/istiocsr/rbacs.go (1)

285-306: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract shared helper for RoleBinding roleRef drift/delete logic.

createOrApplyRoleBindings and createOrApplyRoleBindingForLeases duplicate ~18 nearly-identical lines (Exists check, rbacRoleBindingRefModified check, log, Delete with NotFound tolerance). Given this PR's stated goal of removing duplicated boilerplate, extract this into a shared helper, e.g. deleteRoleBindingIfRoleRefChanged(desired *rbacv1.RoleBinding) error.

♻️ Proposed refactor
+func (r *Reconciler) deleteRoleBindingIfRoleRefChanged(desired *rbacv1.RoleBinding) error {
+	key := client.ObjectKeyFromObject(desired)
+	existing := &rbacv1.RoleBinding{}
+	exists, err := r.Exists(r.ctx, key, existing)
+	if err != nil {
+		return common.FromClientError(err, "failed to check if RoleBinding %q exists", key)
+	}
+	if exists && rbacRoleBindingRefModified(desired, existing) {
+		r.log.V(1).Info("rolebinding roleRef changed, deleting for recreation (roleRef is immutable)", "name", key)
+		if err := r.Delete(r.ctx, existing); err != nil && !apierrors.IsNotFound(err) {
+			return common.FromClientError(err, "failed to delete RoleBinding %q to replace roleRef", key)
+		}
+	}
+	return nil
+}
+
 func (r *Reconciler) createOrApplyRoleBindings(istiocsr *v1alpha1.IstioCSR, serviceAccount string, resourceLabels map[string]string) error {
 	desired := r.getRoleBindingObject(serviceAccount, istiocsr.GetNamespace(), istiocsr.Spec.IstioCSRConfig.Istio.Namespace, resourceLabels)
-
-	// RoleBinding.roleRef is immutable; if it has changed, delete the existing binding first
-	key := client.ObjectKeyFromObject(desired)
-	existing := &rbacv1.RoleBinding{}
-	exists, err := r.Exists(r.ctx, key, existing)
-	if err != nil {
-		return common.FromClientError(err, "failed to check if RoleBinding %q exists", key)
-	}
-	if exists && rbacRoleBindingRefModified(desired, existing) {
-		r.log.V(1).Info("rolebinding roleRef changed, deleting for recreation (roleRef is immutable)", "name", key)
-		if err := r.Delete(r.ctx, existing); err != nil {
-			if !apierrors.IsNotFound(err) {
-				return common.FromClientError(err, "failed to delete RoleBinding %q to replace roleRef", key)
-			}
-		}
-	}
+	if err := r.deleteRoleBindingIfRoleRefChanged(desired); err != nil {
+		return err
+	}
 
 	return common.ApplyResource(r.ctx, r.CtrlClient, r.log, r.eventRecorder, istiocsr, desired, &rbacv1.RoleBinding{}, fieldOwner,
 		func(d, e *rbacv1.RoleBinding) bool { return hasObjectChanged(d, e) },
 	)
 }

Apply the analogous change to createOrApplyRoleBindingForLeases.

Also applies to: 331-352

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/istiocsr/rbacs.go` around lines 285 - 306, Extract the
duplicated RoleBinding roleRef drift handling from createOrApplyRoleBindings and
createOrApplyRoleBindingForLeases into a shared helper such as
deleteRoleBindingIfRoleRefChanged, accepting the desired RoleBinding. Move the
Exists check, rbacRoleBindingRefModified comparison, diagnostic log, deletion,
and NotFound tolerance into that helper, then invoke it from both creation
methods before applying the resource.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/controller/istiocsr/rbacs.go`:
- Around line 285-306: Extract the duplicated RoleBinding roleRef drift handling
from createOrApplyRoleBindings and createOrApplyRoleBindingForLeases into a
shared helper such as deleteRoleBindingIfRoleRefChanged, accepting the desired
RoleBinding. Move the Exists check, rbacRoleBindingRefModified comparison,
diagnostic log, deletion, and NotFound tolerance into that helper, then invoke
it from both creation methods before applying the resource.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: a0bb173e-0351-4833-bd59-fa1f25c895cb

📥 Commits

Reviewing files that changed from the base of the PR and between 8b48aaa and edaac18.

📒 Files selected for processing (26)
  • pkg/controller/common/applier.go
  • pkg/controller/istiocsr/certificates.go
  • pkg/controller/istiocsr/certificates_test.go
  • pkg/controller/istiocsr/constants.go
  • pkg/controller/istiocsr/install_instiocsr_test.go
  • pkg/controller/istiocsr/install_istiocsr.go
  • pkg/controller/istiocsr/networkpolicies.go
  • pkg/controller/istiocsr/rbacs.go
  • pkg/controller/istiocsr/rbacs_test.go
  • pkg/controller/istiocsr/serviceaccounts.go
  • pkg/controller/istiocsr/serviceaccounts_test.go
  • pkg/controller/istiocsr/services.go
  • pkg/controller/istiocsr/services_test.go
  • pkg/controller/trustmanager/certificates.go
  • pkg/controller/trustmanager/certificates_test.go
  • pkg/controller/trustmanager/controller_test.go
  • pkg/controller/trustmanager/deployments.go
  • pkg/controller/trustmanager/deployments_test.go
  • pkg/controller/trustmanager/rbacs.go
  • pkg/controller/trustmanager/rbacs_test.go
  • pkg/controller/trustmanager/serviceaccounts.go
  • pkg/controller/trustmanager/serviceaccounts_test.go
  • pkg/controller/trustmanager/services.go
  • pkg/controller/trustmanager/services_test.go
  • pkg/controller/trustmanager/webhooks.go
  • pkg/controller/trustmanager/webhooks_test.go
🚧 Files skipped from review as they are similar to previous changes (23)
  • pkg/controller/common/applier.go
  • pkg/controller/istiocsr/constants.go
  • pkg/controller/istiocsr/certificates_test.go
  • pkg/controller/trustmanager/serviceaccounts.go
  • pkg/controller/istiocsr/certificates.go
  • pkg/controller/trustmanager/deployments_test.go
  • pkg/controller/trustmanager/deployments.go
  • pkg/controller/istiocsr/install_istiocsr.go
  • pkg/controller/istiocsr/serviceaccounts.go
  • pkg/controller/trustmanager/serviceaccounts_test.go
  • pkg/controller/trustmanager/webhooks_test.go
  • pkg/controller/istiocsr/serviceaccounts_test.go
  • pkg/controller/istiocsr/install_instiocsr_test.go
  • pkg/controller/trustmanager/rbacs_test.go
  • pkg/controller/trustmanager/services_test.go
  • pkg/controller/trustmanager/certificates_test.go
  • pkg/controller/trustmanager/certificates.go
  • pkg/controller/trustmanager/webhooks.go
  • pkg/controller/istiocsr/rbacs_test.go
  • pkg/controller/trustmanager/rbacs.go
  • pkg/controller/istiocsr/services.go
  • pkg/controller/istiocsr/services_test.go
  • pkg/controller/istiocsr/networkpolicies.go

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@sebrandon1: 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/e2e-operator-tech-preview edaac18 link false /test e2e-operator-tech-preview
ci/prow/e2e-operator edaac18 link true /test e2e-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.

2 participants