Skip to content

Commit a6b5f64

Browse files
authored
fix(refmanager): adopt() should update child not parent object (#89)
1 parent 227926e commit a6b5f64

3 files changed

Lines changed: 70 additions & 31 deletions

File tree

controller/refmanager/ref_manager_test.go

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222

2323
"github.com/samber/lo"
24+
corev1 "k8s.io/api/core/v1"
2425
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2526
"k8s.io/utils/ptr"
2627
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -250,7 +251,7 @@ func (s *ownerReferenceTestSute) TestClaimWhenCanAdoptFailed() {
250251
func (s *ownerReferenceTestSute) TestClaimAllOf() {
251252
writer := NewOwnerRefWriter(s.client)
252253
match, err := LabelSelectorAsMatch(s.owner.Spec.Selector)
253-
s.NoError(err)
254+
s.Require().NoError(err)
254255
m := NewObjectControllerRefManager(writer, s.owner, s.ownerGVK, match)
255256

256257
adopted := []metav1.Object{
@@ -273,15 +274,43 @@ func (s *ownerReferenceTestSute) TestClaimAllOf() {
273274
allObjects = append(allObjects, released...)
274275
allObjects = append(allObjects, noChanged...)
275276

277+
for _, obj := range allObjects {
278+
err := s.client.Create(context.TODO(), obj.(client.Object))
279+
s.Require().NoError(err)
280+
}
281+
276282
result, err := m.ClaimAllOf(context.Background(), allObjects)
277-
if s.NoError(err) {
278-
s.Len(result, len(adopted))
279-
resultNames := lo.Map(result, func(o metav1.Object, _ int) string {
280-
return o.GetName()
281-
})
282-
adoptedNames := lo.Map(adopted, func(o metav1.Object, _ int) string {
283-
return o.GetName()
284-
})
285-
s.EqualValues(adoptedNames, resultNames)
283+
s.Require().NoError(err)
284+
// check adopted objects
285+
s.Len(result, len(adopted))
286+
resultNames := lo.Map(result, func(o metav1.Object, _ int) string {
287+
return o.GetName()
288+
})
289+
adoptedNames := lo.Map(adopted, func(o metav1.Object, _ int) string {
290+
return o.GetName()
291+
})
292+
s.EqualValues(adoptedNames, resultNames)
293+
294+
forEarch := func(objs []metav1.Object, check func(ownerRef *metav1.OwnerReference)) {
295+
for _, obj := range objs {
296+
pod := &corev1.Pod{}
297+
err := s.client.Get(context.Background(), client.ObjectKeyFromObject(obj.(client.Object)), pod)
298+
s.Require().NoError(err)
299+
ownerRef := metav1.GetControllerOf(pod)
300+
check(ownerRef)
301+
}
286302
}
303+
304+
// check adopted object owners
305+
forEarch(adopted, func(ownerRef *metav1.OwnerReference) {
306+
s.True(ReferSameObject(*ownerRef, s.ownerRef), "object should be adopted")
307+
})
308+
// check released objects
309+
forEarch(released, func(ownerRef *metav1.OwnerReference) {
310+
s.Require().Nil(ownerRef)
311+
})
312+
// check no changed objects
313+
forEarch(noChanged, func(ownerRef *metav1.OwnerReference) {
314+
s.True(ReferSameObject(*ownerRef, s.deferentOwnerRef), "object should not be changed")
315+
})
287316
}

controller/refmanager/writer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (w *ownerRefWriter) Adopt(ctx context.Context, parent metav1.Object, parent
5353
}
5454

5555
upsertOwner(child, *newOwner)
56-
clientObj, ok := parent.(client.Object)
56+
clientObj, ok := child.(client.Object)
5757
if !ok {
5858
return fmt.Errorf("failed to convert parent object to controller-runtime client.Object")
5959
}

controller/refmanager/writer_test.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package refmanager
1919
import (
2020
"context"
2121

22+
corev1 "k8s.io/api/core/v1"
2223
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2324
"sigs.k8s.io/controller-runtime/pkg/client"
2425
)
@@ -28,20 +29,20 @@ func (s *ownerReferenceTestSute) TestAdopt() {
2829

2930
testcase := []struct {
3031
name string
31-
object client.Object
32+
pod *corev1.Pod
3233
wantErr bool
3334
}{
3435
{
35-
name: "adopt orpha pod",
36-
object: newFakePod(nil),
36+
name: "adopt orpha pod",
37+
pod: newFakePod(nil),
3738
},
3839
{
39-
name: "adopt owned pod",
40-
object: newFakePod(s.owner),
40+
name: "adopt owned pod",
41+
pod: newFakePod(s.owner),
4142
},
4243
{
4344
name: "adopt pod with conflict",
44-
object: newFakePod(s.deferentOwner),
45+
pod: newFakePod(s.deferentOwner),
4546
wantErr: true,
4647
},
4748
}
@@ -50,15 +51,20 @@ func (s *ownerReferenceTestSute) TestAdopt() {
5051
test := testcase[i]
5152
s.Run(test.name, func() {
5253
// create object
53-
err := s.client.Create(context.TODO(), test.object)
54+
err := s.client.Create(context.TODO(), test.pod)
5455
s.NoError(err)
5556

56-
err = writer.Adopt(context.TODO(), s.owner, s.ownerGVK, test.object)
57+
err = writer.Adopt(context.TODO(), s.owner, s.ownerGVK, test.pod)
5758
if test.wantErr {
5859
s.Error(err)
5960
} else {
6061
s.NoError(err)
61-
owner := metav1.GetControllerOfNoCopy(test.object)
62+
// get pod from client
63+
pod := &corev1.Pod{}
64+
err = s.client.Get(context.TODO(), client.ObjectKeyFromObject(test.pod), pod)
65+
s.Require().NoError(err)
66+
owner := metav1.GetControllerOfNoCopy(pod)
67+
s.Require().NotNil(owner)
6268
s.True(ReferSameObject(s.ownerRef, *owner), "the controller owner reference must be the same")
6369
}
6470
})
@@ -69,33 +75,37 @@ func (s *ownerReferenceTestSute) TestRelease() {
6975
writer := NewOwnerRefWriter(s.client)
7076

7177
testcase := []struct {
72-
name string
73-
object client.Object
78+
name string
79+
pod client.Object
7480
}{
7581
{
76-
name: "release orphan pod, nothing changed",
77-
object: newFakePod(nil),
82+
name: "release orphan pod, nothing changed",
83+
pod: newFakePod(nil),
7884
},
7985
{
80-
name: "release owned pod",
81-
object: newFakePod(s.owner),
86+
name: "release owned pod",
87+
pod: newFakePod(s.owner),
8288
},
8389
{
84-
name: "release pod controlled by other object",
85-
object: newFakePod(s.deferentOwner),
90+
name: "release pod controlled by other object",
91+
pod: newFakePod(s.deferentOwner),
8692
},
8793
}
8894

8995
for i := range testcase {
9096
test := testcase[i]
9197
s.Run(test.name, func() {
9298
// create object
93-
err := s.client.Create(context.TODO(), test.object)
99+
err := s.client.Create(context.TODO(), test.pod)
94100
s.NoError(err)
95101

96-
writer.Release(context.TODO(), s.owner, test.object) // nolint
97-
owner := metav1.GetControllerOfNoCopy(test.object)
102+
writer.Release(context.TODO(), s.owner, test.pod) // nolint
98103

104+
// get pod from client
105+
pod := &corev1.Pod{}
106+
err = s.client.Get(context.TODO(), client.ObjectKeyFromObject(test.pod), pod)
107+
s.Require().NoError(err)
108+
owner := metav1.GetControllerOfNoCopy(pod)
99109
if owner != nil {
100110
s.False(ReferSameObject(s.ownerRef, *owner), "the controller owner reference must not be the same")
101111
}

0 commit comments

Comments
 (0)