Skip to content

Commit

Permalink
create RemoveOwnerReference function in controllerutil
Browse files Browse the repository at this point in the history
Signed-off-by: Troy Connor <troy0820@users.noreply.github.com>
  • Loading branch information
troy0820 committed Sep 12, 2023
1 parent aa9f8c9 commit 36ecb53
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
31 changes: 31 additions & 0 deletions pkg/controller/controllerutil/controllerutil.go
Expand Up @@ -121,6 +121,37 @@ func SetOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) erro
return nil
}

// RemoveOwnerReference is a helper method to make sure the given object removes an owner reference to the object provided.
// This allows you to remove the owner to establish a new owner of the object in a subsequent call.
func RemoveOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) error {
owners := object.GetOwnerReferences()
length := len(owners)
if length < 1 {
return fmt.Errorf("%T does not have any owner references", object)
}
ro, ok := owner.(runtime.Object)
if !ok {
return fmt.Errorf("%T is not a runtime.Object, cannot call RemoveOwnerReference", owner)
}
gvk, err := apiutil.GVKForObject(ro, scheme)
if err != nil {
return err
}

index := indexOwnerRef(owners, metav1.OwnerReference{
APIVersion: gvk.GroupVersion().String(),
Name: owner.GetName(),
Kind: gvk.Kind,
})
if index == -1 {
return fmt.Errorf("%T does not have an owner reference for %T", object, owner)
}

owners = append(owners[:index], owners[index+1:]...)
object.SetOwnerReferences(owners)
return nil
}

func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) {
owners := object.GetOwnerReferences()
if idx := indexOwnerRef(owners, ref); idx == -1 {
Expand Down
93 changes: 93 additions & 0 deletions pkg/controller/controllerutil/controllerutil_test.go
Expand Up @@ -102,6 +102,99 @@ var _ = Describe("Controllerutil", func() {
UID: "foo-uid-2",
}))
})
It("should remove the owner reference", func() {
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
OwnerReferences: []metav1.OwnerReference{
{
Name: "foo",
Kind: "Deployment",
APIVersion: "extensions/v1alpha1",
UID: "foo-uid-1",
},
},
},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}

Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{
Name: "foo",
Kind: "Deployment",
APIVersion: "extensions/v1beta1",
UID: "foo-uid-2",
}))
Expect(controllerutil.RemoveOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(len(rs.GetOwnerReferences())).To(Equal(0))

Check failure on line 130 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(BeEmpty())` instead (ginkgolinter)

Check failure on line 130 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(BeEmpty())` instead (ginkgolinter)
})
It("should remove the owner reference established by the SetControllerReference function", func() {
rs := &appsv1.ReplicaSet{}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid"},
}

Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred())
t := true
Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{
Name: "foo",
Kind: "Deployment",
APIVersion: "extensions/v1beta1",
UID: "foo-uid",
Controller: &t,
BlockOwnerDeletion: &t,
}))
Expect(controllerutil.RemoveOwnerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred())
Expect(rs.GetOwnerReferences()).To(HaveLen(0))

Check failure on line 149 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(BeEmpty())` instead (ginkgolinter)

Check failure on line 149 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(BeEmpty())` instead (ginkgolinter)
})
It("should error when trying to remove the reference that doesn't exist", func() {
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}
Expect(controllerutil.RemoveOwnerReference(dep, rs, scheme.Scheme)).To(HaveOccurred())
Expect(len(rs.GetOwnerReferences())).To(Equal(0))

Check failure on line 159 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(BeEmpty())` instead (ginkgolinter)

Check failure on line 159 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(BeEmpty())` instead (ginkgolinter)
})
It("should error when trying to remove the reference that doesn't abide by the scheme", func() {
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(controllerutil.RemoveOwnerReference(dep, rs, runtime.NewScheme())).To(HaveOccurred())
Expect(len(rs.GetOwnerReferences())).To(Equal(1))

Check failure on line 170 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(HaveLen(1))` instead (ginkgolinter)

Check failure on line 170 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(HaveLen(1))` instead (ginkgolinter)
})
It("should error when trying to remove the owner when setting the owner as a non runtime.Object", func() {
var obj metav1.Object
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(controllerutil.RemoveOwnerReference(obj, rs, scheme.Scheme)).To(HaveOccurred())
Expect(len(rs.GetOwnerReferences())).To(Equal(1))

Check failure on line 182 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(HaveLen(1))` instead (ginkgolinter)

Check failure on line 182 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(HaveLen(1))` instead (ginkgolinter)
})
It("should error when trying to remove an owner that doesn't exist", func() {
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}
dep2 := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "bar", UID: "bar-uid-3"},
}
Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(controllerutil.RemoveOwnerReference(dep2, rs, scheme.Scheme)).To(HaveOccurred())
Expect(len(rs.GetOwnerReferences())).To(Equal(1))

Check failure on line 196 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(HaveLen(1))` instead (ginkgolinter)

Check failure on line 196 in pkg/controller/controllerutil/controllerutil_test.go

View workflow job for this annotation

GitHub Actions / lint

ginkgo-linter: wrong length assertion; consider using `Expect(rs.GetOwnerReferences()).To(HaveLen(1))` instead (ginkgolinter)
})
})

Describe("SetControllerReference", func() {
Expand Down

0 comments on commit 36ecb53

Please sign in to comment.