Im using the following code inside kubebuilder controller to read before update for k8s custom resource, im checking if the object exist if yes check if need to update, if not create it , as I need to use it in several places
I want to ask:
-
if there is some helper that can help me to reduce this boilarplate
code ? something likecreateOrUpdate
func -
am I doing it right ?
if err := r.Get(ctx, client.ObjectKey{Name: sCrName, Namespace: sCrNs}, &eCmp); err != nil {
if apierrors.IsNotFound(err) {
// If the object does not exist, create a new one
if err := r.Create(ctx, &eCmp); err != nil {
return ctrl.Result{}, err
}
} else {
// If there was an error other than 'not found', return the error
return ctrl.Result{}, err
}
} else {
// If the object exists, patch it
patch := client.MergeFrom(eCmp.DeepCopy())
if err := r.Patch(ctx, &eCmpp, patch); err != nil {
return ctrl.Result{}, err
}
}
if enverything is as recomended please let me know.
I need also to do the stratgic merge but the code doesnt support it
I found the following
https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#CreateOrUpdate
but I dont want it to be related to timestamp, just if something was change -> update it
or something doesnt exist -> create it
2
Answers
you can use the controllerutil.CreateOrUpdate() function from the sigs.k8s.io/controller-runtime/pkg/controller/controllerutil package to reduce boilerplate code.
use controllerutil.CreateOrUpdate() function:
strategic merge, you can add the strategic merge patch to the callback function to patch the object strategically
There isn’t anything wrong with how you’ve done it, you could potentially restructure it a little to reduce the if nesting.
That
CreateOrUpdate
function looks like it should also do what you want. It doesn’t do any comparison with a timestamp. The example on there is doing that specifically but if you look at the underlying function controllerutil.go#L195 you will see that there is no timestamp comparison there.What you will need to do is either define your mutate function (a function with the patch logic) and pass that as a parameter or create an anonymous function and pass that in.
For example:
If you look at the
CreateOrUpdate
function, it’s essentially doing the same thing you are in your code except for the mutate (patching) of the resource.