kuberneteskubebuilder

Setting status conditions for controller-runtime's client Get errors


Under which conditions will client.Client return a non-nil error and the client object will be also filled (or at least the namespace and name object meta)? The Kubernetes operator framework book suggests to set a status condition in case of getting resource errors in a similar fashion:

myResource := &v1alpha1.MyResource{}
err := r.Get(ctx, req.NamespacedName, myResource)
if err != nil && errors.IsNotFound(err) {
    return ctrl.Result{}, nil
} else if err != nil {
    logger.Error(err, "Error getting resource object")
    meta.SetStatusCondition(&myResource.Status.Conditions, metav1.Condition{
        Type:               "Failed",
        Status:             metav1.ConditionTrue,
        Reason:             "NotAvailable",
        LastTransitionTime: metav1.NewTime(time.Now()),
        Message:            fmt.Sprintf("unable to get custom resource: %s", err.Error()),
    })
    return ctrl.Result{}, utilerrors.NewAggregate([]error{err, r.Status().Update(ctx, myResource)})
}

Is it even possible to update the status of a CR where we are unable to get it, but the error doesn't satisfy the condition errors.IsNotFound(err)?


Solution

  • Here is the list of errors you may get from reconciler's Get() method.

    If the error is not nil, that means you most probably did not get the resource correctly, so you shouldn't update it. Say that your error is TooManyRequests. In this case, errors.IsTooManyRequests(err) returns true while errors.IsNotFound(err) returns false. The point is, there is no guarantee that you have the correct version of the custom resource if the err is not nil. You should return the error and let the controller reconcile it again.