diff --git a/controllers/drplacementcontrol.go b/controllers/drplacementcontrol.go index 4a858fe46..7efb78106 100644 --- a/controllers/drplacementcontrol.go +++ b/controllers/drplacementcontrol.go @@ -33,6 +33,9 @@ const ( // Annotation for the last cluster on which the application was running LastAppDeploymentCluster = "drplacementcontrol.ramendr.openshift.io/last-app-deployment-cluster" + + // Annotation for application namespace on the managed cluster + DRPCAppNamespace = "drplacementcontrol.ramendr.openshift.io/app-namespace" ) var ( diff --git a/controllers/drplacementcontrol_controller.go b/controllers/drplacementcontrol_controller.go index 75624cac2..eb2f9ca9a 100644 --- a/controllers/drplacementcontrol_controller.go +++ b/controllers/drplacementcontrol_controller.go @@ -923,23 +923,32 @@ func (r *DRPlacementControlReconciler) getDRPolicy(ctx context.Context, return drPolicy, nil } -func (r DRPlacementControlReconciler) addLabelsAndFinalizers(ctx context.Context, +// updateObjectMetadata updates drpc labels, annotations and finalizer, and also updates placementObj finalizer +func (r DRPlacementControlReconciler) updateObjectMetadata(ctx context.Context, drpc *rmn.DRPlacementControl, placementObj client.Object, log logr.Logger, ) error { - // add label and finalizer to DRPC - labelAdded := rmnutil.AddLabel(drpc, rmnutil.OCMBackupLabelKey, rmnutil.OCMBackupLabelValue) - finalizerAdded := rmnutil.AddFinalizer(drpc, DRPCFinalizer) + update := false - if labelAdded || finalizerAdded { + update = rmnutil.AddLabel(drpc, rmnutil.OCMBackupLabelKey, rmnutil.OCMBackupLabelValue) + update = rmnutil.AddFinalizer(drpc, DRPCFinalizer) || update + + vrgNamespace, err := selectVRGNamespace(r.Client, r.Log, drpc, placementObj) + if err != nil { + return err + } + + update = rmnutil.AddAnnotation(drpc, DRPCAppNamespace, vrgNamespace) || update + + if update { if err := r.Update(ctx, drpc); err != nil { - log.Error(err, "Failed to add label and finalizer to drpc") + log.Error(err, "Failed to add annotations, labels, or finalizer to drpc") return fmt.Errorf("%w", err) } } // add finalizer to User PlacementRule/Placement - finalizerAdded = rmnutil.AddFinalizer(placementObj, DRPCFinalizer) + finalizerAdded := rmnutil.AddFinalizer(placementObj, DRPCFinalizer) if finalizerAdded { if err := r.Update(ctx, placementObj); err != nil { log.Error(err, "Failed to add finalizer to user placement rule") @@ -1147,7 +1156,7 @@ func (r *DRPlacementControlReconciler) updateAndSetOwner( return false, err } - if err := r.addLabelsAndFinalizers(ctx, drpc, usrPlacement, log); err != nil { + if err := r.updateObjectMetadata(ctx, drpc, usrPlacement, log); err != nil { return false, err } @@ -1960,6 +1969,10 @@ func selectVRGNamespace( drpc *rmn.DRPlacementControl, placementObj client.Object, ) (string, error) { + if drpc.GetAnnotations() != nil && drpc.GetAnnotations()[DRPCAppNamespace] != "" { + return drpc.GetAnnotations()[DRPCAppNamespace], nil + } + switch placementObj.(type) { case *clrapiv1beta1.Placement: vrgNamespace, err := getApplicationDestinationNamespace(client, log, placementObj) diff --git a/controllers/drplacementcontrol_controller_test.go b/controllers/drplacementcontrol_controller_test.go index 699fd372a..7d16cc433 100644 --- a/controllers/drplacementcontrol_controller_test.go +++ b/controllers/drplacementcontrol_controller_test.go @@ -1705,6 +1705,7 @@ func verifyInitialDRPCDeployment(userPlacement client.Object, preferredCluster s _, condition := getDRPCCondition(&latestDRPC.Status, rmn.ConditionAvailable) Expect(condition.Reason).To(Equal(string(rmn.Deployed))) Expect(latestDRPC.GetAnnotations()[controllers.LastAppDeploymentCluster]).To(Equal(preferredCluster)) + Expect(latestDRPC.GetAnnotations()[controllers.DRPCAppNamespace]).To(Equal(getVRGNameSpace())) } func verifyFailoverToSecondary(placementObj client.Object, toCluster string, diff --git a/controllers/util/misc.go b/controllers/util/misc.go index 86f1e5087..652d431be 100644 --- a/controllers/util/misc.go +++ b/controllers/util/misc.go @@ -72,6 +72,24 @@ func AddLabel(obj client.Object, key, value string) bool { return !labelAdded } +func AddAnnotation(obj client.Object, key, value string) bool { + const added = true + + annotations := obj.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + + if keyValue, ok := annotations[key]; !ok || keyValue != value { + annotations[key] = value + obj.SetAnnotations(annotations) + + return added + } + + return !added +} + func AddFinalizer(obj client.Object, finalizer string) bool { const finalizerAdded = true