<p>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:</p>
<ul>
<li><p>if there is some helper that can help me to reduce this boilarplate
code ? something like <code>createOrUpdate</code> func</p>
</li>
<li><p>am I doing it right ?</p>
</li>
</ul>
<pre><code>if err := r.Get(ctx, client.ObjectKey{Name: sCrName, Namespace: sCrNs}, &amp;eCmp); err != nil {
    if apierrors.IsNotFound(err) {
        // If the object does not exist, create a new one
        if err := r.Create(ctx, &amp;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, &amp;eCmp, patch); err != nil {
        return ctrl.Result{}, err
    }
}
</code></pre>
<p><strong>if enverything is as recomended please let me know.</strong>
I need also to do the stratgic merge but the code doesnt support it</p>
<p>I found the following
<a href="https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#CreateOrUpdate" rel="nofollow noreferrer">https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#CreateOrUpdate</a>
but I dont want it to be related to timestamp, just <code>if something was change -&gt; update it</code> or something <code>doesnt exist -&gt; create it</code></p>
<p><strong>when trying to update the CR with the following code it doesnt works , any idea?</strong></p>
<pre><code>// If the object exists, patch it
patch := client.MergeFrom(eCmp.DeepCopy())
if err := r.Patch(ctx, &amp;eCmp, patch); err != nil {
    return ctrl.Result{}, err
}
</code></pre>

PeterSO
<p>There isn't anything wrong with how you've done it, you could potentially restructure it a little to reduce the if nesting.</p>
<pre><code>err := r.Get(ctx, client.ObjectKey{Name: sCrName, Namespace: sCrNs}, &amp;eCmp)
// Object exists, patch it
if err == nil {
    patch := client.MergeFrom(eCmp.DeepCopy())
    if err := r.Patch(ctx, &amp;eCmpp, patch); err != nil {
        return ctrl.Result{}, err
    }
    return patch, nil // Adjust appropriately
} else if apierrors.IsNotFound(err) {
    // Object does not exist, create a new one
    if err := r.Create(ctx, &amp;eCmp); err != nil {
        return ctrl.Result{}, err
    }
} 
return ctrl.Result{}, err
</code></pre>
<p>That <code>CreateOrUpdate</code> 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 <a href="https://github.com/kubernetes-sigs/controller-runtime/blob/v0.14.6/pkg/controller/controllerutil/controllerutil.go#L195" rel="nofollow noreferrer">controllerutil.go#L195</a> you will see that there is no timestamp comparison there.</p>
<p>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.</p>
<p>For example:</p>
<pre><code>op, err := controllerutil.CreateOrUpdate(context.TODO(), client, object, func() error {
    
    // Your mutate logic goes in here

    return nil
})
</code></pre>
<p>If you look at the <code>CreateOrUpdate</code> function, it's essentially doing the same thing you are in your code except for the mutate (patching) of the resource.</p>
