Skip to content

Commit

Permalink
Merge pull request #449 from red-hat-storage/sync_us--main
Browse files Browse the repository at this point in the history
Syncing latest changes from upstream main for ramen
  • Loading branch information
ShyamsundarR authored Feb 6, 2025
2 parents df3bcda + 0fd2352 commit 140fa6c
Show file tree
Hide file tree
Showing 13 changed files with 627 additions and 206 deletions.
8 changes: 8 additions & 0 deletions config/dr-cluster/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ rules:
- get
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- get
- list
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
Expand Down
8 changes: 8 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ rules:
- get
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- get
- list
- watch
- apiGroups:
- cluster.open-cluster-management.io
resources:
Expand Down
8 changes: 4 additions & 4 deletions docs/e2e.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ To run all the tests:

### Run specific E2E tests

The `-run` option is commonly used when debugging a failing test, developing
The `-test.run` option is commonly used when debugging a failing test, developing
a new test, or working on a new deployer or workload. It allows to selectively
execute specific tests by matching full test names using regular expressions,
making it easier to focus on specific scenarios.
Expand All @@ -69,7 +69,7 @@ available tests.
Example:

```sh
./run.sh -run TestSuites/Exhaustive/subscr-deploy-rbd-busybox
./run.sh -test.run TestSuites/Exhaustive/subscr-deploy-rbd-busybox
```

This command runs the specific test for subscription based RBD busybox application.
Expand All @@ -79,7 +79,7 @@ This command runs the specific test for subscription based RBD busybox applicati
Example:

```sh
./run.sh -run //appset
./run.sh -test.run //appset
```

This command runs all tests related to ApplicationSet, covering both RBD and
Expand All @@ -90,7 +90,7 @@ CephFS PVC based applications. Useful when focusing on a specific deployer.
Example:

```sh
./run.sh -run //rbd
./run.sh -test.run //rbd
```

This command runs all tests related to RBD PVCs across all deployers.
Expand Down
10 changes: 3 additions & 7 deletions e2e/config.yaml.sample
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
---
# Configuration file for RamenDR E2E testing on Regional DR.

# Name of the channel used for the Channel CR. This channel is used by
# OCM to pull the application from the specified Git repository.
channelname: "ramen-gitops"
# Configuration for RamenDR End to End testing.

---
# Namespace where the channel CR will be created.
channelnamespace: "ramen-samples"
channelnamespace: "e2e-gitops"

# Git repository URL containing application manifests to be deployed on
# the clusters.
Expand Down
85 changes: 57 additions & 28 deletions e2e/dractions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,43 +112,83 @@ func DisableProtection(ctx types.Context) error {
}

func Failover(ctx types.Context) error {
d := ctx.Deployer()
if d.IsDiscovered() {
return FailoverDiscoveredApps(ctx)
}

managementNamespace := ctx.ManagementNamespace()
log := ctx.Logger()
name := ctx.Name()

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

log.Infof("Failing over workload in namespace %q", managementNamespace)
currentCluster, err := getCurrentCluster(client, managementNamespace, name)
if err != nil {
return err
}

return failoverRelocate(ctx, ramen.ActionFailover, ramen.FailedOver)
drpolicy, err := util.GetDRPolicy(client, drPolicyName)
if err != nil {
return err
}

targetCluster, err := getTargetCluster(client, managementNamespace, drpcName, drpolicy)
if err != nil {
return err
}

log.Infof("Failing over workload from cluster %q to cluster %q", currentCluster, targetCluster)

return failoverRelocate(ctx, ramen.ActionFailover, ramen.FailedOver, currentCluster, targetCluster)
}

