...
1
13
14 package finalizer
15
16 import (
17 "context"
18 "fmt"
19
20 kerrors "k8s.io/apimachinery/pkg/util/errors"
21 "sigs.k8s.io/controller-runtime/pkg/client"
22 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
23 )
24
25 type finalizers map[string]Finalizer
26
27
28 type Result struct {
29
30
31 Updated bool
32
33
34 StatusUpdated bool
35 }
36
37
38 func NewFinalizers() Finalizers {
39 return finalizers{}
40 }
41
42 func (f finalizers) Register(key string, finalizer Finalizer) error {
43 if _, ok := f[key]; ok {
44 return fmt.Errorf("finalizer for key %q already registered", key)
45 }
46 f[key] = finalizer
47 return nil
48 }
49
50 func (f finalizers) Finalize(ctx context.Context, obj client.Object) (Result, error) {
51 var (
52 res Result
53 errList []error
54 )
55 res.Updated = false
56 for key, finalizer := range f {
57 if dt := obj.GetDeletionTimestamp(); dt.IsZero() && !controllerutil.ContainsFinalizer(obj, key) {
58 controllerutil.AddFinalizer(obj, key)
59 res.Updated = true
60 } else if !dt.IsZero() && controllerutil.ContainsFinalizer(obj, key) {
61 finalizerRes, err := finalizer.Finalize(ctx, obj)
62 if err != nil {
63
64
65 res.Updated = res.Updated || finalizerRes.Updated
66 res.StatusUpdated = res.StatusUpdated || finalizerRes.StatusUpdated
67 errList = append(errList, fmt.Errorf("finalizer %q failed: %w", key, err))
68 } else {
69
70
71 res.Updated = true
72 controllerutil.RemoveFinalizer(obj, key)
73
74 res.StatusUpdated = res.StatusUpdated || finalizerRes.StatusUpdated
75 }
76 }
77 }
78 return res, kerrors.NewAggregate(errList)
79 }
80
View as plain text