diff --git a/pkg/runtime/reconciler.go b/pkg/runtime/reconciler.go index ff02467..1d96e52 100644 --- a/pkg/runtime/reconciler.go +++ b/pkg/runtime/reconciler.go @@ -745,6 +745,13 @@ func (r *resourceReconciler) updateResource( return latest, err } + // We don't want to attempt updating the resource until it is Synced! + if synced, err := IsSyncedInRes(ctx, rm, latest); !synced { + rlog.Info( + "requeing until resource is synced", + ) + return latest, err + } // Check to see if the latest observed state already matches the // desired state and if not, update the resource delta := r.rd.Delta(desired, latest) diff --git a/pkg/runtime/util.go b/pkg/runtime/util.go index adc994a..229a25a 100644 --- a/pkg/runtime/util.go +++ b/pkg/runtime/util.go @@ -14,6 +14,7 @@ package runtime import ( + "context" "encoding/json" "fmt" "strings" @@ -70,6 +71,27 @@ func IsSynced(res acktypes.AWSResource) bool { return false } +// IsSyncedInRes is like IsSynced, but instead of returnning false +// when the Synced condition is not there, it returns true. +// Note(michaelhtm) We will be using this as a preUpdate check to +// see if a resource has a NotSynced condition +func IsSyncedInRes(ctx context.Context, rm acktypes.AWSResourceManager, res acktypes.AWSResource) (bool, error) { + for _, c := range res.Conditions() { + if c.Type == ackv1alpha1.ConditionTypeResourceSynced { + if c.Status == corev1.ConditionTrue { + return true, nil + } + // TODO(michaelhtm) we should probably start relying more and more in IsSynced below. + // Or maybe store the RequeueError in ackCondition.RequeueError... + return false, fmt.Errorf("resource is not synced") + + } + } + + synced, err := rm.IsSynced(ctx, res) + return synced, err +} + // IsReadOnly returns true if the supplied AWSResource has an annotation // indicating that it is in read-only mode. func IsReadOnly(res acktypes.AWSResource) bool {