Hi David,
I'd suggest you ensure that you have the latest state of the resource in the variable. I mean, you re-fetch/get them before doing the actions.
Example:
// Check if the deployment already exists, if not create a new one
c := &appsv1.Deployment{}
err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found)
if err != nil && errors.IsNotFound(err) {
// {... code}
} else if err != nil {
// {... code}
}
Then, before doing anything with the Deployment, which was stored in the `found` variable, we get it again to ensure that we have the latest version/state. Note that from the first time that we get that from the cluster until the second moment that we will use it, it can be changed or no longer exist there. In the code/variable, we have stored the data from when we requested that to the k8s API via the client.
So, if a reconciling process already deletes the external resource, the next ones won't will try to delete them because they will check first that it no longer exists. So, in this scenario, you can stop the reconcile with the return or move to the next step/operation (if required). It is like a "loop" that will be executed until you ensure that the desired state is applied to the cluster.
The finalizer is useful when you want to ensure that an action/operation will be performed before the CR be deleted. Therefore, you will not allow the CR to get deleted until the requirement is satisfied.
I hope that it helps you.
Cheers,
CAMILA MACEDO
SR. SOFTWARE ENGINEER
RED HAT Operator framework
Red Hat UK
She / Her / Hers
IM: cmacedo