Skip to content

Commit 2f12419

Browse files
committed
Error when ReconcileFn changes object name/namespace
1 parent 1280ca7 commit 2f12419

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

pkg/controller/controllerutil/controllerutil.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,22 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj runtime.Object, r
135135

136136
// reconcile the existing object
137137
newobj := existing.DeepCopyObject()
138-
if e := r(newobj); e != nil {
139-
return OperationNoop, e
140-
}
141-
// as promised, CreateOrUpdate creates or updates object with the same name and namespace
142138
newmo := newobj.(v1.Object)
143139
newmo.SetName(mo.GetName())
144140
newmo.SetNamespace(mo.GetNamespace())
145141

142+
if e := r(newobj); e != nil {
143+
return OperationNoop, e
144+
}
145+
146+
if newmo.GetName() != mo.GetName() {
147+
return OperationNoop, fmt.Errorf("ReconcileFn cannot mutate objects name")
148+
}
149+
150+
if newmo.GetNamespace() != mo.GetNamespace() {
151+
return OperationNoop, fmt.Errorf("ReconcileFn cannot mutate objects namespace")
152+
}
153+
146154
if errors.IsNotFound(err) {
147155
err = c.Create(ctx, newobj)
148156
op = OperationCreate
@@ -163,5 +171,4 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj runtime.Object, r
163171
}
164172

165173
// ReconcileFn is a function which mutates the existing object into it's desired state.
166-
// If there is no existing object, a zero value object is passed in.
167174
type ReconcileFn func(existing runtime.Object) error

pkg/controller/controllerutil/controllerutil_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,36 @@ var _ = Describe("Controllerutil", func() {
186186
By("returning no error")
187187
Expect(err).NotTo(HaveOccurred())
188188
})
189+
190+
It("errors when reconcile renames an object", func() {
191+
op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentSpecr(deplSpec))
192+
193+
Expect(op).To(BeEquivalentTo(controllerutil.OperationCreate))
194+
Expect(err).NotTo(HaveOccurred())
195+
196+
op, err = controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentRenamer)
197+
198+
By("returning OperationNoop")
199+
Expect(op).To(BeEquivalentTo(controllerutil.OperationNoop))
200+
201+
By("returning error")
202+
Expect(err).To(HaveOccurred())
203+
})
204+
205+
It("errors when object namespace changes", func() {
206+
op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentSpecr(deplSpec))
207+
208+
Expect(op).To(BeEquivalentTo(controllerutil.OperationCreate))
209+
Expect(err).NotTo(HaveOccurred())
210+
211+
op, err = controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentNamespaceChanger)
212+
213+
By("returning OperationNoop")
214+
Expect(op).To(BeEquivalentTo(controllerutil.OperationNoop))
215+
216+
By("returning error")
217+
Expect(err).To(HaveOccurred())
218+
})
189219
})
190220
})
191221

@@ -207,6 +237,18 @@ var deploymentIdentity controllerutil.ReconcileFn = func(obj runtime.Object) err
207237
return nil
208238
}
209239

240+
var deploymentRenamer controllerutil.ReconcileFn = func(obj runtime.Object) error {
241+
deploy := obj.(*appsv1.Deployment)
242+
deploy.Name = fmt.Sprintf("%s-1", deploy.Name)
243+
return nil
244+
}
245+
246+
var deploymentNamespaceChanger controllerutil.ReconcileFn = func(obj runtime.Object) error {
247+
deploy := obj.(*appsv1.Deployment)
248+
deploy.Namespace = fmt.Sprintf("%s-1", deploy.Namespace)
249+
return nil
250+
}
251+
210252
func deploymentScaler(replicas int32) controllerutil.ReconcileFn {
211253
fn := func(obj runtime.Object) error {
212254
deploy := obj.(*appsv1.Deployment)

0 commit comments

Comments
 (0)