Skip to content

Commit a100c1b

Browse files
committed
✨ implement helpers for add/remove finalizer
1 parent dd6ead6 commit a100c1b

File tree

3 files changed

+92
-2
lines changed

3 files changed

+92
-2
lines changed

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ require (
3232
go.uber.org/zap v1.9.1
3333
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac // indirect
3434
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be // indirect
35-
golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect
3635
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect
3736
gomodules.xyz/jsonpatch/v2 v2.0.1
3837
google.golang.org/appengine v1.1.0 // indirect
@@ -44,7 +43,7 @@ require (
4443
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
4544
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
4645
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c // indirect
47-
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 // indirect
46+
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5
4847
sigs.k8s.io/testing_frameworks v0.1.1
4948
sigs.k8s.io/yaml v1.1.0
5049
)

pkg/controller/controllerutil/controllerutil.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ 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"
29+
"k8s.io/apimachinery/pkg/util/sets"
2830
"sigs.k8s.io/controller-runtime/pkg/client"
2931
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
3032
)
@@ -168,3 +170,39 @@ func mutate(f MutateFn, key client.ObjectKey, obj runtime.Object) error {
168170

169171
// MutateFn is a function which mutates the existing object into it's desired state.
170172
type MutateFn func() error
173+
174+
// AddFinalizer accepts a metav1 object and adds the provided finalizer if not present.
175+
func AddFinalizer(o metav1.Object, finalizer string) {
176+
finalizers := sets.NewString(o.GetFinalizers()...)
177+
finalizers.Insert(finalizer)
178+
o.SetFinalizers(finalizers.List())
179+
}
180+
181+
// AddFinalizerIfPossible tries to convert a runtime object to a metav1 object and add the provided finalizer.
182+
// It returns an error if the provided object cannot provide an accessor.
183+
func AddFinalizerIfPossible(o runtime.Object, finalizer string) error {
184+
m, err := meta.Accessor(o)
185+
if err != nil {
186+
return err
187+
}
188+
AddFinalizer(m, finalizer)
189+
return nil
190+
}
191+
192+
// RemoveFinalizer accepts a metav1 object and removes the provided finalizer if present.
193+
func RemoveFinalizer(o metav1.Object, finalizer string) {
194+
finalizers := sets.NewString(o.GetFinalizers()...)
195+
finalizers.Delete(finalizer)
196+
o.SetFinalizers(finalizers.List())
197+
}
198+
199+
// RemoveFinalizerIfPossible tries to convert a runtime object to a metav1 object and remove the provided finalizer.
200+
// It returns an error if the provided object cannot provide an accessor.
201+
func RemoveFinalizerIfPossible(o runtime.Object, finalizer string) error {
202+
m, err := meta.Accessor(o)
203+
if err != nil {
204+
return err
205+
}
206+
RemoveFinalizer(m, finalizer)
207+
return nil
208+
}

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("AddFinalizeIfPossible", func() {
274+
It("should return an error if object can't provide accessor", func() {
275+
Expect(controllerutil.AddFinalizerIfPossible(obj, testFinalizer)).To(HaveOccurred())
276+
})
277+
})
278+
279+
Describe("RemoveFinalizeIfPossible", func() {
280+
It("should return an error if object can't provide accessor", func() {
281+
Expect(controllerutil.RemoveFinalizerIfPossible(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)