Skip to content

Commit 24d42ee

Browse files
committed
fixup! Use Patch instead of Update for finalizer operations
Signed-off-by: Todd Short <[email protected]>
1 parent 87224a7 commit 24d42ee

File tree

2 files changed

+443
-30
lines changed

2 files changed

+443
-30
lines changed

internal/shared/util/finalizer/finalizer.go

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,26 @@ package finalizer
1818

1919
import (
2020
"context"
21+
"encoding/json"
2122
"fmt"
2223
"slices"
2324
"sort"
2425
"strings"
2526

26-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
27+
"k8s.io/apimachinery/pkg/types"
2728
"sigs.k8s.io/controller-runtime/pkg/client"
28-
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
2929
)
3030

3131
const (
3232
FinalizerPrefix = "olm.operatorframework.io/"
3333
)
3434

35-
// EnsureFinalizers sets the finalizers on an object to exactly the provided list using server-side apply.
36-
// If no finalizers are supplied, all finalizers will be removed from the object.
37-
// If one finalizer is supplied, all other finalizers will be removed and only the supplied one will remain.
35+
// EnsureFinalizers sets the FinalizerPrefix finalizers an object using Patch (vs. Update)
36+
// If no finalizers are supplied, all FinalizerPrefix finalizers will be removed from the object.
37+
// If any finalizers are supplied, all other FinalizerPrefix finalizers will be removed and only the supplied ones will remain.
3838
// Returns (true, nil) if the finalizers were changed, (false, nil) if they were already set to the desired value.
3939
// Note: This function will update the passed object with the server response.
4040
func EnsureFinalizers(ctx context.Context, owner string, c client.Client, obj client.Object, finalizers ...string) (bool, error) {
41-
// Sort the desired finalizers for consistent ordering
4241
newFinalizers := slices.Clone(finalizers)
4342
if newFinalizers == nil {
4443
newFinalizers = []string{}
@@ -49,47 +48,45 @@ func EnsureFinalizers(ctx context.Context, owner string, c client.Client, obj cl
4948
panic(fmt.Sprintf("finalizer does not have %q prefix: %q", FinalizerPrefix, s))
5049
}
5150
}
52-
sort.Strings(newFinalizers)
5351

54-
// Check if the current finalizers already match the desired state
55-
// Remove any non-"olm.operatorframework.io" finalizers (ones we don't manage) from the list
52+
// Add any other, non-FinalizerPrefix, finalizers to the newFinalizer list
5653
currentFinalizers := obj.GetFinalizers()
54+
for _, f := range currentFinalizers {
55+
if !strings.HasPrefix(f, FinalizerPrefix) {
56+
newFinalizers = append(newFinalizers, f)
57+
}
58+
}
59+
// Sort the desired finalizers for consistent ordering
60+
sort.Strings(newFinalizers)
61+
62+
// Check if the current finalizers already match the desired state (newFinalizers)
5763
currentSorted := slices.Clone(currentFinalizers)
58-
currentSorted = slices.DeleteFunc(currentSorted, func(f string) bool {
59-
return !strings.HasPrefix(f, FinalizerPrefix)
60-
})
6164
if currentSorted == nil {
6265
currentSorted = []string{}
6366
}
6467
sort.Strings(currentSorted)
6568

66-
// With only "olm.operatorframework.io" finalizers, other controller's finalizers
67-
// won't interfere in this check
69+
// Compare the current list with the desired newFinalizers
6870
if slices.Equal(currentSorted, newFinalizers) {
6971
return false, nil
7072
}
7173

72-
// Get the GVK for this object type
73-
gvk, err := apiutil.GVKForObject(obj, c.Scheme())
74-
if err != nil {
75-
return false, fmt.Errorf("getting object kind: %w", err)
74+
patch := map[string]any{
75+
"metadata": map[string]any{
76+
"resourceVersion": obj.GetResourceVersion(),
77+
"finalizers": newFinalizers,
78+
},
7679
}
7780

78-
// Create an unstructured object for server-side apply
79-
u := &unstructured.Unstructured{}
80-
u.SetGroupVersionKind(gvk)
81-
u.SetName(obj.GetName())
82-
u.SetNamespace(obj.GetNamespace())
83-
u.SetFinalizers(newFinalizers)
81+
patchJSON, err := json.Marshal(patch)
82+
if err != nil {
83+
return false, fmt.Errorf("marshalling patch to ensure finalizers: %w", err)
84+
}
8485

85-
// Use server-side apply to update finalizers
86-
if err := c.Patch(ctx, u, client.Apply, client.ForceOwnership, client.FieldOwner(owner)); err != nil {
86+
// Use patch to update finalizers
87+
if err := c.Patch(ctx, obj, client.RawPatch(types.MergePatchType, patchJSON)); err != nil {
8788
return false, fmt.Errorf("updating finalizers: %w", err)
8889
}
8990

90-
// Update the passed object with the new finalizers
91-
obj.SetFinalizers(u.GetFinalizers())
92-
obj.SetResourceVersion(u.GetResourceVersion())
93-
9491
return true, nil
9592
}

0 commit comments

Comments
 (0)