From 559bdd9d035ebeba272869b89960cc9f5a359d03 Mon Sep 17 00:00:00 2001 From: Matt Pryor Date: Sun, 30 Aug 2026 16:05:09 +0100 Subject: [PATCH] bug: clean up orphaned drift-detection version ConfigMaps removeStaleDriftDetectionResources already deletes the ResourceSummary instances and the drift-detection-manager deployment for a cluster once it's gone, but left the per-cluster version-tracking ConfigMap behind forever since nothing else owns it. Delete it too, after the deployment so drift-detection-manager isn't still around to recreate it. Needs the delete verb on configmaps, which the manager didn't have before since it never mutated them. --- config/rbac/role.yaml | 10 +++++++++- controllers/clustersummary_controller.go | 2 +- controllers/utils.go | 12 ++++++++++++ controllers/utils_test.go | 25 ++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- manifest/manifest.yaml | 10 +++++++++- 7 files changed, 59 insertions(+), 6 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 37ef3044..3be04947 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -8,8 +8,8 @@ rules: - "" resources: - configmaps - - secrets verbs: + - delete - get - list - watch @@ -20,6 +20,14 @@ rules: verbs: - get - list +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch - apiGroups: - '*' resources: diff --git a/controllers/clustersummary_controller.go b/controllers/clustersummary_controller.go index 66fd782c..bb230bc2 100644 --- a/controllers/clustersummary_controller.go +++ b/controllers/clustersummary_controller.go @@ -157,7 +157,7 @@ type reconcileCooldown struct { //+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=configurationbundles,verbs=get;list;watch;create;delete;update;patch //+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=configurationbundles/status,verbs=get;list;watch;update //+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch -//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch +//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;delete //+kubebuilder:rbac:groups=controlplane.cluster.x-k8s.io,resources=kubeadmcontrolplanes,verbs=get;watch;list //+kubebuilder:rbac:groups="infrastructure.cluster.x-k8s.io",resources="*",verbs=get;watch;list //+kubebuilder:rbac:groups="source.toolkit.fluxcd.io",resources=gitrepositories,verbs=get;watch;list diff --git a/controllers/utils.go b/controllers/utils.go index 54e9b692..a6611ecd 100644 --- a/controllers/utils.go +++ b/controllers/utils.go @@ -432,6 +432,18 @@ func removeStaleDriftDetectionResources(ctx context.Context, logger logr.Logger) logger.V(logs.LogInfo).Info(fmt.Sprintf("deleting driftDetection deployment %s/%s", depl.Namespace, depl.Name)) _ = c.Delete(ctx, depl) + + // Delete the deployment first, not the ConfigMap. drift-detection-manager itself writes + // the ConfigMap and is still running at this point, so deleting it first risks a + // recreate in the gap - and once the deployment's gone we have no way back to this + // cluster to retry. This only narrows that window, doesn't close it (we don't know the + // pod's write cadence, and waiting here for it to fully terminate would stall cleanup + // for every other cluster). Best effort, same as the deployment delete above - still + // better than the unconditional orphan today. + if err := sveltos_upgrade.DeleteDriftDetectionVersion(ctx, c, getSveltosNamespace(), clusterNs, clusterName, + clusterType, true, logger); err != nil { + logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to delete driftDetection version configMap: %v", err)) + } } } } diff --git a/controllers/utils_test.go b/controllers/utils_test.go index 805c0899..5758a2a3 100644 --- a/controllers/utils_test.go +++ b/controllers/utils_test.go @@ -705,6 +705,24 @@ metadata: Expect(waitForObject(context.TODO(), testEnv, driftDetectionManager)).To(Succeed()) logger := textlogger.NewLogger(textlogger.NewConfig()) + + Expect(sveltos_upgrade.StoreDriftDetectionVersion(context.TODO(), testEnv.Client, sveltosNamespace, "v1.0.0", + namespace, clusterName, libsveltosv1beta1.ClusterTypeSveltos, true, logger)).To(Succeed()) + + var versionConfigMap corev1.ConfigMap + Eventually(func() bool { + versionConfigMaps := &corev1.ConfigMapList{} + err := testEnv.List(context.TODO(), versionConfigMaps, client.InNamespace(namespace), client.MatchingLabels{ + sveltos_upgrade.ClusterNameLabel: clusterName, + sveltos_upgrade.ClusterTypeLabel: strings.ToLower(string(libsveltosv1beta1.ClusterTypeSveltos)), + }) + if err != nil || len(versionConfigMaps.Items) != 1 { + return false + } + versionConfigMap = versionConfigMaps.Items[0] + return true + }, timeout, pollingInterval).Should(BeTrue()) + go controllers.RemoveStaleDriftDetectionResources(ctx, logger) // RemoveStaleDriftDetectionResources sleeps for a minute @@ -747,6 +765,13 @@ metadata: } return apierrors.IsNotFound(err) }, timeout, pollingInterval).Should(BeTrue()) + + Eventually(func() bool { + err := testEnv.Get(context.TODO(), + types.NamespacedName{Namespace: versionConfigMap.Namespace, Name: versionConfigMap.Name}, + &corev1.ConfigMap{}) + return apierrors.IsNotFound(err) + }, timeout, pollingInterval).Should(BeTrue()) }) }) diff --git a/go.mod b/go.mod index b306ba21..40487433 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/onsi/gomega v1.42.1 github.com/opencontainers/image-spec v1.1.1 github.com/pkg/errors v0.9.1 - github.com/projectsveltos/libsveltos v1.14.0 + github.com/projectsveltos/libsveltos v1.14.1-0.20260830144548-82677637a8ae github.com/prometheus/client_golang v1.24.1 github.com/sigstore/cosign/v3 v3.1.3 github.com/sigstore/sigstore v1.10.9 diff --git a/go.sum b/go.sum index 1be46dd6..7ec0b80a 100644 --- a/go.sum +++ b/go.sum @@ -639,8 +639,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/projectsveltos/libsveltos v1.14.0 h1:vw+kbGfsMcKk69AdQsjpdhlZK0LI/07Y+292noB9F+8= -github.com/projectsveltos/libsveltos v1.14.0/go.mod h1:U6iGj5KoC/PcTD2vh3XU6gy7g11suThT6sZSEpmLEkU= +github.com/projectsveltos/libsveltos v1.14.1-0.20260830144548-82677637a8ae h1:ULG/BXW/tHRT4UfjDzKHtaGDHJMRHYgZgy0IazxPZ18= +github.com/projectsveltos/libsveltos v1.14.1-0.20260830144548-82677637a8ae/go.mod h1:U6iGj5KoC/PcTD2vh3XU6gy7g11suThT6sZSEpmLEkU= github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5 h1:khnc+994UszxZYu69J+R5FKiLA/Nk1JQj0EYAkwTWz0= github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5/go.mod h1:yVL8KQFa9tmcxgwl9nwIMtKgtmIVC1zaFRSCfOwYvPY= github.com/projectsveltos/lua-utils/glua-runes v0.0.0-20251212200258-2b3cdcb7c0f5 h1:YbsebwRwTRhV8QacvEAdFqxcxHdeu7JTVtsBovbkgos= diff --git a/manifest/manifest.yaml b/manifest/manifest.yaml index 83713a4a..e972ba78 100644 --- a/manifest/manifest.yaml +++ b/manifest/manifest.yaml @@ -11607,8 +11607,8 @@ rules: - "" resources: - configmaps - - secrets verbs: + - delete - get - list - watch @@ -11619,6 +11619,14 @@ rules: verbs: - get - list +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch - apiGroups: - '*' resources: