Skip to content

Commit 1149aa0

Browse files
committed
create RemoveOwnerReference function in controllerutil
Signed-off-by: Troy Connor <[email protected]>
1 parent aa9f8c9 commit 1149aa0

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

pkg/controller/controllerutil/controllerutil.go

+31
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,37 @@ func SetOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) erro
121121
return nil
122122
}
123123

124+
// RemoveOwnerReference is a helper method to make sure the given object removes an owner reference to the object provided.
125+
// This allows you to remove the owner to establish a new owner of the object in a subsequent call.
126+
func RemoveOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) error {
127+
owners := object.GetOwnerReferences()
128+
length := len(owners)
129+
if length < 1 {
130+
return fmt.Errorf("%T does not have any owner references", object)
131+
}
132+
ro, ok := owner.(runtime.Object)
133+
if !ok {
134+
return fmt.Errorf("%T is not a runtime.Object, cannot call RemoveOwnerReference", owner)
135+
}
136+
gvk, err := apiutil.GVKForObject(ro, scheme)
137+
if err != nil {
138+
return err
139+
}
140+
141+
index := indexOwnerRef(owners, metav1.OwnerReference{
142+
APIVersion: gvk.GroupVersion().String(),
143+
Name: owner.GetName(),
144+
Kind: gvk.Kind,
145+
})
146+
if index == -1 {
147+
return fmt.Errorf("%T does not have an owner reference for %T", object, owner)
148+
}
149+
150+
owners = append(owners[:index], owners[index+1:]...)
151+
object.SetOwnerReferences(owners)
152+
return nil
153+
}
154+
124155
func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) {
125156
owners := object.GetOwnerReferences()
126157
if idx := indexOwnerRef(owners, ref); idx == -1 {

pkg/controller/controllerutil/controllerutil_test.go

+74
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,80 @@ var _ = Describe("Controllerutil", func() {
102102
UID: "foo-uid-2",
103103
}))
104104
})
105+
It("should remove the owner reference", func() {
106+
rs := &appsv1.ReplicaSet{
107+
ObjectMeta: metav1.ObjectMeta{
108+
OwnerReferences: []metav1.OwnerReference{
109+
{
110+
Name: "foo",
111+
Kind: "Deployment",
112+
APIVersion: "extensions/v1alpha1",
113+
UID: "foo-uid-1",
114+
},
115+
},
116+
},
117+
}
118+
dep := &extensionsv1beta1.Deployment{
119+
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
120+
}
121+
122+
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
123+
Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{
124+
Name: "foo",
125+
Kind: "Deployment",
126+
APIVersion: "extensions/v1beta1",
127+
UID: "foo-uid-2",
128+
}))
129+
Expect(controllerutil.RemoveOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
130+
Expect(rs.GetOwnerReferences()).To(BeEmpty())
131+
})
132+
It("should error when trying to remove the reference that doesn't exist", func() {
133+
rs := &appsv1.ReplicaSet{
134+
ObjectMeta: metav1.ObjectMeta{},
135+
}
136+
dep := &extensionsv1beta1.Deployment{
137+
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
138+
}
139+
Expect(controllerutil.RemoveOwnerReference(dep, rs, scheme.Scheme)).To(HaveOccurred())
140+
Expect(rs.GetOwnerReferences()).To(BeEmpty())
141+
})
142+
It("should error when trying to remove the reference that doesn't abide by the scheme", func() {
143+
rs := &appsv1.ReplicaSet{
144+
ObjectMeta: metav1.ObjectMeta{},
145+
}
146+
dep := &extensionsv1beta1.Deployment{
147+
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
148+
}
149+
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
150+
Expect(controllerutil.RemoveOwnerReference(dep, rs, runtime.NewScheme())).To(HaveOccurred())
151+
Expect(rs.GetOwnerReferences()).To(HaveLen(1))
152+
})
153+
It("should error when trying to remove the owner when setting the owner as a non runtime.Object", func() {
154+
var obj metav1.Object
155+
rs := &appsv1.ReplicaSet{
156+
ObjectMeta: metav1.ObjectMeta{},
157+
}
158+
dep := &extensionsv1beta1.Deployment{
159+
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
160+
}
161+
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
162+
Expect(controllerutil.RemoveOwnerReference(obj, rs, scheme.Scheme)).To(HaveOccurred())
163+
Expect(rs.GetOwnerReferences()).To(HaveLen(1))
164+
})
165+
It("should error when trying to remove an owner that doesn't exist", func() {
166+
rs := &appsv1.ReplicaSet{
167+
ObjectMeta: metav1.ObjectMeta{},
168+
}
169+
dep := &extensionsv1beta1.Deployment{
170+
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
171+
}
172+
dep2 := &extensionsv1beta1.Deployment{
173+
ObjectMeta: metav1.ObjectMeta{Name: "bar", UID: "bar-uid-3"},
174+
}
175+
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
176+
Expect(controllerutil.RemoveOwnerReference(dep2, rs, scheme.Scheme)).To(HaveOccurred())
177+
Expect(rs.GetOwnerReferences()).To(HaveLen(1))
178+
})
105179
})
106180

107181
Describe("SetControllerReference", func() {

0 commit comments

Comments
 (0)