From acc2fdf9c273b08c3486a600f1ea6976b822a902 Mon Sep 17 00:00:00 2001
From: Brad Davidson <brad.davidson@rancher.com>
Date: Mon, 3 Mar 2025 21:18:04 +0000
Subject: [PATCH] Make IgnoreUpdate secrets optional

Fixes issue where nonexistent secret with ignoreUpdate set would cause the plan to endlessly requeue due to errors. If it is ignored for purposes of plan hash, it should be optional.

Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
---
 pkg/upgrade/handle_upgrade.go |  2 +-
 pkg/upgrade/job/job.go        |  1 +
 pkg/upgrade/plan/plan.go      | 25 +++++++++++++++++++------
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/pkg/upgrade/handle_upgrade.go b/pkg/upgrade/handle_upgrade.go
index 810544d6..2a0bfa7a 100644
--- a/pkg/upgrade/handle_upgrade.go
+++ b/pkg/upgrade/handle_upgrade.go
@@ -40,7 +40,7 @@ func (ctl *Controller) handlePlans(ctx context.Context) error {
 			// validate plan, and generate events for transitions
 			validated := upgradeapiv1.PlanSpecValidated
 			validated.CreateUnknownIfNotExists(obj)
-			if err := upgradeplan.Validate(obj); err != nil {
+			if err := upgradeplan.Validate(obj, secretsCache); err != nil {
 				if !validated.IsFalse(obj) {
 					recorder.Eventf(obj, corev1.EventTypeWarning, "ValidateFailed", "Failed to validate plan: %v", err)
 				}
diff --git a/pkg/upgrade/job/job.go b/pkg/upgrade/job/job.go
index fa17f260..7e34f87b 100644
--- a/pkg/upgrade/job/job.go
+++ b/pkg/upgrade/job/job.go
@@ -288,6 +288,7 @@ func New(plan *upgradeapiv1.Plan, node *corev1.Node, controllerName string) *bat
 			VolumeSource: corev1.VolumeSource{
 				Secret: &corev1.SecretVolumeSource{
 					SecretName: secret.Name,
+					Optional:   pointer.Bool(secret.IgnoreUpdates),
 				},
 			},
 		})
diff --git a/pkg/upgrade/plan/plan.go b/pkg/upgrade/plan/plan.go
index 0a9d46d8..f7e2054d 100644
--- a/pkg/upgrade/plan/plan.go
+++ b/pkg/upgrade/plan/plan.go
@@ -79,15 +79,17 @@ func DigestStatus(plan *upgradeapiv1.Plan, secretCache corectlv1.SecretCache) (u
 		}
 
 		for _, s := range plan.Spec.Secrets {
-			secret, err := secretCache.Get(plan.Namespace, s.Name)
-			if err != nil {
-				return plan.Status, err
-			}
 			if !s.IgnoreUpdates {
+				secret, err := secretCache.Get(plan.Namespace, s.Name)
+				if err != nil {
+					return plan.Status, err
+				}
+
 				secretHash, err := hash.SecretHash(secret)
 				if err != nil {
 					return plan.Status, err
 				}
+
 				h.Write([]byte(secretHash))
 			}
 		}
@@ -239,7 +241,7 @@ func sha256sum(s ...string) string {
 }
 
 // Validate performs validation of the plan spec, raising errors for any conflicting or invalid settings.
-func Validate(plan *upgradeapiv1.Plan) error {
+func Validate(plan *upgradeapiv1.Plan, secretCache corectlv1.SecretCache) error {
 	if drainSpec := plan.Spec.Drain; drainSpec != nil {
 		if drainSpec.DeleteEmptydirData != nil && drainSpec.DeleteLocalData != nil {
 			return ErrDrainDeleteConflict
@@ -262,5 +264,16 @@ func Validate(plan *upgradeapiv1.Plan) error {
 	if delay := plan.Spec.PostCompleteDelay; delay != nil && delay.Duration < 0 {
 		return ErrInvalidDelay
 	}
-	return nil
+
+	sErrs := []error{}
+	for _, secret := range plan.Spec.Secrets {
+		if secret.IgnoreUpdates {
+			continue
+		}
+		if _, err := secretCache.Get(plan.Namespace, secret.Name); err != nil {
+			sErrs = append(sErrs, err)
+		}
+	}
+
+	return merr.NewErrors(sErrs...)
 }
-- 
GitLab