Skip to content

Commit 8caebef

Browse files
authored
Merge pull request #3193 from ian-howell/create-or-update-documentation
📖 Document pitfalls of CreateOrUpdate and CreateOrPatch
2 parents bd600cf + 93a8d95 commit 8caebef

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

pkg/controller/controllerutil/controllerutil.go

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ func referSameObject(a, b metav1.OwnerReference) bool {
278278
return aGV.Group == bGV.Group && a.Kind == b.Kind && a.Name == b.Name
279279
}
280280

281-
// OperationResult is the action result of a CreateOrUpdate call.
281+
// OperationResult is the action result of a CreateOrUpdate or CreateOrPatch call.
282282
type OperationResult string
283283

284284
const ( // They should complete the sentence "Deployment default/foo has been ..."
@@ -294,13 +294,26 @@ const ( // They should complete the sentence "Deployment default/foo has been ..
294294
OperationResultUpdatedStatusOnly OperationResult = "updatedStatusOnly"
295295
)
296296

297-
// CreateOrUpdate creates or updates the given object in the Kubernetes
298-
// cluster. The object's desired state must be reconciled with the existing
299-
// state inside the passed in callback MutateFn.
297+
// CreateOrUpdate attempts to fetch the given object from the Kubernetes cluster.
298+
// If the object didn't exist, MutateFn will be called, and it will be created.
299+
// If the object did exist, MutateFn will be called, and if it changed the
300+
// object, it will be updated.
301+
// Otherwise, it will be left unchanged.
302+
// The executed operation (and an error) will be returned.
300303
//
301-
// The MutateFn is called regardless of creating or updating an object.
304+
// WARNING: If the MutateFn resets a value on obj that has a default value,
305+
// CreateOrUpdate will *always* perform an update. This is because when the
306+
// object is fetched from the API server, the value will have taken on the
307+
// default value, and the check for equality will fail. For example, Deployments
308+
// must have a Replicas value set. If the MutateFn sets a Deployment's Replicas
309+
// to nil, then it will never match with the object returned from the API
310+
// server, which defaults the value to 1.
302311
//
303-
// It returns the executed operation and an error.
312+
// WARNING: CreateOrUpdate assumes that no values have been set on obj aside
313+
// from the Name/Namespace. Values other than Name and Namespace that existed on
314+
// obj may be overwritten by the corresponding values in the object returned
315+
// from the Kubernetes API server. When this happens, the Update will not work
316+
// as expected.
304317
//
305318
// Note: changes made by MutateFn to any sub-resource (status...), will be
306319
// discarded.
@@ -339,13 +352,26 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f M
339352
return OperationResultUpdated, nil
340353
}
341354

342-
// CreateOrPatch creates or patches the given object in the Kubernetes
343-
// cluster. The object's desired state must be reconciled with the before
344-
// state inside the passed in callback MutateFn.
355+
// CreateOrPatch attempts to fetch the given object from the Kubernetes cluster.
356+
// If the object didn't exist, MutateFn will be called, and it will be created.
357+
// If the object did exist, MutateFn will be called, and if it changed the
358+
// object, it will be patched.
359+
// Otherwise, it will be left unchanged.
360+
// The executed operation (and an error) will be returned.
345361
//
346-
// The MutateFn is called regardless of creating or updating an object.
362+
// WARNING: If the MutateFn resets a value on obj that has a default value,
363+
// CreateOrPatch will *always* perform a patch. This is because when the
364+
// object is fetched from the API server, the value will have taken on the
365+
// default value, and the check for equality will fail.
366+
// For example, Deployments must have a Replicas value set. If the MutateFn sets
367+
// a Deployment's Replicas to nil, then it will never match with the object
368+
// returned from the API server, which defaults the value to 1.
347369
//
348-
// It returns the executed operation and an error.
370+
// WARNING: CreateOrPatch assumes that no values have been set on obj aside
371+
// from the Name/Namespace. Values other than Name and Namespace that existed on
372+
// obj may be overwritten by the corresponding values in the object returned
373+
// from the Kubernetes API server. When this happens, the Patch will not work
374+
// as expected.
349375
//
350376
// Note: changes to any sub-resource other than status will be ignored.
351377
// Changes to the status sub-resource will only be applied if the object

0 commit comments

Comments
 (0)