Skip to content

Commit e7e24af

Browse files
committed
✨ implement helpers for add/remove finalizer
1 parent 4ba0a3b commit e7e24af

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

pkg/controller/controllerutil/controllerutil.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"reflect"
2323

2424
"k8s.io/apimachinery/pkg/api/errors"
25+
"k8s.io/apimachinery/pkg/api/meta"
2526
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2627
"k8s.io/apimachinery/pkg/runtime"
2728
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -168,3 +169,47 @@ func mutate(f MutateFn, key client.ObjectKey, obj runtime.Object) error {
168169

169170
// MutateFn is a function which mutates the existing object into it's desired state.
170171
type MutateFn func() error
172+
173+
// AddFinalizer accepts a metav1 object and adds the provided finalizer if not present.
174+
func AddFinalizer(o metav1.Object, finalizer string) {
175+
f := o.GetFinalizers()
176+
for _, e := range f {
177+
if e == finalizer {
178+
return
179+
}
180+
}
181+
o.SetFinalizers(append(f, finalizer))
182+
}
183+
184+
// AddFinalizerWithError tries to convert a runtime object to a metav1 object and add the provided finalizer.
185+
// It returns an error if the provided object cannot provide an accessor.
186+
func AddFinalizerWithError(o runtime.Object, finalizer string) error {
187+
m, err := meta.Accessor(o)
188+
if err != nil {
189+
return err
190+
}
191+
AddFinalizer(m, finalizer)
192+
return nil
193+
}
194+
195+
// RemoveFinalizer accepts a metav1 object and removes the provided finalizer if present.
196+
func RemoveFinalizer(o metav1.Object, finalizer string) {
197+
f := o.GetFinalizers()
198+
for i, e := range f {
199+
if e == finalizer {
200+
f = append(f[:i], f[i+1:]...)
201+
}
202+
}
203+
o.SetFinalizers(f)
204+
}
205+
206+
// RemoveFinalizerWithError tries to convert a runtime object to a metav1 object and remove the provided finalizer.
207+
// It returns an error if the provided object cannot provide an accessor.
208+
func RemoveFinalizerWithError(o runtime.Object, finalizer string) error {
209+
m, err := meta.Accessor(o)
210+
if err != nil {
211+
return err
212+
}
213+
RemoveFinalizer(m, finalizer)
214+
return nil
215+
}

pkg/controller/controllerutil/controllerutil_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,63 @@ var _ = Describe("Controllerutil", func() {
265265
Expect(err).To(HaveOccurred())
266266
})
267267
})
268+
269+
Describe("Finalizers", func() {
270+
var obj runtime.Object = &errRuntimeObj{}
271+
var deploy *appsv1.Deployment
272+
273+
Describe("AddFinalizerWithError", func() {
274+
It("should return an error if object can't provide accessor", func() {
275+
Expect(controllerutil.AddFinalizerWithError(obj, testFinalizer)).To(HaveOccurred())
276+
})
277+
})
278+
279+
Describe("RemoveFinalizerWithError", func() {
280+
It("should return an error if object can't provide accessor", func() {
281+
Expect(controllerutil.RemoveFinalizerWithError(obj, testFinalizer)).To(HaveOccurred())
282+
})
283+
})
284+
285+
Describe("AddFinalizer", func() {
286+
deploy = &appsv1.Deployment{
287+
ObjectMeta: metav1.ObjectMeta{
288+
Finalizers: []string{},
289+
},
290+
}
291+
292+
It("should add the finalizer when not present", func() {
293+
controllerutil.AddFinalizer(deploy, testFinalizer)
294+
Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer}))
295+
})
296+
297+
It("should not add the finalizer when already present", func() {
298+
controllerutil.AddFinalizer(deploy, testFinalizer)
299+
Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer}))
300+
})
301+
})
302+
303+
Describe("RemoveFinalizer", func() {
304+
It("should remove finalizer if present", func() {
305+
controllerutil.RemoveFinalizer(deploy, testFinalizer)
306+
Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{}))
307+
})
308+
})
309+
})
268310
})
269311

312+
const testFinalizer = "foo.bar.baz"
313+
314+
var _ runtime.Object = &errRuntimeObj{}
270315
var _ metav1.Object = &errMetaObj{}
271316

317+
type errRuntimeObj struct {
318+
runtime.TypeMeta
319+
}
320+
321+
func (o *errRuntimeObj) DeepCopyObject() runtime.Object {
322+
return &errRuntimeObj{}
323+
}
324+
272325
type errMetaObj struct {
273326
metav1.ObjectMeta
274327
}

0 commit comments

Comments
 (0)