Skip to content

Commit a7d5207

Browse files
authored
Merge pull request #1207 from gianlucam76/resourcesummary-agentless
(bug) clean ResourceSummary instances when cluster is deleted
2 parents a4fd455 + d39b4e3 commit a7d5207

15 files changed

Lines changed: 263 additions & 148 deletions

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ KUBECTL := $(TOOLS_BIN_DIR)/kubectl
7373

7474
GOVULNCHECK_VERSION := "v1.1.3"
7575
GOLANGCI_LINT_VERSION := "v1.64.7"
76-
CLUSTERCTL_VERSION := "v1.10.1"
76+
CLUSTERCTL_VERSION := "v1.10.2"
7777

7878
KUSTOMIZE_VER := v5.3.0
7979
KUSTOMIZE_BIN := kustomize
@@ -194,7 +194,7 @@ endif
194194
# K8S_VERSION for the Kind cluster can be set as environment variable. If not defined,
195195
# this default value is used
196196
ifndef K8S_VERSION
197-
K8S_VERSION := v1.32.2
197+
K8S_VERSION := v1.33.0
198198
endif
199199

200200
KIND_CONFIG ?= kind-cluster.yaml

controllers/clustersummary_controller.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,17 @@ func (r *ClusterSummaryReconciler) reconcileDelete(
286286

287287
logger.V(logs.LogDebug).Info("remove drift-detection-manager resources from management cluster")
288288
cs := clusterSummaryScope.ClusterSummary
289-
if err := removeDriftDetectionManagerFromManagementCluster(ctx,
290-
cs.Spec.ClusterNamespace, cs.Spec.ClusterName, cs.Spec.ClusterType, logger); err != nil {
289+
290+
err = removeStaleResourceSummary(ctx, cs.Spec.ClusterNamespace, cs.Spec.ClusterName, cs.Spec.ClusterType, logger)
291+
if err != nil {
292+
logger.V(logs.LogInfo).Info(
293+
fmt.Sprintf("failed to remove resourceSummary instances from management cluster: %v", err))
294+
return reconcile.Result{Requeue: true, RequeueAfter: deleteRequeueAfter}, nil
295+
}
296+
297+
err := removeDriftDetectionManagerFromManagementCluster(ctx,
298+
cs.Spec.ClusterNamespace, cs.Spec.ClusterName, cs.Spec.ClusterType, logger)
299+
if err != nil {
291300
logger.V(logs.LogInfo).Info(
292301
fmt.Sprintf("failed to remove drift-detection-manager resources from management cluster: %v", err))
293302
return reconcile.Result{Requeue: true, RequeueAfter: deleteRequeueAfter}, nil
@@ -439,7 +448,7 @@ func (r *ClusterSummaryReconciler) SetupWithManager(ctx context.Context, mgr ctr
439448
}
440449

441450
if getAgentInMgmtCluster() {
442-
go removeStaleDriftDetectionManager(ctx, r.Logger)
451+
go removeStaleDriftDetectionResources(ctx, r.Logger)
443452
}
444453

445454
initializeManager(ctrl.Log.WithName("watchers"), mgr.GetConfig(), mgr.GetClient())

controllers/export_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ var (
207207
)
208208

209209
var (
210-
AssociatedClusterExist = associatedClusterExist
211-
RemoveDuplicates = removeDuplicates
210+
DeplAssociatedClusterExist = deplAssociatedClusterExist
211+
RemoveStaleResourceSummary = removeStaleResourceSummary
212+
RemoveDuplicates = removeDuplicates
212213
)

controllers/handlers_helm.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,7 @@ func handleInstall(ctx context.Context, clusterSummary *configv1beta1.ClusterSum
760760
maxHistory := uint(getMaxHistoryValue(currentChart.Options))
761761

762762
if fs := getFeatureSummaryForFeatureID(clusterSummary, configv1beta1.FeatureHelm); fs != nil {
763-
if fs.ConsecutiveFailures%maxHistory == 0 && fs.FailureMessage != nil &&
764-
strings.Contains(*fs.FailureMessage, "context deadline exceeded") {
765-
763+
if fs.ConsecutiveFailures%maxHistory == 0 && fs.FailureMessage != nil {
766764
err := doUninstallRelease(ctx, clusterSummary, currentChart, kubeconfig, registryOptions, logger)
767765
if err != nil {
768766
return nil, err

controllers/resourcesummary_collection.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,19 @@ func collectResourceSummariesFromCluster(ctx context.Context, c client.Client, c
126126
}
127127

128128
logger.V(logs.LogVerbose).Info("collecting ResourceSummaries from cluster")
129+
listOptions := []client.ListOption{}
130+
if getAgentInMgmtCluster() {
131+
listOptions = []client.ListOption{
132+
client.MatchingLabels{
133+
sveltos_upgrade.ClusterNameLabel: cluster.Name,
134+
libsveltosv1beta1.ClusterSummaryNamespaceLabel: cluster.Namespace,
135+
},
136+
}
137+
}
138+
129139
rsList := libsveltosv1beta1.ResourceSummaryList{}
130140

131-
err = clusterClient.List(ctx, &rsList)
141+
err = clusterClient.List(ctx, &rsList, listOptions...)
132142
if err != nil {
133143
return err
134144
}
@@ -138,7 +148,7 @@ func collectResourceSummariesFromCluster(ctx context.Context, c client.Client, c
138148
for i := range rsList.Items {
139149
rs := &rsList.Items[i]
140150
if !rs.DeletionTimestamp.IsZero() {
141-
// ignore deleted ClassifierReport
151+
// ignore deleted resourceSummary
142152
continue
143153
}
144154
if rs.Status.ResourcesChanged || rs.Status.HelmResourcesChanged || rs.Status.KustomizeResourcesChanged {

controllers/utils.go

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import (
5050
"github.com/projectsveltos/libsveltos/lib/clusterproxy"
5151
"github.com/projectsveltos/libsveltos/lib/logsettings"
5252
libsveltosset "github.com/projectsveltos/libsveltos/lib/set"
53+
"github.com/projectsveltos/libsveltos/lib/sveltos_upgrade"
5354
)
5455

5556
//+kubebuilder:rbac:groups=extension.projectsveltos.io,resources=yttsources,verbs=get;list;watch
@@ -498,7 +499,8 @@ func getSortedKustomizationRefs(clusterSummary *configv1beta1.ClusterSummary) []
498499
}
499500

500501
// Identifies and removes drift detection deployments that are no longer associated with active clusters
501-
func removeStaleDriftDetectionManager(ctx context.Context, logger logr.Logger) {
502+
// Identifies and removes resourceSummary instances from clusters that are no longer existing
503+
func removeStaleDriftDetectionResources(ctx context.Context, logger logr.Logger) {
502504
listOptions := []client.ListOption{
503505
client.MatchingLabels{
504506
driftDetectionFeatureLabelKey: driftDetectionFeatureLabelValue,
@@ -507,6 +509,7 @@ func removeStaleDriftDetectionManager(ctx context.Context, logger logr.Logger) {
507509

508510
for {
509511
time.Sleep(time.Minute)
512+
510513
c := getManagementClusterClient()
511514
driftDetectionDeployments := &appsv1.DeploymentList{}
512515
err := c.List(ctx, driftDetectionDeployments, listOptions...)
@@ -518,7 +521,15 @@ func removeStaleDriftDetectionManager(ctx context.Context, logger logr.Logger) {
518521
for i := range driftDetectionDeployments.Items {
519522
depl := &driftDetectionDeployments.Items[i]
520523

521-
if !associatedClusterExist(ctx, c, depl, logger) {
524+
exist, clusterNs, clusterName, clusterType := deplAssociatedClusterExist(ctx, c, depl, logger)
525+
if !exist {
526+
// find resourceSummaries from this cluster and remove those.
527+
// Remove deployment only after this one succeed
528+
err = removeStaleResourceSummary(ctx, clusterNs, clusterName, clusterType, logger)
529+
if err != nil {
530+
continue
531+
}
532+
522533
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("deleting driftDetection deployment %s/%s",
523534
depl.Namespace, depl.Name))
524535
_ = c.Delete(ctx, depl)
@@ -527,35 +538,72 @@ func removeStaleDriftDetectionManager(ctx context.Context, logger logr.Logger) {
527538
}
528539
}
529540

530-
func associatedClusterExist(ctx context.Context, c client.Client, depl *appsv1.Deployment, logger logr.Logger) bool {
541+
func removeStaleResourceSummary(ctx context.Context, clusterNamespace, clusterName string,
542+
clusterType libsveltosv1beta1.ClusterType, logger logr.Logger) error {
543+
544+
c := getManagementClusterClient()
545+
546+
rsListOptions := []client.ListOption{
547+
client.MatchingLabels{
548+
sveltos_upgrade.ClusterNameLabel: clusterName,
549+
sveltos_upgrade.ClusterTypeLabel: strings.ToLower(string(clusterType)),
550+
libsveltosv1beta1.ClusterSummaryNamespaceLabel: clusterNamespace,
551+
},
552+
}
553+
554+
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("MGIANLUC %v", rsListOptions))
555+
556+
resourceSummaries := &libsveltosv1beta1.ResourceSummaryList{}
557+
err := c.List(ctx, resourceSummaries, rsListOptions...)
558+
if err != nil {
559+
logger.V(logsettings.LogInfo).Info(
560+
fmt.Sprintf("failed to collect resourceSummary instances: %v", err))
561+
return err
562+
}
563+
564+
for i := range resourceSummaries.Items {
565+
rs := &resourceSummaries.Items[i]
566+
err = c.Delete(ctx, rs)
567+
if err != nil {
568+
logger.V(logsettings.LogInfo).Info(
569+
fmt.Sprintf("failed to delete resourceSummary instance: %v", err))
570+
return err
571+
}
572+
}
573+
574+
return nil
575+
}
576+
577+
func deplAssociatedClusterExist(ctx context.Context, c client.Client, depl *appsv1.Deployment,
578+
logger logr.Logger) (exist bool, clusterName, clusterNamespace string, clusterType libsveltosv1beta1.ClusterType) {
579+
531580
if depl.Labels == nil {
532581
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("driftDetection %s/%s has no label",
533582
depl.Namespace, depl.Name))
534-
return true
583+
return true, "", "", ""
535584
}
536585

537586
clusterNamespace, ok := depl.Labels[driftDetectionClusterNamespaceLabel]
538587
if !ok {
539588
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("driftDetection %s/%s has no %s label",
540589
depl.Namespace, depl.Name, driftDetectionClusterNamespaceLabel))
541-
return true
590+
return true, "", "", ""
542591
}
543592

544-
clusterName, ok := depl.Labels[driftDetectionClusterNameLabel]
593+
clusterName, ok = depl.Labels[driftDetectionClusterNameLabel]
545594
if !ok {
546595
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("driftDetection %s/%s has no %s label",
547596
depl.Namespace, depl.Name, driftDetectionClusterNameLabel))
548-
return true
597+
return true, "", "", ""
549598
}
550599

551600
clusterTypeString, ok := depl.Labels[driftDetectionClusterTypeLabel]
552601
if !ok {
553602
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("driftDetection %s/%s has no %s label",
554603
depl.Namespace, depl.Name, driftDetectionClusterTypeLabel))
555-
return true
604+
return true, "", "", ""
556605
}
557606

558-
var clusterType libsveltosv1beta1.ClusterType
559607
if strings.EqualFold(clusterTypeString, string(libsveltosv1beta1.ClusterTypeSveltos)) {
560608
clusterType = libsveltosv1beta1.ClusterTypeSveltos
561609
} else if strings.EqualFold(clusterTypeString, string(libsveltosv1beta1.ClusterTypeCapi)) {
@@ -565,11 +613,11 @@ func associatedClusterExist(ctx context.Context, c client.Client, depl *appsv1.D
565613
_, err := clusterproxy.GetCluster(ctx, c, clusterNamespace, clusterName, clusterType)
566614
if err != nil {
567615
if apierrors.IsNotFound(err) {
568-
return false
616+
return false, clusterNamespace, clusterName, clusterType
569617
}
570618
logger.V(logsettings.LogInfo).Info(fmt.Sprintf("failed to get cluster %s:%s/%s: %v",
571619
clusterNamespace, clusterName, clusterTypeString, err))
572620
}
573621

574-
return true
622+
return true, "", "", ""
575623
}

controllers/utils_test.go

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package controllers_test
1919
import (
2020
"context"
2121
"fmt"
22+
"strings"
2223
"time"
2324

2425
. "github.com/onsi/ginkgo/v2"
@@ -28,6 +29,7 @@ import (
2829
appsv1 "k8s.io/api/apps/v1"
2930
corev1 "k8s.io/api/core/v1"
3031
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
32+
apierrors "k8s.io/apimachinery/pkg/api/errors"
3133
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3234
"k8s.io/apimachinery/pkg/runtime"
3335
"k8s.io/apimachinery/pkg/types"
@@ -428,7 +430,7 @@ var _ = Describe("getClusterProfileOwner ", func() {
428430
}
429431
})
430432

431-
It("associatedClusterExist returns false when associated cluster does not exist",
433+
It("deplAssociatedClusterExist returns false when associated cluster does not exist",
432434
func() {
433435
clusterNamespace := randomString()
434436
clusterName := randomString()
@@ -474,7 +476,8 @@ spec:
474476
Expect(c.Get(context.TODO(),
475477
types.NamespacedName{Namespace: u.GetNamespace(), Name: u.GetName()}, currentDepl)).To(Succeed())
476478

477-
Expect(controllers.AssociatedClusterExist(context.TODO(), c, currentDepl, logger)).To(BeFalse())
479+
exist, _, _, _ := controllers.DeplAssociatedClusterExist(context.TODO(), c, currentDepl, logger)
480+
Expect(exist).To(BeFalse())
478481

479482
sveltosCluster := libsveltosv1beta1.SveltosCluster{
480483
ObjectMeta: metav1.ObjectMeta{
@@ -483,8 +486,57 @@ spec:
483486
},
484487
}
485488
Expect(c.Create(context.TODO(), &sveltosCluster)).To(Succeed())
486-
Expect(controllers.AssociatedClusterExist(context.TODO(), c, currentDepl, logger)).To(BeTrue())
489+
exist, _, _, _ = controllers.DeplAssociatedClusterExist(context.TODO(), c, currentDepl, logger)
490+
Expect(exist).To(BeTrue())
491+
})
492+
493+
It("removeStaleResourceSummary removes stales resourceSummary instances",
494+
func() {
495+
clusterNamespace := randomString()
496+
clusterName := randomString()
497+
clusterType := libsveltosv1beta1.ClusterTypeSveltos
498+
499+
logger := textlogger.NewLogger(textlogger.NewConfig())
500+
501+
ns := &corev1.Namespace{
502+
ObjectMeta: metav1.ObjectMeta{
503+
Name: clusterNamespace,
504+
},
505+
}
506+
507+
Expect(testEnv.Create(context.TODO(), ns)).To(Succeed())
508+
Expect(waitForObject(context.TODO(), testEnv.Client, ns)).To(Succeed())
509+
510+
rs := fmt.Sprintf(`apiVersion: lib.projectsveltos.io/v1beta1
511+
kind: ResourceSummary
512+
metadata:
513+
labels:
514+
projectsveltos.io/cluster-summary-namespace: %s
515+
version.projectsveltos.io/clustername: %s
516+
version.projectsveltos.io/clustertype: %s
517+
name: deploy-cert-manager-sveltos-cluster1
518+
namespace: %s
519+
`, clusterNamespace, clusterName, strings.ToLower(string(clusterType)), clusterNamespace)
520+
521+
u, err := k8s_utils.GetUnstructured([]byte(rs))
522+
Expect(err).To(BeNil())
523+
524+
Expect(testEnv.Create(context.TODO(), u)).To(Succeed())
525+
Expect(waitForObject(context.TODO(), testEnv.Client, u)).To(Succeed())
526+
527+
currentRS := &libsveltosv1beta1.ResourceSummary{}
528+
529+
Expect(controllers.RemoveStaleResourceSummary(context.TODO(), clusterNamespace, clusterName,
530+
clusterType, logger)).To(Succeed())
487531

532+
Eventually(func() bool {
533+
err = testEnv.Get(context.TODO(),
534+
types.NamespacedName{Namespace: u.GetNamespace(), Name: u.GetName()}, currentRS)
535+
if err == nil {
536+
return false
537+
}
538+
return apierrors.IsNotFound(err)
539+
}, timeout, pollingInterval).Should(BeTrue())
488540
})
489541
})
490542

0 commit comments

Comments
 (0)