Skip to content

Log 9591 Do not overwrite ConfigMaps owned by other resources - #3381

Open
stilwank wants to merge 3 commits into
openshift:masterfrom
stilwank:LOG-9591-do-not-overwrite-foreign-configmap
Open

Log 9591 Do not overwrite ConfigMaps owned by other resources#3381
stilwank wants to merge 3 commits into
openshift:masterfrom
stilwank:LOG-9591-do-not-overwrite-foreign-configmap

Conversation

@stilwank

@stilwank stilwank commented Jul 30, 2026

Copy link
Copy Markdown

Summary

  • Prevents Cluster Logging Operator from updating resources that already exist but are not owned by the desired owner (e.g. ClusterLogForwarder).
  • Surfaces the conflict as a deployment error on the CLF (Ready=False / DeploymentError) so users can rename or clean up conflicting resources.
  • Replaces the earlier ConfigMap rename approach (closed PR Log 9591 prefix collector ConfigMap with clf- #3352) per review consensus with @jcantrill / @xperimental.

Details

Problem

When a LokiStack and a ClusterLogForwarder share the same metadata.name, CLO previously overwrote Loki’s ConfigMap {name}-config (and could also create/collide on other same-named objects such as DaemonSet/Service/ServiceMonitor). That could leave Loki CrashLoopBackOff and is a general name-collision hazard, not Loki-specific.
Ref: LOG-9591

Solution

  • Add shared helper internal/utils/ownership.go (EnsureCanUpdateOwnedResource) that refuses update when existing ownerReferences do not match the desired owner (UID-based).
  • Wire the check into reconcile paths for:
    ConfigMap, DaemonSet, Deployment, Service, ServiceAccount, ServiceMonitor, NetworkPolicy, Role/RoleBinding, ClusterRoleBinding, and trusted-CA ConfigMap (trust_bundle.go).
  • Unit tests cover create/update of owned objects and refusal for foreign-owned / unowned objects.

Notes

  • Customers should still use different names for LokiStack and ClusterLogForwarder.
  • Shared SCC handling is unchanged (different ownership model).
  • Symmetric fix in the Loki Operator is tracked separately.

Test plan

  • Unit tests (go test ./internal/utils/ ./internal/reconcile/)
  • LokiStack first → same-named CLF → Loki ConfigMap unchanged; CLF Ready=False with refuse-overwrite message
  • Different CLF name → collector resources created; CLF Ready=True
  • Owned collector resources still update normally on reconcile

Links

JIRA: https://redhat.atlassian.net/browse/LOG-9591
Supersedes: #3352

Summary by CodeRabbit

  • Bug Fixes
    • Prevented reconciliation from overwriting resources (including ConfigMaps, Deployments, DaemonSets, NetworkPolicies, Services, ServiceAccounts, ServiceMonitors, and RBAC objects) when they’re owned by a different controller.
    • Refused updates when the existing resource ownership doesn’t match expected owner references, avoiding unintended takeover.
    • Continued updating when ownership matches and the desired content differs.
  • Tests
    • Expanded ownership conflict test coverage for ConfigMaps, DaemonSets, RBAC (including RoleBindings), and shared ownership validation behavior.

Super User and others added 2 commits July 27, 2026 23:11
Refuse to update an existing ConfigMap when its ownerReferences do not
match the ClusterLogForwarder. This prevents CLO from overwriting
LokiStack (or other) ConfigMaps that share the same name, and surfaces
the conflict as a deployment error on the forwarder.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Changes

Owned resource reconciliation

Layer / File(s) Summary
Ownership validation helper
internal/utils/ownership.go, internal/utils/ownership_test.go
Adds shared UID-based ownership checks and stable conflict errors, with tests for persisted, owned, foreign-owned, and unowned resources.
ConfigMap reconciliation
internal/reconcile/configmaps.go, internal/reconcile/configmaps_test.go
Validates ownership before comparing or updating ConfigMaps and covers creation, compatible owners, foreign owners, empty owners, and additional owner references.
Resource reconciler guards
internal/reconcile/daemon_sets.go, internal/reconcile/deployment.go, internal/reconcile/networkpolicy.go, internal/reconcile/service.go, internal/reconcile/service_account.go, internal/reconcile/service_monitor.go, internal/collector/trust_bundle.go, internal/reconcile/daemonset_ownership_test.go
Adds ownership checks before mutating workload, networking, service, service account, service monitor, and trusted bundle resources; includes DaemonSet conflict coverage.
RBAC reconciliation
internal/reconcile/rbac.go, internal/reconcile/rbac_test.go
Adds ownership checks to RBAC reconciliation, updates ClusterRoleBinding owner references, and tests compatible and conflicting RoleBinding ownership.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: alanconway, clee2691, jcantrill

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description covers summary, details, tests, and links, but it omits the mandatory /cc and /assign reviewer/approver commands. Add the required /cc and /assign commands, and include any requested link fields such as depending PRs or related issues if applicable.
✅ Passed checks (3 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly states the main change: preventing overwrites of ConfigMaps owned by other resources.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@openshift-ci
openshift-ci Bot requested review from Clee2691 and alanconway July 30, 2026 16:48
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@openshift-ci openshift-ci Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jul 30, 2026
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Hi @stilwank. Thanks for your PR.

I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@qodo-for-rh-openshift

Copy link
Copy Markdown

PR Summary by Qodo

Prevent overwriting ConfigMaps not owned by the ClusterLogForwarder

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Refuse to update an existing ConfigMap if its ownerReferences don’t match the target CLF.
• Return a clear reconcile error to surface name/ownership conflicts instead of overwriting.
• Add unit tests covering create, owned-update, and foreign/unowned refusal cases.
Diagram

graph TD
  A["CLF reconcile"] --> B["reconcile.Configmap()"] --> C[("Kubernetes API")]
  C --> D{"ConfigMap exists?"}
  D -- "no" --> E["Create ConfigMap"] --> H["Reconcile success"]
  D -- "yes" --> F{"Owner matches CLF?"}
  F -- "no" --> G["Return error (refuse overwrite)"] --> I["CLF DeploymentError"]
  F -- "yes" --> J{"Data/labels same?"}
  J -- "yes" --> H
  J -- "no" --> K["Update ConfigMap"] --> H
  subgraph Legend
    direction LR
    _proc["Reconcile step"] ~~~ _dec{"Decision"} ~~~ _api[("API")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Rename the collector ConfigMap to avoid collisions
  • ➕ Avoids ownership-based failures when a same-named foreign ConfigMap exists
  • ➕ Reduces risk of breaking existing dashboards/auxiliary ConfigMap reconciles that intentionally have no owners
  • ➖ Requires migration logic and/or backward compatibility to avoid breaking existing installs
  • ➖ Doesn’t prevent collisions for other resources that might still share names inadvertently
2. Adopt-only-with-explicit-annotation (opt-in takeover)
  • ➕ Allows controlled adoption of unowned ConfigMaps without forcing users to rename
  • ➕ Keeps safety by requiring an explicit user signal (annotation)
  • ➖ More UX surface area to document and support
  • ➖ Still needs a clear policy for foreign-owned ConfigMaps (likely must refuse)
3. Gate updates by managed-by label/field manager instead of ownerReferences
  • ➕ Works even when ownerReferences are undesirable/omitted for some ConfigMaps
  • ➕ Can better align with SSA/field ownership semantics
  • ➖ Labels are easier for users/other operators to accidentally mimic or remove
  • ➖ More complex to implement correctly across all callers than ownerRef matching

Recommendation: The PR’s approach (refuse to overwrite when ownerReferences don’t match) is the safest default for preventing cross-operator corruption, especially in LokiStack/CLF name-collision scenarios. If future UX demands smoother recovery, consider an opt-in adoption annotation for unowned ConfigMaps, while continuing to hard-refuse foreign-owned resources.

Files changed (2) +141 / -6

Bug fix (1) +18 / -6
configmaps.goRefuse updates to ConfigMaps not owned by the desired owner +18/-6

Refuse updates to ConfigMaps not owned by the desired owner

• Adds an explicit ownerReferences guard before comparing/updating ConfigMaps. If an existing ConfigMap is not owned by the desired owner, reconciliation returns an error and leaves the resource unchanged, preventing accidental overwrites of foreign-owned ConfigMaps.

internal/reconcile/configmaps.go

Tests (1) +123 / -0
configmaps_test.goAdd unit tests for ConfigMap ownership conflict behavior +123/-0

Add unit tests for ConfigMap ownership conflict behavior

• Introduces Ginkgo/Gomega tests validating ConfigMap creation, updates when owned by the CLF, and refusal to overwrite foreign-owned or unowned ConfigMaps. Confirms foreign content and ownership remain unchanged on refusal.

internal/reconcile/configmaps_test.go

@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)
internal/reconcile/configmaps_test.go (1)

90-105: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Cover conflicts where the content is already identical.

Because the existing foreign-owned ConfigMap has different data, this test would still pass if ownership validation were moved after AreSame. Add a case with identical data and a foreign owner to verify that ownership conflicts always return an error.

Suggested test case
+It("should refuse an identical ConfigMap owned by another resource", func() {
+    existing := runtime.NewConfigMap(namespace, name, map[string]string{
+        "vector.toml": "data_dir = \"/var/lib/vector\"",
+    })
+    utils.AddOwnerRefToObject(existing, lokiOwner)
+    k8sClient := newClient(existing)
+
+    err := reconcile.Configmap(k8sClient, k8sClient, desiredCollectorCM(), comparators.CompareLabels)
+    Expect(err).To(HaveOccurred())
+})
🤖 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 `@internal/reconcile/configmaps_test.go` around lines 90 - 105, Add a test
alongside “should refuse to overwrite a ConfigMap owned by another resource”
using identical existing and desired ConfigMap data while retaining a foreign
owner reference. Call reconcile.Configmap and assert it returns an error
containing “refusing to overwrite,” confirming ownership validation occurs even
when content matches.
🤖 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 `@internal/reconcile/configmaps_test.go`:
- Around line 90-105: Add a test alongside “should refuse to overwrite a
ConfigMap owned by another resource” using identical existing and desired
ConfigMap data while retaining a foreign owner reference. Call
reconcile.Configmap and assert it returns an error containing “refusing to
overwrite,” confirming ownership validation occurs even when content matches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e6f4d65-dc5b-4152-b16f-da2b16cc7674

📥 Commits

Reviewing files that changed from the base of the PR and between d3b6f7a and 757c63b.

📒 Files selected for processing (2)
  • internal/reconcile/configmaps.go
  • internal/reconcile/configmaps_test.go

@qodo-for-rh-openshift

qodo-for-rh-openshift Bot commented Jul 30, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 9 rules

Grey Divider


Remediation recommended

1. Overstrict ownerRef match ✓ Resolved 🐞 Bug ≡ Correctness
Description
Configmap() now treats any non-identical OwnerReferences slice as foreign and errors, because
utils.HasSameOwner is reflect.DeepEqual over the entire []OwnerReference. This can reject updates
for ConfigMaps that are still effectively controlled by the same owner but have additional
ownerRefs, ordering differences, or defaulted/optional-field differences, and will surface as a CLF
DeploymentError when invoked from CLF reconciliation.
Code

internal/reconcile/configmaps.go[R31-36]

+		if !utils.HasSameOwner(current.OwnerReferences, configMap.OwnerReferences) {
+			return fmt.Errorf(
+				"configmap %s/%s already exists and is not owned by this ClusterLogForwarder; refusing to overwrite",
+				key.Namespace, key.Name,
+			)
+		}
Relevance

●● Moderate

Loosening ownerRef equality changes safety semantics of [LOG-9591](https://redhat.atlassian.net/browse/LOG-9591) fix; no close repo precedent found.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new guard in Configmap() blocks any update when HasSameOwner is false; HasSameOwner is
implemented as reflect.DeepEqual on the entire ownerRef slice, making extra owner refs, ordering,
and optional-field differences significant. Errors from collector reconciliation are propagated to
the CLF Ready condition as DeploymentError, so these false conflicts will surface as CLF not-ready
failures.

internal/reconcile/configmaps.go[16-47]
internal/utils/utils.go[37-53]
internal/controller/observability/clusterlogforwarder_controller.go[125-131]
internal/collector/config.go[15-29]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`reconcile.Configmap()` currently blocks updates unless `current.OwnerReferences` is *exactly* `reflect.DeepEqual` to `desired.OwnerReferences`. This is stricter than “is owned/controlled by the desired owner” and can cause false conflicts if the current object has extra owner refs, a different order, or optional/defaulted fields that differ while still being controlled by the intended owner.

### Issue Context
- `utils.HasSameOwner()` is strict slice equality.
- `Configmap()` uses it as the gate for whether the operator may update.
- CLF reconciliation will mark Ready=False/DeploymentError on any error returned by reconcile paths.

### Fix Focus Areas
- internal/reconcile/configmaps.go[31-46]
- internal/utils/utils.go[37-53]

### Suggested fix
1. Replace the deep-equality ownership check with a semantic ownership check:
  - Determine the desired *controller* owner (typically the single CLF ownerRef).
  - Determine the current controller owner (`metav1.GetControllerOf(...)` or equivalent logic on `OwnerReferences`).
  - Refuse overwrite only when the current controller exists and does not match the desired controller (match at least APIVersion/Kind/Name; consider UID handling per desired semantics).
  - Optionally allow additional non-controller ownerReferences without treating it as foreign.
2. Keep the “unowned existing configmap” refusal if that is required by [LOG-9591](https://redhat.atlassian.net/browse/LOG-9591), but implement it explicitly (e.g., `len(current.OwnerReferences)==0` and configmap exists => refuse).
3. Add/adjust unit tests to cover: current has desired controller ownerRef + extra ownerRefs (should still allow update), and/or ownerRef ordering differences (should allow).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. CLF-specific refusal message ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
Configmap() now returns an ownership-conflict error string that always refers to “this
ClusterLogForwarder”, but the helper is also used to reconcile non-CLF ConfigMaps (e.g., dashboards
and AWS credentials). If those paths hit the mismatch check, the resulting error/telemetry will
misidentify the owning resource, complicating debugging.
Code

internal/reconcile/configmaps.go[R32-35]

+			return fmt.Errorf(
+				"configmap %s/%s already exists and is not owned by this ClusterLogForwarder; refusing to overwrite",
+				key.Namespace, key.Name,
+			)
Relevance

●●● Strong

Misleading CLF-specific error for shared helper; small wording change likely accepted.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The error string introduced in configmaps.go explicitly references ClusterLogForwarder, while other
packages call reconcile.Configmap() for non-CLF ConfigMaps; therefore the message can be inaccurate
depending on the caller.

internal/reconcile/configmaps.go[31-36]
internal/collector/aws/credentials.go[55-70]
internal/metrics/dashboard/dashboards.go[69-85]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The new refusal error message in `reconcile.Configmap()` is hard-coded to ClusterLogForwarder ownership, but the function is used by other reconcilers too. When ownership mismatches occur outside CLF reconciliation, the message is misleading.

### Issue Context
`reconcile.Configmap()` is called from multiple packages (collector config, AWS creds, dashboards).

### Fix Focus Areas
- internal/reconcile/configmaps.go[32-35]
- internal/collector/aws/credentials.go[55-70]
- internal/metrics/dashboard/dashboards.go[69-82]

### Suggested fix
- Change the error to be generic and include the desired owner identity derived from `configMap.OwnerReferences` (e.g., kind/name/uid of the controller owner), or accept an optional parameter indicating the owning reconciler/resource kind.
- Example wording: `configmap ns/name already exists and is controlled by <currentKind>/<currentName>; refusing to overwrite (desired owner: <desiredKind>/<desiredName>)`. This keeps [LOG-9591](https://redhat.atlassian.net/browse/LOG-9591) behavior while improving diagnostics.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread internal/reconcile/configmaps.go Outdated
Comment thread internal/reconcile/configmaps.go Outdated
Extend ownership checks beyond ConfigMaps to DaemonSet, Deployment,
Service, ServiceAccount, ServiceMonitor, NetworkPolicy, Role/RoleBinding,
ClusterRoleBinding, and trusted-CA ConfigMap. Shared helper matches owners
by UID and surfaces a clear refuse-to-overwrite error.

Co-authored-by: Cursor <cursoragent@cursor.com>

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

🧹 Nitpick comments (2)
internal/utils/ownership_test.go (1)

34-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for shared ownership.

The suite does not test an existing object containing the desired owner plus an additional non-controller owner. Add that case, and add a reconciler-level assertion that the additional OwnerReference remains after update.

🤖 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 `@internal/utils/ownership_test.go` around lines 34 - 55, Add a test in the
ownership suite where the object has the desired owner plus an additional
non-controller OwnerReference, and verify EnsureCanUpdateOwnedResource succeeds.
Add a reconciler-level test or assertion covering the update path, confirming
the additional OwnerReference is preserved after reconciliation.
internal/reconcile/configmaps_test.go (1)

136-152: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert that additional owner references are preserved.

This test verifies that reconciliation succeeds, but it would also pass if the implementation silently removed extra-uid. Add an assertion that the extra OwnerReference remains after the update.

🤖 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 `@internal/reconcile/configmaps_test.go` around lines 136 - 152, Strengthen the
test around reconcile.Configmap by asserting that the additional OwnerReference
with UID "extra-uid" remains on the resulting ConfigMap. Keep the existing
success and data assertions, and verify preservation using
result.OwnerReferences.
🤖 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 `@internal/reconcile/configmaps.go`:
- Around line 30-31: Preserve unrelated OwnerReferences whenever reconciliation
updates an owned resource instead of replacing the full list with
desired.OwnerReferences: update internal/reconcile/configmaps.go:30-31,
internal/reconcile/deployment.go:20-22,
internal/reconcile/networkpolicy.go:20-22, internal/reconcile/rbac.go:19-21,
internal/reconcile/rbac.go:44-46, internal/reconcile/rbac.go:75-77, and
internal/reconcile/rbac.go:88-90 to retain existing non-target references while
ensuring desired references; in internal/reconcile/configmaps_test.go:136-152,
assert that the additional owner reference with UID extra-uid remains after
reconciliation.

In `@internal/utils/ownership.go`:
- Around line 26-41: Preserve the subset-matching behavior of IsOwnedByDesired
and add or document a merge operation that combines desired owners with existing
references without duplicates. Update owner-reference assignments in
internal/reconcile/daemon_sets.go (20-22), service.go (20-22),
service_account.go (18-20), service_monitor.go (20-22), and
internal/collector/trust_bundle.go (27-34) to retain additional existing owners
while ensuring all desired references are present.

---

Nitpick comments:
In `@internal/reconcile/configmaps_test.go`:
- Around line 136-152: Strengthen the test around reconcile.Configmap by
asserting that the additional OwnerReference with UID "extra-uid" remains on the
resulting ConfigMap. Keep the existing success and data assertions, and verify
preservation using result.OwnerReferences.

In `@internal/utils/ownership_test.go`:
- Around line 34-55: Add a test in the ownership suite where the object has the
desired owner plus an additional non-controller OwnerReference, and verify
EnsureCanUpdateOwnedResource succeeds. Add a reconciler-level test or assertion
covering the update path, confirming the additional OwnerReference is preserved
after reconciliation.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9811bb02-6e6c-47d6-b218-e601542b75bc

📥 Commits

Reviewing files that changed from the base of the PR and between 757c63b and 4c7fa7c.

📒 Files selected for processing (14)
  • internal/collector/trust_bundle.go
  • internal/reconcile/configmaps.go
  • internal/reconcile/configmaps_test.go
  • internal/reconcile/daemon_sets.go
  • internal/reconcile/daemonset_ownership_test.go
  • internal/reconcile/deployment.go
  • internal/reconcile/networkpolicy.go
  • internal/reconcile/rbac.go
  • internal/reconcile/rbac_test.go
  • internal/reconcile/service.go
  • internal/reconcile/service_account.go
  • internal/reconcile/service_monitor.go
  • internal/utils/ownership.go
  • internal/utils/ownership_test.go

Comment on lines +30 to +31
if err := utils.EnsureCanUpdateOwnedResource(current, configMap.OwnerReferences); err != nil {
return err

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Keep unrelated OwnerReferences intact when the ownership guard allows a mutation.

The new contract explicitly allows a desired owner to coexist with additional OwnerReferences, but these reconciliation paths later replace the entire list with desired.OwnerReferences. That can remove another owner’s garbage-collection relationship. Preserve existing non-target references while ensuring desired references, and assert this behavior in the additional-owner test.

  • internal/reconcile/configmaps.go#L30-L31: preserve unrelated references when updating the ConfigMap.
  • internal/reconcile/configmaps_test.go#L136-L152: assert that extra-uid remains after reconciliation.
  • internal/reconcile/deployment.go#L20-L22: preserve unrelated Deployment references.
  • internal/reconcile/networkpolicy.go#L20-L22: preserve unrelated NetworkPolicy references.
  • internal/reconcile/rbac.go#L19-L21: preserve unrelated Role references.
  • internal/reconcile/rbac.go#L44-L46: preserve unrelated RoleBinding references.
  • internal/reconcile/rbac.go#L75-L77: preserve unrelated ClusterRoleBinding references before roleRef handling.
  • internal/reconcile/rbac.go#L88-L90: preserve unrelated ClusterRoleBinding references during update.
📍 Affects 5 files
  • internal/reconcile/configmaps.go#L30-L31 (this comment)
  • internal/reconcile/configmaps_test.go#L136-L152
  • internal/reconcile/deployment.go#L20-L22
  • internal/reconcile/networkpolicy.go#L20-L22
  • internal/reconcile/rbac.go#L19-L21
  • internal/reconcile/rbac.go#L44-L46
  • internal/reconcile/rbac.go#L75-L77
  • internal/reconcile/rbac.go#L88-L90
🤖 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 `@internal/reconcile/configmaps.go` around lines 30 - 31, Preserve unrelated
OwnerReferences whenever reconciliation updates an owned resource instead of
replacing the full list with desired.OwnerReferences: update
internal/reconcile/configmaps.go:30-31, internal/reconcile/deployment.go:20-22,
internal/reconcile/networkpolicy.go:20-22, internal/reconcile/rbac.go:19-21,
internal/reconcile/rbac.go:44-46, internal/reconcile/rbac.go:75-77, and
internal/reconcile/rbac.go:88-90 to retain existing non-target references while
ensuring desired references; in internal/reconcile/configmaps_test.go:136-152,
assert that the additional owner reference with UID extra-uid remains after
reconciliation.

Comment on lines +26 to +41
// IsOwnedByDesired reports whether every desired owner UID is present among current owners.
// An empty desired owner list only matches when current owners are also empty.
func IsOwnedByDesired(current, desired []metav1.OwnerReference) bool {
if len(desired) == 0 {
return len(current) == 0
}
currentUIDs := make(map[string]struct{}, len(current))
for _, ref := range current {
currentUIDs[string(ref.UID)] = struct{}{}
}
for _, want := range desired {
if _, ok := currentUIDs[string(want.UID)]; !ok {
return false
}
}
return true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Preserve additional owner references when shared ownership is accepted.

The ownership predicate allows current references to contain additional owners, but the reconcilers replace the complete list with only the desired references. This can remove another controller’s lifecycle/garbage-collection relationship.

  • internal/utils/ownership.go#L26-L41: retain the subset-matching contract and provide or document a merge operation for callers.
  • internal/reconcile/daemon_sets.go#L20-L22: preserve additional DaemonSet owner references.
  • internal/reconcile/service.go#L20-L22: preserve additional Service owner references.
  • internal/reconcile/service_account.go#L18-L20: preserve additional ServiceAccount owner references.
  • internal/reconcile/service_monitor.go#L20-L22: preserve additional ServiceMonitor owner references.
  • internal/collector/trust_bundle.go#L27-L34: preserve additional trusted-bundle ConfigMap owner references.
📍 Affects 6 files
  • internal/utils/ownership.go#L26-L41 (this comment)
  • internal/reconcile/daemon_sets.go#L20-L22
  • internal/reconcile/service.go#L20-L22
  • internal/reconcile/service_account.go#L18-L20
  • internal/reconcile/service_monitor.go#L20-L22
  • internal/collector/trust_bundle.go#L27-L34
🤖 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 `@internal/utils/ownership.go` around lines 26 - 41, Preserve the
subset-matching behavior of IsOwnedByDesired and add or document a merge
operation that combines desired owners with existing references without
duplicates. Update owner-reference assignments in
internal/reconcile/daemon_sets.go (20-22), service.go (20-22),
service_account.go (18-20), service_monitor.go (20-22), and
internal/collector/trust_bundle.go (27-34) to retain additional existing owners
while ensuring all desired references are present.

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

Labels

needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant