Skip to content

Commit

Permalink
e2e: move cluster retrieval functions to util/placement.go
Browse files Browse the repository at this point in the history
- Moved functions responsible for retrieving the current cluster from dractions/retry.go to util/placement.go
- Moved getPlacement from dractions/crug.go to util/placement.go
- Refactored getTargetCluster to get drPolicy and also changed to pass currentCluster as argument.
- Made GetCurrentCluster(added doc) and GetPlacement functions public.
- Updated references to use the new public functions.

Signed-off-by: Parikshith <[email protected]>
  • Loading branch information
parikshithb committed Feb 18, 2025
1 parent a7ca2eb commit 5a40e73
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 114 deletions.
27 changes: 6 additions & 21 deletions e2e/dractions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,15 @@ func EnableProtection(ctx types.Context) error {
placementName := name
drpcName := name

placementDecision, err := waitPlacementDecision(util.Ctx.Hub.Client, managementNamespace, placementName)
clusterName, err := util.GetCurrentCluster(util.Ctx.Hub.Client, managementNamespace, placementName)
if err != nil {
return err
}

clusterName := placementDecision.Status.Decisions[0].ClusterName
log.Debugf("Workload running on cluster %q", clusterName)

err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
placement, err := getPlacement(util.Ctx.Hub.Client, managementNamespace, placementName)
placement, err := util.GetPlacement(util.Ctx.Hub.Client, managementNamespace, placementName)
if err != nil {
return err
}
Expand Down Expand Up @@ -117,21 +116,14 @@ func Failover(ctx types.Context) error {
log := ctx.Logger()
name := ctx.Name()

drpcName := name
client := util.Ctx.Hub.Client
drPolicyName := util.DefaultDRPolicyName

currentCluster, err := getCurrentCluster(client, managementNamespace, name)
if err != nil {
return err
}

drpolicy, err := util.GetDRPolicy(client, drPolicyName)
currentCluster, err := util.GetCurrentCluster(client, managementNamespace, name)
if err != nil {
return err
}

targetCluster, err := getTargetCluster(client, managementNamespace, drpcName, drpolicy)
targetCluster, err := getTargetCluster(client, currentCluster)
if err != nil {
return err
}
Expand All @@ -150,21 +142,14 @@ func Relocate(ctx types.Context) error {
log := ctx.Logger()
name := ctx.Name()

drpcName := name
client := util.Ctx.Hub.Client
drPolicyName := util.DefaultDRPolicyName

currentCluster, err := getCurrentCluster(client, managementNamespace, name)
if err != nil {
return err
}

drpolicy, err := util.GetDRPolicy(client, drPolicyName)
currentCluster, err := util.GetCurrentCluster(client, managementNamespace, name)
if err != nil {
return err
}

targetCluster, err := getTargetCluster(client, managementNamespace, drpcName, drpolicy)
targetCluster, err := getTargetCluster(client, currentCluster)
if err != nil {
return err
}
Expand Down
12 changes: 0 additions & 12 deletions e2e/dractions/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ import (
"sigs.k8s.io/yaml"
)

func getPlacement(client client.Client, namespace, name string) (*clusterv1beta1.Placement, error) {
placement := &clusterv1beta1.Placement{}
key := k8stypes.NamespacedName{Namespace: namespace, Name: name}

err := client.Get(context.Background(), key, placement)
if err != nil {
return nil, err
}

return placement, nil
}

func updatePlacement(client client.Client, placement *clusterv1beta1.Placement) error {
return client.Update(context.Background(), placement)
}
Expand Down
83 changes: 2 additions & 81 deletions e2e/dractions/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package dractions

import (
"context"
"fmt"
"time"

Expand All @@ -14,38 +13,9 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"open-cluster-management.io/api/cluster/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// waitPlacementDecision waits until we have a placement decision and returns the placement decision object.
func waitPlacementDecision(client client.Client, namespace string, placementName string,
) (*v1beta1.PlacementDecision, error) {
startTime := time.Now()

for {
placement, err := getPlacement(client, namespace, placementName)
if err != nil {
return nil, err
}

placementDecision, err := getPlacementDecisionFromPlacement(client, placement)
if err != nil {
return nil, err
}

if placementDecision != nil && len(placementDecision.Status.Decisions) > 0 {
return placementDecision, nil
}

if time.Since(startTime) > util.Timeout {
return nil, fmt.Errorf("timeout waiting for placement decisions for %q ", placementName)
}

time.Sleep(util.RetryInterval)
}
}

func waitDRPCReady(ctx types.Context, client client.Client, namespace string, drpcName string) error {
log := ctx.Logger()
startTime := time.Now()
Expand Down Expand Up @@ -109,15 +79,6 @@ func waitDRPCPhase(ctx types.Context, client client.Client, namespace, name stri
}
}

func getCurrentCluster(client client.Client, namespace string, placementName string) (string, error) {
placementDecision, err := waitPlacementDecision(client, namespace, placementName)
if err != nil {
return "", err
}

return placementDecision.Status.Decisions[0].ClusterName, nil
}

// return dr cluster client
func getDRClusterClient(clusterName string, drpolicy *ramen.DRPolicy) client.Client {
if clusterName == drpolicy.Spec.DRClusters[0] {
Expand All @@ -127,8 +88,8 @@ func getDRClusterClient(clusterName string, drpolicy *ramen.DRPolicy) client.Cli
return util.Ctx.C2.Client
}

func getTargetCluster(client client.Client, namespace, placementName string, drpolicy *ramen.DRPolicy) (string, error) {
currentCluster, err := getCurrentCluster(client, namespace, placementName)
func getTargetCluster(client client.Client, currentCluster string) (string, error) {
drpolicy, err := util.GetDRPolicy(client, util.DefaultDRPolicyName)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -202,43 +163,3 @@ func waitDRPCProgression(
time.Sleep(util.RetryInterval)
}
}

func getPlacementDecisionFromPlacement(ctrlClient client.Client, placement *v1beta1.Placement,
) (*v1beta1.PlacementDecision, error) {
matchLabels := map[string]string{
v1beta1.PlacementLabel: placement.GetName(),
}

listOptions := []client.ListOption{
client.InNamespace(placement.GetNamespace()),
client.MatchingLabels(matchLabels),
}

plDecisions := &v1beta1.PlacementDecisionList{}
if err := ctrlClient.List(context.Background(), plDecisions, listOptions...); err != nil {
return nil, fmt.Errorf("failed to list PlacementDecisions (placement: %s)",
placement.GetNamespace()+"/"+placement.GetName())
}

if len(plDecisions.Items) == 0 {
return nil, nil
}

if len(plDecisions.Items) > 1 {
return nil, fmt.Errorf("multiple PlacementDecisions found for Placement (count: %d, placement: %s)",
len(plDecisions.Items), placement.GetNamespace()+"/"+placement.GetName())
}

plDecision := plDecisions.Items[0]
// r.Log.Info("Found ClusterDecision", "ClsDedicision", plDecision.Status.Decisions)

if len(plDecision.Status.Decisions) > 1 {
return nil, fmt.Errorf("multiple placements found in PlacementDecision"+
" (count: %d, Placement: %s, PlacementDecision: %s)",
len(plDecision.Status.Decisions),
placement.GetNamespace()+"/"+placement.GetName(),
plDecision.GetName()+"/"+plDecision.GetNamespace())
}

return &plDecision, nil
}
107 changes: 107 additions & 0 deletions e2e/util/placement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// SPDX-FileCopyrightText: The RamenDR authors
// SPDX-License-Identifier: Apache-2.0

package util

import (
"context"
"fmt"
"time"

k8stypes "k8s.io/apimachinery/pkg/types"
"open-cluster-management.io/api/cluster/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// GetCurrentCluster returns the name of the cluster where the workload is currently placed,
// based on the PlacementDecision for the given Placement resource.
// Assumes the PlacementDecision exists with a Decision.
// Not applicable for discovered apps before enabling protection, as no Placement exists.
func GetCurrentCluster(client client.Client, namespace string, placementName string) (string, error) {
placementDecision, err := waitPlacementDecision(client, namespace, placementName)
if err != nil {
return "", err
}

return placementDecision.Status.Decisions[0].ClusterName, nil
}

func GetPlacement(client client.Client, namespace, name string) (*v1beta1.Placement, error) {
placement := &v1beta1.Placement{}
key := k8stypes.NamespacedName{Namespace: namespace, Name: name}

err := client.Get(context.Background(), key, placement)
if err != nil {
return nil, err
}

return placement, nil
}

// waitPlacementDecision waits until we have a placement decision and returns the placement decision object.
func waitPlacementDecision(client client.Client, namespace string, placementName string,
) (*v1beta1.PlacementDecision, error) {
startTime := time.Now()

for {
placement, err := GetPlacement(client, namespace, placementName)
if err != nil {
return nil, err
}

placementDecision, err := getPlacementDecisionFromPlacement(client, placement)
if err != nil {
return nil, err
}

if placementDecision != nil && len(placementDecision.Status.Decisions) > 0 {
return placementDecision, nil
}

if time.Since(startTime) > Timeout {
return nil, fmt.Errorf("timeout waiting for placement decisions for %q ", placementName)
}

time.Sleep(RetryInterval)
}
}

func getPlacementDecisionFromPlacement(ctrlClient client.Client, placement *v1beta1.Placement,
) (*v1beta1.PlacementDecision, error) {
matchLabels := map[string]string{
v1beta1.PlacementLabel: placement.GetName(),
}

listOptions := []client.ListOption{
client.InNamespace(placement.GetNamespace()),
client.MatchingLabels(matchLabels),
}

plDecisions := &v1beta1.PlacementDecisionList{}
if err := ctrlClient.List(context.Background(), plDecisions, listOptions...); err != nil {
return nil, fmt.Errorf("failed to list PlacementDecisions (placement: %s)",
placement.GetNamespace()+"/"+placement.GetName())
}

if len(plDecisions.Items) == 0 {
return nil, nil
}

if len(plDecisions.Items) > 1 {
return nil, fmt.Errorf("multiple PlacementDecisions found for Placement (count: %d, placement: %s)",
len(plDecisions.Items), placement.GetNamespace()+"/"+placement.GetName())
}

plDecision := plDecisions.Items[0]
// r.Log.Info("Found ClusterDecision", "ClsDedicision", plDecision.Status.Decisions)

if len(plDecision.Status.Decisions) > 1 {
return nil, fmt.Errorf("multiple placements found in PlacementDecision"+
" (count: %d, Placement: %s, PlacementDecision: %s)",
len(plDecision.Status.Decisions),
placement.GetNamespace()+"/"+placement.GetName(),
plDecision.GetName()+"/"+plDecision.GetNamespace())
}

return &plDecision, nil
}

0 comments on commit 5a40e73

Please sign in to comment.