// Determine DRPC
// Check Placement
// Relocate to Primary in DRPolicy as the PrimaryCluster
// Update DRPC
func Relocate(ctx types.Context) error {
d := ctx.Deployer()
if d.IsDiscovered() {
return RelocateDiscoveredApps(ctx)
}

managementNamespace := ctx.ManagementNamespace()
log := ctx.Logger()
name := ctx.Name()

log.Infof("Relocating workload in namespace %q", managementNamespace)
drpcName := name
client := util.Ctx.Hub.Client
drPolicyName := util.DefaultDRPolicyName

return failoverRelocate(ctx, ramen.ActionRelocate, ramen.Relocated)
currentCluster, err := getCurrentCluster(client, managementNamespace, name)
if err != nil {
return err
}

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

targetCluster, err := getTargetCluster(client, managementNamespace, drpcName, drpolicy)
if err != nil {
return err
}

log.Infof("Relocating workload from cluster %q to cluster %q", currentCluster, targetCluster)

return failoverRelocate(ctx, ramen.ActionRelocate, ramen.Relocated, currentCluster, targetCluster)
}

func failoverRelocate(ctx types.Context, action ramen.DRAction, state ramen.DRState) error {
func failoverRelocate(ctx types.Context,
action ramen.DRAction,
state ramen.DRState,
currentCluster string,
targetCluster string,
) error {
d := ctx.Deployer()
if d.IsDiscovered() {
return failoverRelocateDiscoveredApps(ctx, action, state, currentCluster, targetCluster)
}

drpcName := ctx.Name()
managementNamespace := ctx.ManagementNamespace()
client := util.Ctx.Hub.Client

if err := waitAndUpdateDRPC(ctx, client, managementNamespace, drpcName, action); err != nil {
if err := waitAndUpdateDRPC(ctx, client, managementNamespace, drpcName, action, targetCluster); err != nil {
return err
}

Expand All @@ -164,6 +204,7 @@ func waitAndUpdateDRPC(
client client.Client,
namespace, drpcName string,
action ramen.DRAction,
targetCluster string,
) error {
log := ctx.Logger()

Expand All @@ -172,18 +213,6 @@ func waitAndUpdateDRPC(
return err
}

drPolicyName := util.DefaultDRPolicyName

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

targetCluster, err := getTargetCluster(client, namespace, drpcName, drpolicy)
if err != nil {
return err
}

log.Info("Updating drpc " + strings.ToLower(string(action)) + " to " + targetCluster)

return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
Expand Down
38 changes: 8 additions & 30 deletions e2e/dractions/discovered.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,14 @@ func DisableProtectionDiscoveredApps(ctx types.Context) error {
return deployers.DeleteManagedClusterSetBinding(ctx, deployers.McsbName, managementNamespace)
}

func FailoverDiscoveredApps(ctx types.Context) error {
log := ctx.Logger()
managementNamespace := ctx.ManagementNamespace()

log.Infof("Failing over workload in namespace %q", managementNamespace)

return failoverRelocateDiscoveredApps(ctx, ramen.ActionFailover, ramen.FailedOver)
}

func RelocateDiscoveredApps(ctx types.Context) error {
log := ctx.Logger()
managementNamespace := ctx.ManagementNamespace()

log.Infof("Relocating workload in namespace %q", managementNamespace)

return failoverRelocateDiscoveredApps(ctx, ramen.ActionRelocate, ramen.Relocated)
}

// nolint:funlen,cyclop
func failoverRelocateDiscoveredApps(ctx types.Context, action ramen.DRAction, state ramen.DRState) error {
func failoverRelocateDiscoveredApps(
ctx types.Context,
action ramen.DRAction,
state ramen.DRState,
currentCluster string,
targetCluster string,
) error {
name := ctx.Name()
log := ctx.Logger()
managementNamespace := ctx.ManagementNamespace()
Expand All @@ -116,24 +104,14 @@ func failoverRelocateDiscoveredApps(ctx types.Context, action ramen.DRAction, st
drpcName := name
client := util.Ctx.Hub.Client

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

drPolicyName := util.DefaultDRPolicyName

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

targetCluster, err := getTargetCluster(client, managementNamespace, drpcName, drpolicy)
if err != nil {
return err
}

if err := waitAndUpdateDRPC(ctx, client, managementNamespace, drpcName, action); err != nil {
if err := waitAndUpdateDRPC(ctx, client, managementNamespace, drpcName, action, targetCluster); err != nil {
return err
}

Expand Down
8 changes: 4 additions & 4 deletions e2e/util/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ func createChannel() error {
return err
}

Ctx.Log.Infof("Channel %q already exists", GetChannelName())
Ctx.Log.Debugf("Channel \"%s/%s\" already exists", GetChannelNamespace(), GetChannelName())
} else {
Ctx.Log.Infof("Created channel %q", GetChannelName())
Ctx.Log.Infof("Created channel \"%s/%s\"", GetChannelNamespace(), GetChannelName())
}

return nil
Expand All @@ -70,9 +70,9 @@ func deleteChannel() error {
return err
}

Ctx.Log.Infof("Channel %q not found", GetChannelName())
Ctx.Log.Debugf("Channel \"%s/%s\" not found", GetChannelNamespace(), GetChannelName())
} else {
Ctx.Log.Infof("Channel %q is deleted", GetChannelName())
Ctx.Log.Infof("Deleted channel \"%s/%s\"", GetChannelNamespace(), GetChannelName())
}

return nil
Expand Down
36 changes: 26 additions & 10 deletions e2e/util/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ package util

import (
"fmt"
"regexp"
"strings"

"github.com/spf13/viper"
"go.uber.org/zap"
)

const (
defaultChannelName = "ramen-gitops"
defaultChannelNamespace = "ramen-samples"
defaultChannelNamespace = "e2e-gitops"
defaultGitURL = "https://github.com/RamenDR/ocm-ramen-samples.git"
)

Expand All @@ -23,27 +24,28 @@ type PVCSpec struct {
UnsupportedDeployers []string
}
type TestConfig struct {
ChannelName string
// User configurable values.
ChannelNamespace string
GitURL string
Clusters map[string]struct {
KubeconfigPath string
}
PVCSpecs []PVCSpec

// Generated values
channelName string
}

var config = &TestConfig{}
var (
resourceNameForbiddenCharacters *regexp.Regexp
config = &TestConfig{}
)

//nolint:cyclop
func ReadConfig(log *zap.SugaredLogger, configFile string) error {
viper.SetDefault("ChannelName", defaultChannelName)
viper.SetDefault("ChannelNamespace", defaultChannelNamespace)
viper.SetDefault("GitURL", defaultGitURL)

if err := viper.BindEnv("ChannelName", "ChannelName"); err != nil {
return (err)
}

if err := viper.BindEnv("ChannelNamespace", "ChannelNamespace"); err != nil {
return (err)
}
Expand Down Expand Up @@ -84,11 +86,13 @@ func ReadConfig(log *zap.SugaredLogger, configFile string) error {
return fmt.Errorf("failed to find pvcs in configuration")
}

config.channelName = resourceName(config.GitURL)

return nil
}

func GetChannelName() string {
return config.ChannelName
return config.channelName
}

func GetChannelNamespace() string {
Expand All @@ -102,3 +106,15 @@ func GetGitURL() string {
func GetPVCSpecs() []PVCSpec {
return config.PVCSpecs
}

// resourceName convert a URL to conventional k8s resource name:
// "https://github.com/foo/bar.git" -> "https-github-com-foo-bar-git"
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
func resourceName(url string) string {
return strings.ToLower(resourceNameForbiddenCharacters.ReplaceAllString(url, "-"))
}

func init() {
// Matches one of more forbidden characters, so we can replace them with single replacement character.
resourceNameForbiddenCharacters = regexp.MustCompile(`[^\w]+`)
}
Loading

0 comments on commit 140fa6c

Please sign in to comment.