fix: add do-not-delete finalizer to signal the finalizer shouldn't be removed manually#2574
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
How to use the Graphite Merge QueueAdd the label main-merge-queue to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
Claude finished @assafgi's task in 2m 8s —— View job Claude PR Review
SummaryThe intent — adding a second, human-readable guard finalizer alongside Findings (see inline comments for details and suggested fixes):
Non-issues I looked at: the Overall: nice idea, low-risk diff, but please address #1 before merge — otherwise the guard won't be doing its job on the fleet that actually needs protecting. · Branch: |
Graphite Automations"Add anton/matt/sergey/kristina as reviwers on operator PRs" took an action on this PR • (05/31/26)2 reviewers were added to this PR based on Anton Bykov's automation. |
| logger.Info("Adding Finalizer for weka client") | ||
| controllerutil.AddFinalizer(c.wekaClient, consts.DeletionProtectionFinalizer) | ||
| if ok := controllerutil.AddFinalizer(c.wekaClient, consts.WekaFinalizer); !ok { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Bug: guard finalizer is not persisted on existing resources.
AddFinalizer returns false when the finalizer is already present. So for a WekaClient created before this PR (which has WekaFinalizer but no DeletionProtectionFinalizer), the flow is:
AddFinalizer(DeletionProtectionFinalizer)— mutates the in-memory object.AddFinalizer(WekaFinalizer)returnsfalse→ earlyreturn nil.Update()is never called → the guard addition is lost.
This means rollout to existing clusters won't backfill the protection finalizer; only freshly created WekaClient resources will get it.
Suggest tracking whether either call mutated the object and only short-circuiting when neither did:
| logger.Info("Adding Finalizer for weka client") | |
| controllerutil.AddFinalizer(c.wekaClient, consts.DeletionProtectionFinalizer) | |
| if ok := controllerutil.AddFinalizer(c.wekaClient, consts.WekaFinalizer); !ok { | |
| return nil | |
| } | |
| logger.Info("Adding Finalizer for weka client") | |
| addedGuard := controllerutil.AddFinalizer(c.wekaClient, consts.DeletionProtectionFinalizer) | |
| addedWeka := controllerutil.AddFinalizer(c.wekaClient, consts.WekaFinalizer) | |
| if !addedGuard && !addedWeka { | |
| return nil | |
| } |
| controllerutil.AddFinalizer(container, consts.DeletionProtectionFinalizer) | ||
| if ok := controllerutil.AddFinalizer(container, consts.WekaFinalizer); !ok { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Same bug as in wekaclient: if WekaFinalizer is already present, AddFinalizer returns false, the function returns early, and the DeletionProtectionFinalizer addition is never Update()'d. Existing WekaContainer resources will not be backfilled with the guard finalizer.
| controllerutil.AddFinalizer(container, consts.DeletionProtectionFinalizer) | |
| if ok := controllerutil.AddFinalizer(container, consts.WekaFinalizer); !ok { | |
| return nil | |
| } | |
| addedGuard := controllerutil.AddFinalizer(container, consts.DeletionProtectionFinalizer) | |
| addedWeka := controllerutil.AddFinalizer(container, consts.WekaFinalizer) | |
| if !addedGuard && !addedWeka { | |
| return nil | |
| } |
| // DeletionProtectionFinalizer is a guard finalizer with a clear name to prevent | ||
| // accidental deletion by automation or AI agents. It is added alongside WekaFinalizer | ||
| // and removed only during intentional operator-driven deletion flows. | ||
| DeletionProtectionFinalizer = "do-not-delete.protection.io/guard" |
There was a problem hiding this comment.
Nit (naming): every other finalizer/annotation/resource constant in this file uses the weka.io domain that the project owns (e.g. weka.weka.io/finalizer, weka.io/weka-drives). protection.io is a generic, unowned domain and breaks that convention.
Suggest something like do-not-delete.weka.io/guard so the "do-not-delete" semantic signal is preserved while staying within a domain you control.
There was a problem hiding this comment.
Pull request overview
This PR adds a second Kubernetes finalizer intended to act as a deletion-protection guard alongside the existing Weka finalizer, and updates WekaContainer, WekaCluster, and WekaClient deletion paths to remove it during operator-managed cleanup.
Changes:
- Adds
DeletionProtectionFinalizerininternal/consts. - Adds the new finalizer during active/init reconciliation for Weka resources.
- Removes the new finalizer during deletion handling.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
internal/consts/consts.go |
Defines the new deletion-protection finalizer constant. |
internal/controllers/wekacontainer/funcs_active_state_init.go |
Adds the protection finalizer during container finalizer reconciliation. |
internal/controllers/wekacontainer/funcs_common_deletion.go |
Removes the protection finalizer during container deletion. |
internal/controllers/wekacluster/steps_cluster_creation.go |
Adds the protection finalizer during cluster initialization. |
internal/controllers/wekacluster/steps_deletion.go |
Removes the protection finalizer during cluster deletion. |
internal/controllers/wekaclient/client_reconciler_loop.go |
Adds/removes the protection finalizer for WekaClient resources. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| controllerutil.AddFinalizer(container, consts.DeletionProtectionFinalizer) | ||
| if ok := controllerutil.AddFinalizer(container, consts.WekaFinalizer); !ok { | ||
| return nil |
| controllerutil.AddFinalizer(wekaCluster, consts.DeletionProtectionFinalizer) | ||
| if updated := controllerutil.AddFinalizer(wekaCluster, consts.WekaFinalizer); updated { |
| controllerutil.AddFinalizer(c.wekaClient, consts.DeletionProtectionFinalizer) | ||
| if ok := controllerutil.AddFinalizer(c.wekaClient, consts.WekaFinalizer); !ok { | ||
| return nil |
| // DeletionProtectionFinalizer is a guard finalizer with a clear name to prevent | ||
| // accidental deletion by automation or AI agents. It is added alongside WekaFinalizer | ||
| // and removed only during intentional operator-driven deletion flows. | ||
| DeletionProtectionFinalizer = "do-not-delete.protection.io/guard" |
… removed manually
f21ffdb to
5293e20
Compare
|
Claude finished @assafgi's task in 37s —— View job Claude PR Review
Status: no new changes since prior reviewThe current PR head is still commit Summary (unchanged)The intent — adding a second, human-readable guard finalizer alongside Findings (see inline comments on the prior review for details and suggested fixes):
Issue #1 is the main blocker — please address before merge. --- · Branch: |

No description provided.