diff --git a/pkg/reconcilers/configresolver/reconciler.go b/pkg/reconcilers/configresolver/reconciler.go index 362fe294..a1227e70 100644 --- a/pkg/reconcilers/configresolver/reconciler.go +++ b/pkg/reconcilers/configresolver/reconciler.go @@ -240,6 +240,17 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu // ── No change ───────────────────────────────────────────────────────────── if change.noChange() { + // Even when content is identical to the stored SensitiveConfig, clear a + // stale Resolver=False condition. This occurs when a secret is deleted + // (which sets Resolver=False and preserves the last-good SC), then + // re-created with the same content: detectChange returns noChange=true + // because all hashes still match, but the failure condition from the + // deletion window must be cleared so the Config can become Ready again. + resolverC := cfgOrig.GetCondition(configv1alpha1.ConditionTypeResolver) + if resolverC.Status != "" && !resolverC.IsTrue() { + log.Info("no content change but stale Resolver=False detected — clearing condition") + return ctrl.Result{}, errors.Wrap(r.handleSuccess(ctx, cfgOrig), errUpdateStatus) + } log.Debug("no change detected, skipping") return ctrl.Result{}, nil } diff --git a/pkg/reconcilers/targetconfig/reconciler.go b/pkg/reconcilers/targetconfig/reconciler.go index 94f6bc31..f5a19f0d 100644 --- a/pkg/reconcilers/targetconfig/reconciler.go +++ b/pkg/reconcilers/targetconfig/reconciler.go @@ -239,6 +239,17 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu if !hasChanged { log.Info("Transact skip, nothing to update") + // Still reset TargetForConfig to Ready so any stale Failed condition + // (set when the target was briefly not-ready) is cleared. Without this + // the overall Config Ready condition stays False permanently whenever a + // target drops and recovers but no intent change is detected. + if err := r.cfgMgr.SetConfigsTargetConditionForTarget( + ctx, targetOrig, + configv1alpha1.TargetForConfigReady("target ready"), + ); err != nil { + return ctrl.Result{}, + errors.Wrap(r.handleError(ctx, targetOrig, "cannot update config status", err), errUpdateStatus) + } return ctrl.Result{}, nil }