Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable watching multiple namespaces #1649

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add test of multiple namespaces
  • Loading branch information
ryu-sato committed Dec 28, 2024
commit c1a8ee031e2d5de732dabc80fe1a6c499d469b5f
11 changes: 8 additions & 3 deletions pkg/helm/helm.go
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ func DependencyUpdate(chartPath string) error {
}

// Install a helm chert at the given path with the given name and the provided set arguments.
func Install(chartPath, chartName string, flags map[string]string, templateValues map[string]string) error {
func Install(chartPath, chartName string, flags map[string]string, templateValues map[string]interface{}) error {
helmArgs := []string{"install"}
helmArgs = append(helmArgs, chartName, chartPath)
for flagKey, flagValue := range flags {
@@ -53,10 +53,15 @@ func executeHelmCommand(args []string, messagePredicate func(string) bool) error

// mapToHelmValuesArg accepts a map of string to string and returns a list of arguments
// that can be passed to a shell helm command.
func mapToHelmValuesArg(m map[string]string) []string {
func mapToHelmValuesArg(m map[string]interface{}) []string {
var args []string
for k, v := range m {
args = append(args, "--set", fmt.Sprintf("%s=%s", k, v))
if strValue, ok := v.(string); ok {
args = append(args, "--set", fmt.Sprintf("%s=%s", k, strValue))
}
if sliceValue, ok := v.([]string); ok {
args = append(args, "--set", fmt.Sprintf("%s={%s}", k, strings.Join(sliceValue, ",")))
}
}
return args
}
7 changes: 7 additions & 0 deletions pkg/util/envvar/envvars.go
Original file line number Diff line number Diff line change
@@ -41,3 +41,10 @@ func ReadBool(envVarName string) bool {
envVar := GetEnvOrDefault(envVarName, "false")
return strings.TrimSpace(strings.ToLower(envVar)) == "true"
}

func ReadCSVOrDefault(envVarName string, defaultValue []string) []string {
if val, ok := os.LookupEnv(envVarName); ok {
return strings.Split(val, ",")
}
return defaultValue
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package replica_set_multiple_namespaces

import (
"context"
"fmt"
"os"
"testing"
"strings"

"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/mongotester"

e2eutil "github.com/mongodb/mongodb-kubernetes-operator/test/e2e"
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/mongodbtests"
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/setup"
)

const (
testWatchNamespaceEnvName = "TEST_WATCH_NAMESPACE"
testMongoDBNamespaces = "ns1,ns2"
)

func TestMain(m *testing.M) {
code, err := e2eutil.RunTest(m)
if err != nil {
fmt.Println(err)
}
os.Exit(code)
}

// TestReplicaSetMultipleNamespaces creates two MongoDB resources in separate
// namespaces to be processed by the Operator simultaneously.
func TestReplicaSetMultipleNamespaces(t *testing.T) {
t.Setenv(testWatchNamespaceEnvName, testMongoDBNamespaces)
ctx := context.Background()

testCtx := setup.Setup(ctx, t)
defer testCtx.Teardown()

for _, namespace := range strings.Split(testMongoDBNamespaces, ",") {
mdb, user := e2eutil.NewTestMongoDB(testCtx, "mdb", namespace)

_, err := setup.GeneratePasswordForUser(testCtx, user, namespace)
if err != nil {
t.Fatal(err)
}

tester, err := mongotester.FromResource(ctx, t, mdb)
if err != nil {
t.Fatal(err)
}

t.Run("Create MongoDB Resource mdb", mongodbtests.CreateMongoDBResource(&mdb, testCtx))

t.Run("mdb: Basic tests", mongodbtests.BasicFunctionality(ctx, &mdb))

t.Run("mdb: Test Basic Connectivity", tester.ConnectivitySucceeds())

t.Run("mdb: AutomationConfig has the correct version", mongodbtests.AutomationConfigVersionHasTheExpectedVersion(ctx, &mdb, 1))

t.Run("mdb: Ensure Authentication", tester.EnsureAuthenticationIsConfigured(3))
}
}
39 changes: 29 additions & 10 deletions test/e2e/setup/setup.go
Original file line number Diff line number Diff line change
@@ -49,6 +49,9 @@ func Setup(ctx context.Context, t *testing.T) *e2eutil.TestContext {
}

config := LoadTestConfigFromEnv()
if err := ensureWatchNamespaces(testCtx, config); err != nil {
t.Fatal(err)
}
if err := DeployOperator(ctx, config, "mdb", false, false); err != nil {
t.Fatal(err)
}
@@ -57,13 +60,16 @@ func Setup(ctx context.Context, t *testing.T) *e2eutil.TestContext {
}

func SetupWithTLS(ctx context.Context, t *testing.T, resourceName string, additionalHelmArgs ...HelmArg) (*e2eutil.TestContext, TestConfig) {
textCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv))
testCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv))

if err != nil {
t.Fatal(err)
}

config := LoadTestConfigFromEnv()
if err := ensureWatchNamespaces(testCtx, config); err != nil {
t.Fatal(err)
}
if err := deployCertManager(config); err != nil {
t.Fatal(err)
}
@@ -72,7 +78,7 @@ func SetupWithTLS(ctx context.Context, t *testing.T, resourceName string, additi
t.Fatal(err)
}

return textCtx, config
return testCtx, config
}

func SetupWithTestConfig(ctx context.Context, t *testing.T, testConfig TestConfig, withTLS, defaultOperator bool, resourceName string) *e2eutil.TestContext {
@@ -88,6 +94,9 @@ func SetupWithTestConfig(ctx context.Context, t *testing.T, testConfig TestConfi
}
}

if err := ensureWatchNamespaces(testCtx, testConfig); err != nil {
t.Fatal(err)
}
if err := DeployOperator(ctx, testConfig, resourceName, withTLS, defaultOperator); err != nil {
t.Fatal(err)
}
@@ -138,17 +147,17 @@ func extractRegistryNameAndVersion(fullImage string) (string, string, string) {
}

// getHelmArgs returns a map of helm arguments that are required to install the operator.
func getHelmArgs(testConfig TestConfig, watchNamespace string, resourceName string, withTLS bool, defaultOperator bool, additionalHelmArgs ...HelmArg) map[string]string {
func getHelmArgs(testConfig TestConfig, watchNamespaces []string, resourceName string, withTLS bool, defaultOperator bool, additionalHelmArgs ...HelmArg) map[string]interface{} {
agentRegistry, agentName, agentVersion := extractRegistryNameAndVersion(testConfig.AgentImage)
versionUpgradeHookRegistry, versionUpgradeHookName, versionUpgradeHookVersion := extractRegistryNameAndVersion(testConfig.VersionUpgradeHookImage)
readinessProbeRegistry, readinessProbeName, readinessProbeVersion := extractRegistryNameAndVersion(testConfig.ReadinessProbeImage)
operatorRegistry, operatorName, operatorVersion := extractRegistryNameAndVersion(testConfig.OperatorImage)

helmArgs := make(map[string]string)
helmArgs := make(map[string]interface{})

helmArgs["namespace"] = testConfig.Namespace

helmArgs["operator.watchNamespace"] = watchNamespace
helmArgs["operator.watchNamespaces"] = watchNamespaces

if !defaultOperator {
helmArgs["operator.operatorImageName"] = operatorName
@@ -189,18 +198,18 @@ func getHelmArgs(testConfig TestConfig, watchNamespace string, resourceName stri
func DeployOperator(ctx context.Context, config TestConfig, resourceName string, withTLS bool, defaultOperator bool, additionalHelmArgs ...HelmArg) error {
e2eutil.OperatorNamespace = config.Namespace
fmt.Printf("Setting operator namespace to %s\n", e2eutil.OperatorNamespace)
watchNamespace := config.Namespace
watchNamespaces := config.WatchNamespaces
if config.ClusterWide {
watchNamespace = "*"
watchNamespaces = []string{"*"}
}
fmt.Printf("Setting namespace to watch to %s\n", watchNamespace)
fmt.Printf("Setting namespace to watch to %s\n", strings.Join(watchNamespaces, ","))

helmChartName := "mongodb-kubernetes-operator"
if err := helm.Uninstall(helmChartName, config.Namespace); err != nil {
return err
}

helmArgs := getHelmArgs(config, watchNamespace, resourceName, withTLS, defaultOperator, additionalHelmArgs...)
helmArgs := getHelmArgs(config, watchNamespaces, resourceName, withTLS, defaultOperator, additionalHelmArgs...)
helmFlags := map[string]string{
"namespace": config.Namespace,
"create-namespace": "",
@@ -256,7 +265,7 @@ func deployCertManager(config TestConfig) error {
"namespace": config.CertManagerNamespace,
"create-namespace": "",
}
values := map[string]string{"installCRDs": "true"}
values := map[string]interface{}{"installCRDs": "true"}
if err := helm.Install(charlUrl, helmChartName, flags, values); err != nil {
return fmt.Errorf("failed to install cert-manager Helm chart: %s", err)
}
@@ -283,3 +292,13 @@ func hasDeploymentRequiredReplicas(dep *appsv1.Deployment) wait.ConditionWithCon
return false, nil
}
}

func ensureWatchNamespaces(ctx *e2eutil.TestContext, config TestConfig) error {
for _, namespace := range config.WatchNamespaces {
err := e2eutil.EnsureNamespace(ctx, namespace)
if err != nil {
return err
}
}
return nil
}
3 changes: 3 additions & 0 deletions test/e2e/setup/test_config.go
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import (

const (
testNamespaceEnvName = "TEST_NAMESPACE"
testWatchNamespacesEnvName = "TEST_WATCH_NAMESPACE"
testCertManagerNamespaceEnvName = "TEST_CERT_MANAGER_NAMESPACE"
testCertManagerVersionEnvName = "TEST_CERT_MANAGER_VERSION"
operatorImageEnvName = "OPERATOR_IMAGE"
@@ -18,6 +19,7 @@ const (

type TestConfig struct {
Namespace string
WatchNamespaces []string
CertManagerNamespace string
CertManagerVersion string
OperatorImage string
@@ -35,6 +37,7 @@ type TestConfig struct {
func LoadTestConfigFromEnv() TestConfig {
return TestConfig{
Namespace: envvar.GetEnvOrDefault(testNamespaceEnvName, "mongodb"),
WatchNamespaces: envvar.ReadCSVOrDefault(testWatchNamespacesEnvName, []string{"mongodb"}),
CertManagerNamespace: envvar.GetEnvOrDefault(testCertManagerNamespaceEnvName, "cert-manager"),
CertManagerVersion: envvar.GetEnvOrDefault(testCertManagerVersionEnvName, "v1.5.3"),
OperatorImage: envvar.GetEnvOrDefault(operatorImageEnvName, "quay.io/mongodb/community-operator-dev:latest"),