forked from kubernetes-sigs/aws-load-balancer-controller
/
finalizer.go
81 lines (71 loc) · 2.24 KB
/
finalizer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package k8s
import (
"context"
"github.com/go-logr/logr"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
type FinalizerManager interface {
AddFinalizers(ctx context.Context, object client.Object, finalizers ...string) error
RemoveFinalizers(ctx context.Context, object client.Object, finalizers ...string) error
}
func NewDefaultFinalizerManager(k8sClient client.Client, log logr.Logger) FinalizerManager {
return &defaultFinalizerManager{
k8sClient: k8sClient,
log: log,
}
}
type defaultFinalizerManager struct {
k8sClient client.Client
log logr.Logger
}
func (m *defaultFinalizerManager) AddFinalizers(ctx context.Context, obj client.Object, finalizers ...string) error {
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
if err := m.k8sClient.Get(ctx, NamespacedName(obj), obj); err != nil {
return err
}
oldObj := obj.DeepCopyObject().(client.Object)
needsUpdate := false
for _, finalizer := range finalizers {
if !HasFinalizer(obj, finalizer) {
controllerutil.AddFinalizer(obj, finalizer)
needsUpdate = true
}
}
if !needsUpdate {
return nil
}
return m.k8sClient.Patch(ctx, obj, client.MergeFromWithOptions(oldObj, client.MergeFromWithOptimisticLock{}))
})
}
func (m *defaultFinalizerManager) RemoveFinalizers(ctx context.Context, obj client.Object, finalizers ...string) error {
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
if err := m.k8sClient.Get(ctx, NamespacedName(obj), obj); err != nil {
return err
}
oldObj := obj.DeepCopyObject().(client.Object)
needsUpdate := false
for _, finalizer := range finalizers {
if HasFinalizer(obj, finalizer) {
controllerutil.RemoveFinalizer(obj, finalizer)
needsUpdate = true
}
}
if !needsUpdate {
return nil
}
return m.k8sClient.Patch(ctx, obj, client.MergeFromWithOptions(oldObj, client.MergeFromWithOptimisticLock{}))
})
}
// HasFinalizer tests whether k8s object has specified finalizer
func HasFinalizer(obj metav1.Object, finalizer string) bool {
f := obj.GetFinalizers()
for _, e := range f {
if e == finalizer {
return true
}
}
return false
}