From c8d3cd47bb2873e68fdf77b56388ae4f9b7002a2 Mon Sep 17 00:00:00 2001 From: Coleen Iona Quadros Date: Mon, 17 Jun 2024 19:37:02 +0200 Subject: [PATCH] Wait for vendor label on managedcluster object (#1476) * wait for vendor label on managedcluster object Signed-off-by: Coleen Iona Quadros * wait for vendor label on managedcluster object Signed-off-by: Coleen Iona Quadros * fix test Signed-off-by: Coleen Iona Quadros * do not create managedclusteraddon for local cluster Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * logs Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * logs Signed-off-by: Coleen Iona Quadros * logs Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros * refactor Signed-off-by: Coleen Iona Quadros --------- Signed-off-by: Coleen Iona Quadros --- .../placementrule/placementrule_controller.go | 16 ++++ .../placementrule/predicate_func.go | 12 ++- .../placementrule/predicate_func_test.go | 81 +++++++++++++++++++ 3 files changed, 105 insertions(+), 4 deletions(-) diff --git a/operators/multiclusterobservability/controllers/placementrule/placementrule_controller.go b/operators/multiclusterobservability/controllers/placementrule/placementrule_controller.go index 878e78563..8142209ed 100644 --- a/operators/multiclusterobservability/controllers/placementrule/placementrule_controller.go +++ b/operators/multiclusterobservability/controllers/placementrule/placementrule_controller.go @@ -197,6 +197,7 @@ func (r *PlacementRuleReconciler) Reconcile(ctx context.Context, req ctrl.Reques if operatorconfig.IsMCOTerminating { delete(managedClusterList, "local-cluster") } + if !deleteAll { if err := createAllRelatedRes( r.Client, @@ -583,6 +584,21 @@ func deleteManagedClusterRes(c client.Client, namespace string) error { return nil } +func areManagedClusterLabelsReady(obj client.Object) bool { + vendor, vendorOk := obj.GetLabels()["vendor"] + openshiftVendor := vendor == "OpenShift" + + if _, openshiftVersionPresent := obj.GetLabels()["openshiftVersion"]; openshiftVersionPresent && openshiftVendor { + return true + } + if vendorOk && vendor != "auto-detect" { + return true + } + + log.Info("ManagedCluster labels are not ready", "cluster", obj.GetName()) + return false + +} func updateManagedClusterList(obj client.Object) { managedClusterListMutex.Lock() defer managedClusterListMutex.Unlock() diff --git a/operators/multiclusterobservability/controllers/placementrule/predicate_func.go b/operators/multiclusterobservability/controllers/placementrule/predicate_func.go index 013c1ce11..626cea672 100644 --- a/operators/multiclusterobservability/controllers/placementrule/predicate_func.go +++ b/operators/multiclusterobservability/controllers/placementrule/predicate_func.go @@ -34,10 +34,11 @@ func getClusterPreds() predicate.Funcs { if isAutomaticAddonInstallationDisabled(e.Object) { return false } - if e.Object.GetName() != "local-cluster" { - updateManagedClusterList(e.Object) - } updateManagedClusterImageRegistry(e.Object) + if !areManagedClusterLabelsReady(e.Object) { + return false + } + updateManagedClusterList(e.Object) return true } @@ -65,8 +66,11 @@ func getClusterPreds() predicate.Funcs { delete(managedClusterImageRegistry, e.ObjectNew.GetName()) managedClusterImageRegistryMutex.Unlock() } else { - updateManagedClusterList(e.ObjectNew) updateManagedClusterImageRegistry(e.ObjectNew) + if !areManagedClusterLabelsReady(e.ObjectNew) { + return false + } + updateManagedClusterList(e.ObjectNew) } return true diff --git a/operators/multiclusterobservability/controllers/placementrule/predicate_func_test.go b/operators/multiclusterobservability/controllers/placementrule/predicate_func_test.go index 157027733..b0cc58bd4 100644 --- a/operators/multiclusterobservability/controllers/placementrule/predicate_func_test.go +++ b/operators/multiclusterobservability/controllers/placementrule/predicate_func_test.go @@ -71,6 +71,7 @@ func TestClusterPred(t *testing.T) { Name: name, Namespace: c.namespace, Annotations: c.annotations, + Labels: map[string]string{"vendor": "OpenShift", "openshiftVersion": "4.6.0"}, }, Spec: appsv1.DeploymentSpec{ Replicas: int32Ptr(2), @@ -96,6 +97,7 @@ func TestClusterPred(t *testing.T) { ResourceVersion: "2", DeletionTimestamp: c.deletionTimestamp, Annotations: c.annotations, + Labels: map[string]string{"vendor": "OpenShift", "openshiftVersion": "4.6.0"}, }, }, ObjectOld: &appsv1.Deployment{ @@ -148,6 +150,85 @@ func TestClusterPred(t *testing.T) { } } +func TestManagedClusterLabelReady(t *testing.T) { + + name := "test-obj" + caseList := []struct { + caseName string + namespace string + annotations map[string]string + deletionTimestamp *metav1.Time + expectedCreate bool + expectedUpdate bool + expectedDelete bool + }{ + { + caseName: "ManagedCluster with vendor label", + namespace: testNamespace, + expectedCreate: false, + expectedUpdate: true, + }, + } + + for _, c := range caseList { + t.Run(c.caseName, func(t *testing.T) { + pred := getClusterPreds() + create_event := event.CreateEvent{ + Object: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: c.namespace, + Annotations: c.annotations, + Labels: map[string]string{"vendor": "auto-detect"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: int32Ptr(2), + }, + }, + } + + if c.expectedCreate { + if !pred.CreateFunc(create_event) { + t.Fatalf("pre func return false on applied createevent in case: (%v)", c.caseName) + } + } else { + if pred.CreateFunc(create_event) { + t.Fatalf("pre func return true on non-applied createevent in case: (%v)", c.caseName) + } + } + update_event := event.UpdateEvent{ + ObjectNew: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: c.namespace, + ResourceVersion: "2", + DeletionTimestamp: c.deletionTimestamp, + Annotations: c.annotations, + Labels: map[string]string{"vendor": "OpenShift", "openshiftVersion": "4.6.0"}, + }, + }, + ObjectOld: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: c.namespace, + ResourceVersion: "1", + }, + }, + } + + if c.expectedUpdate { + if !pred.UpdateFunc(update_event) { + t.Fatalf("pre func return false on applied update event in case: (%v)", c.caseName) + } + } else { + if pred.UpdateFunc(update_event) { + t.Fatalf("pre func return true on non-applied updateevent in case: (%v)", c.caseName) + } + } + }) + } +} + func TestAddOnDeploymentConfigPredicate(t *testing.T) { name := "test-obj" caseList := []struct {