Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌱 Add function RemoveControllerReference and HasControllerReference #2509

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions pkg/controller/controllerutil/controllerutil.go
Expand Up @@ -152,6 +152,28 @@ func RemoveOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) e
return nil
}

// HasControllerReference returns true if the object
// has an owner ref with controller equal to true
func HasControllerReference(object metav1.Object) bool {
owners := object.GetOwnerReferences()
for _, owner := range owners {
isTrue := owner.Controller
if owner.Controller != nil && *isTrue {
return true
}
}
return false
}

// RemoveControllerReference removes an owner reference where the controller
// equals true
func RemoveControllerReference(owner, object metav1.Object, scheme *runtime.Scheme) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@troy0820 Sorry for the late review :).

I'm not sure if this func works as intended. It first checks if there is a controller ownerRef on the object and then it removes the passed in owner. It doesn't check that the passed in owner is actually the controller (which I think is the goal of this func)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now looking at it, I’m not sure how I missed that. I’ll update the func to look if the owner is the controlled and remove that reference, otherwise it misses the goal as you said.

I’ll create an issue and assign it to me.

if ok := HasControllerReference(object); !ok {
return fmt.Errorf("%T does not have a owner reference with controller equals true", object)
}
return RemoveOwnerReference(owner, object, scheme)
}

func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) {
owners := object.GetOwnerReferences()
if idx := indexOwnerRef(owners, ref); idx == -1 {
Expand Down
45 changes: 45 additions & 0 deletions pkg/controller/controllerutil/controllerutil_test.go
Expand Up @@ -195,6 +195,51 @@ var _ = Describe("Controllerutil", func() {
Expect(controllerutil.RemoveOwnerReference(dep2, rs, scheme.Scheme)).To(HaveOccurred())
Expect(rs.GetOwnerReferences()).To(HaveLen(1))
})

It("should return true when HasControllerReference evaluates owner reference set by SetControllerReference", func() {
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}
Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(controllerutil.HasControllerReference(rs)).To(BeTrue())
})

It("should return false when HasControllerReference evaluates owner reference set by SetOwnerReference", 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.HasControllerReference(rs)).To(BeFalse())
})

It("should error when RemoveControllerReference owner's controller is set to false", 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.RemoveControllerReference(dep, rs, scheme.Scheme)).To(HaveOccurred())
})

It("should not error when RemoveControllerReference owner's controller is set to true", func() {
rs := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{},
}
dep := &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"},
}
Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(controllerutil.RemoveControllerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred())
Expect(rs.GetOwnerReferences()).To(BeEmpty())
})
})

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