From 58f831d550aff7c6f4fef5654834ab8ef27686ad Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Fri, 31 Oct 2025 22:10:43 +0100 Subject: [PATCH 1/9] feature: create secret for agent password --- .evergreen-tasks.yml | 5 + .evergreen.yml | 1 + controllers/om/automation_config.go | 68 ++++- .../operator/appdbreplicaset_controller.go | 2 +- .../operator/authentication/authentication.go | 20 +- .../authentication_mechanism.go | 5 +- .../configure_authentication_test.go | 39 ++- controllers/operator/authentication/ldap.go | 6 +- .../operator/authentication/ldap_test.go | 9 +- controllers/operator/authentication/oidc.go | 5 +- .../operator/authentication/oidc_test.go | 9 +- .../operator/authentication/scramsha.go | 12 +- .../operator/authentication/scramsha_test.go | 9 +- controllers/operator/authentication/x509.go | 5 +- .../operator/authentication/x509_test.go | 9 +- controllers/operator/common_controller.go | 6 +- .../mongodbmultireplicaset_controller.go | 2 +- .../mongodbreplicaset_controller_test.go | 2 +- .../mongodbshardedcluster_controller_test.go | 2 +- .../mongodbstandalone_controller_test.go | 2 +- ...-cluster-scram-sha-256-switch-project.yaml | 25 ++ ...ed_cluster_scram_sha_256_switch_project.py | 112 +++++++++ public/samples/community/setup | 236 ++++++++++++++++++ 23 files changed, 551 insertions(+), 40 deletions(-) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-scram-sha-256-switch-project.yaml create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py create mode 100644 public/samples/community/setup diff --git a/.evergreen-tasks.yml b/.evergreen-tasks.yml index 2d0803097..8e5259c62 100644 --- a/.evergreen-tasks.yml +++ b/.evergreen-tasks.yml @@ -585,6 +585,11 @@ tasks: commands: - func: "e2e_test" + - name: e2e_sharded_cluster_scram_sha_256_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + - name: e2e_sharded_cluster_scram_sha_1_user_connectivity tags: [ "patch-run" ] commands: diff --git a/.evergreen.yml b/.evergreen.yml index 1732b36b6..7a90bc1e1 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -710,6 +710,7 @@ task_groups: - e2e_replica_set_scram_x509_ic_manual_certs - e2e_sharded_cluster_scram_sha_1_upgrade - e2e_sharded_cluster_scram_sha_256_user_connectivity + - e2e_sharded_cluster_scram_sha_256_switch_project - e2e_sharded_cluster_scram_sha_1_user_connectivity - e2e_sharded_cluster_scram_x509_ic_manual_certs - e2e_sharded_cluster_external_access diff --git a/controllers/om/automation_config.go b/controllers/om/automation_config.go index bfb61c369..f0f0835cb 100644 --- a/controllers/om/automation_config.go +++ b/controllers/om/automation_config.go @@ -1,19 +1,28 @@ package om import ( + "context" "encoding/json" + "fmt" "github.com/google/go-cmp/cmp" "github.com/spf13/cast" "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" "github.com/mongodb/mongodb-kubernetes/controllers/operator/ldap" "github.com/mongodb/mongodb-kubernetes/controllers/operator/oidc" + "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/secret" "github.com/mongodb/mongodb-kubernetes/pkg/util" "github.com/mongodb/mongodb-kubernetes/pkg/util/generate" "github.com/mongodb/mongodb-kubernetes/pkg/util/maputil" ) +// The constants for the authentication secret +const agentAuthenticationSecretSuffix = "-agent-auth-secret" +const autoPwdSecretKey = "automation-agent-password" + // AutomationConfig maintains the raw map in the Deployment field // and constructs structs to make use of go's type safety // Dev notes: actually, this object is just a wrapper for the `Deployment` object which is received from Ops Manager, @@ -429,16 +438,63 @@ func (ac *AutomationConfig) EnsureKeyFileContents() error { // EnsurePassword makes sure that there is an Automation Agent password // that the agents will use to communicate with the deployments. The password // is returned, so it can be provided to the other agents -func (ac *AutomationConfig) EnsurePassword() (string, error) { - if ac.Auth.AutoPwd == "" || ac.Auth.AutoPwd == util.InvalidAutomationAgentPassword { - automationAgentBackupPassword, err := generate.KeyFileContents() +// EnsurePassword makes sure that there is an Automation Agent password +// that the agents will use to communicate with the deployments. The password +// is returned, so it can be provided to the other agents. +func (ac *AutomationConfig) EnsurePassword(k8sClient secret.GetUpdateCreator, ctx context.Context, mdbNamespacedName *types.NamespacedName) (string, error) { + secretNamespacedName := client.ObjectKey{Name: mdbNamespacedName.Name + agentAuthenticationSecretSuffix, Namespace: mdbNamespacedName.Namespace} + + var password string + + data, err := secret.ReadStringData(ctx, k8sClient, secretNamespacedName) + if err == nil { + if val, ok := data[autoPwdSecretKey]; ok && len(val) > 0 { + password = val + } + } else if secret.SecretNotExist(err) { + if ac.Auth.AutoPwd != "" && ac.Auth.AutoPwd != util.InvalidAutomationAgentPassword { + password = ac.Auth.AutoPwd + } + + err := EnsureEmptySecret(ctx, k8sClient, secretNamespacedName) if err != nil { return "", err } - ac.Auth.AutoPwd = automationAgentBackupPassword - return automationAgentBackupPassword, nil } - return ac.Auth.AutoPwd, nil + + if password == "" { + generatedPassword, genErr := generate.KeyFileContents() + if genErr != nil { + return "", genErr + } + password = generatedPassword + } + + ac.Auth.AutoPwd = password + err = secret.UpdateField(ctx, k8sClient, secretNamespacedName, autoPwdSecretKey, password) + if err != nil { + return "", fmt.Errorf("failed to update password field in shared secret %s/%s: %w", secretNamespacedName.Namespace, secretNamespacedName.Name, err) + } + + return password, nil +} + +func EnsureEmptySecret(ctx context.Context, k8sClient secret.GetUpdateCreator, secretNamespacedName types.NamespacedName) error { + dataFields := map[string]string{ + autoPwdSecretKey: "", + } + + emptySecret := secret.Builder(). + SetName(secretNamespacedName.Name). + SetNamespace(secretNamespacedName.Namespace). + SetStringMapToData(dataFields). + Build() + + if err := secret.CreateOrUpdateIfNeeded(ctx, k8sClient, emptySecret); err != nil { + return fmt.Errorf("failed to create or update empty secret %s/%s: %w", secretNamespacedName.Namespace, secretNamespacedName.Name, err) + } + + return nil } func (ac *AutomationConfig) CanEnableX509ProjectAuthentication() (bool, string) { diff --git a/controllers/operator/appdbreplicaset_controller.go b/controllers/operator/appdbreplicaset_controller.go index fe68e07c6..d2fe09d0d 100644 --- a/controllers/operator/appdbreplicaset_controller.go +++ b/controllers/operator/appdbreplicaset_controller.go @@ -1667,7 +1667,7 @@ func (r *ReconcileAppDbReplicaSet) tryConfigureMonitoringInOpsManager(ctx contex AutoPEMKeyFilePath: agentCertPath, CAFilePath: util.CAFilePathInContainer, } - err = authentication.Configure(conn, opts, false, log) + err = authentication.Configure(r.client, ctx, &types.NamespacedName{Namespace: opsManager.Namespace, Name: opsManager.Name}, conn, opts, false, log) if err != nil { log.Errorf("Could not set Automation Authentication options in Ops/Cloud Manager for the Application Database. "+ "Application Database is always configured with authentication enabled, but this will not be "+ diff --git a/controllers/operator/authentication/authentication.go b/controllers/operator/authentication/authentication.go index c2e36735b..6858414a4 100644 --- a/controllers/operator/authentication/authentication.go +++ b/controllers/operator/authentication/authentication.go @@ -1,13 +1,17 @@ package authentication import ( + "context" + "go.uber.org/zap" "golang.org/x/xerrors" + "k8s.io/apimachinery/pkg/types" mdbv1 "github.com/mongodb/mongodb-kubernetes/api/v1/mdb" "github.com/mongodb/mongodb-kubernetes/controllers/om" "github.com/mongodb/mongodb-kubernetes/controllers/operator/ldap" "github.com/mongodb/mongodb-kubernetes/controllers/operator/oidc" + kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client" "github.com/mongodb/mongodb-kubernetes/pkg/util" ) @@ -82,7 +86,7 @@ type UserOptions struct { // Configure will configure all the specified authentication Mechanisms. We need to ensure we wait for // the agents to reach ready state after each operation as prematurely updating the automation config can cause the agents to get stuck. -func Configure(conn om.Connection, opts Options, isRecovering bool, log *zap.SugaredLogger) error { +func Configure(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, isRecovering bool, log *zap.SugaredLogger) error { log.Infow("ensuring correct deployment mechanisms", "ProcessNames", opts.ProcessNames, "Mechanisms", opts.Mechanisms) // In case we're recovering, we can push all changes at once, because the mechanism is triggered after 20min by default. @@ -113,7 +117,7 @@ func Configure(conn om.Connection, opts Options, isRecovering bool, log *zap.Sug // once we have made sure that the deployment authentication mechanism array contains the desired auth mechanism // we can then configure the agent authentication. - if err := enableAgentAuthentication(conn, opts, log); err != nil { + if err := enableAgentAuthentication(client, ctx, mdbNamespacedName, conn, opts, log); err != nil { return xerrors.Errorf("error enabling agent authentication: %w", err) } if err := waitForReadyStateIfNeeded(); err != nil { @@ -151,7 +155,7 @@ func Configure(conn om.Connection, opts Options, isRecovering bool, log *zap.Sug // Disable disables all authentication mechanisms, and waits for the agents to reach goal state. It is still required to provide // automation agent username, password and keyfile contents to ensure a valid Automation Config. -func Disable(conn om.Connection, opts Options, deleteUsers bool, log *zap.SugaredLogger) error { +func Disable(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, deleteUsers bool, log *zap.SugaredLogger) error { ac, err := conn.ReadAutomationConfig() if err != nil { return xerrors.Errorf("error reading automation config: %w", err) @@ -181,7 +185,7 @@ func Disable(conn om.Connection, opts Options, deleteUsers bool, log *zap.Sugare if err := ac.EnsureKeyFileContents(); err != nil { return xerrors.Errorf("error ensuring keyfile contents: %w", err) } - if _, err := ac.EnsurePassword(); err != nil { + if _, err := ac.EnsurePassword(client, ctx, mdbNamespacedName); err != nil { return xerrors.Errorf("error ensuring agent password: %w", err) } @@ -258,7 +262,7 @@ func removeUnsupportedAgentMechanisms(conn om.Connection, opts Options, log *zap // enableAgentAuthentication determines which agent authentication mechanism should be configured // and enables it in Ops Manager -func enableAgentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func enableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { ac, err := conn.ReadAutomationConfig() if err != nil { return xerrors.Errorf("error reading automation config: %w", err) @@ -267,7 +271,7 @@ func enableAgentAuthentication(conn om.Connection, opts Options, log *zap.Sugare // we then configure the agent authentication for that type mechanism := convertToMechanismOrPanic(opts.AgentMechanism, ac) - if err := ensureAgentAuthenticationIsConfigured(conn, opts, ac, mechanism, log); err != nil { + if err := ensureAgentAuthenticationIsConfigured(client, ctx, mdbNamespacedName, conn, opts, ac, mechanism, log); err != nil { return xerrors.Errorf("error ensuring agent authentication is configured: %w", err) } @@ -365,14 +369,14 @@ func addOrRemoveAgentClientCertificate(conn om.Connection, opts Options, log *za } // ensureAgentAuthenticationIsConfigured will configure the agent authentication settings based on the desiredAgentAuthMechanism -func ensureAgentAuthenticationIsConfigured(conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error { +func ensureAgentAuthenticationIsConfigured(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error { if mechanism.IsAgentAuthenticationConfigured(ac, opts) { log.Infof("Agent authentication mechanism %s is already configured", mechanism.GetName()) return nil } log.Infof("Enabling %s agent authentication", mechanism.GetName()) - return mechanism.EnableAgentAuthentication(conn, opts, log) + return mechanism.EnableAgentAuthentication(client, ctx, mdbNamespacedName, conn, opts, log) } // ensureDeploymentMechanisms configures the given AutomationConfig to allow deployments to diff --git a/controllers/operator/authentication/authentication_mechanism.go b/controllers/operator/authentication/authentication_mechanism.go index 90e6877e8..ba65e1324 100644 --- a/controllers/operator/authentication/authentication_mechanism.go +++ b/controllers/operator/authentication/authentication_mechanism.go @@ -1,19 +1,22 @@ package authentication import ( + "context" "slices" "strings" "go.uber.org/zap" "golang.org/x/xerrors" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" + kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client" "github.com/mongodb/mongodb-kubernetes/pkg/util" ) // Mechanism is an interface that needs to be implemented for any Ops Manager authentication mechanism type Mechanism interface { - EnableAgentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error + EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error DisableAgentAuthentication(conn om.Connection, log *zap.SugaredLogger) error EnableDeploymentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error DisableDeploymentAuthentication(conn om.Connection, log *zap.SugaredLogger) error diff --git a/controllers/operator/authentication/configure_authentication_test.go b/controllers/operator/authentication/configure_authentication_test.go index 8e8ae95df..5a6dcc79e 100644 --- a/controllers/operator/authentication/configure_authentication_test.go +++ b/controllers/operator/authentication/configure_authentication_test.go @@ -1,13 +1,16 @@ package authentication import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" + "github.com/mongodb/mongodb-kubernetes/controllers/operator/mock" "github.com/mongodb/mongodb-kubernetes/pkg/util" ) @@ -17,6 +20,10 @@ func init() { } func TestConfigureScramSha256(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -27,7 +34,7 @@ func TestConfigureScramSha256(t *testing.T) { AgentMechanism: "SCRAM", } - if err := Configure(conn, opts, false, zap.S()); err != nil { + if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -41,6 +48,10 @@ func TestConfigureScramSha256(t *testing.T) { } func TestConfigureX509(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -55,7 +66,7 @@ func TestConfigureX509(t *testing.T) { }, } - if err := Configure(conn, opts, false, zap.S()); err != nil { + if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -69,6 +80,10 @@ func TestConfigureX509(t *testing.T) { } func TestConfigureScramSha1(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -79,7 +94,7 @@ func TestConfigureScramSha1(t *testing.T) { AgentMechanism: "SCRAM-SHA-1", } - if err := Configure(conn, opts, false, zap.S()); err != nil { + if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -91,6 +106,10 @@ func TestConfigureScramSha1(t *testing.T) { } func TestConfigureMultipleAuthenticationMechanisms(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -104,7 +123,7 @@ func TestConfigureMultipleAuthenticationMechanisms(t *testing.T) { }, } - if err := Configure(conn, opts, false, zap.S()); err != nil { + if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -124,6 +143,10 @@ func TestConfigureMultipleAuthenticationMechanisms(t *testing.T) { } func TestDisableAuthentication(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -133,7 +156,7 @@ func TestDisableAuthentication(t *testing.T) { return nil }, zap.S()) - if err := Disable(conn, Options{}, true, zap.S()); err != nil { + if err := Disable(kubeClient, ctx, mdbNamespacedName, conn, Options{}, true, zap.S()); err != nil { t.Fatal(err) } @@ -212,7 +235,11 @@ func assertDeploymentMechanismsConfigured(t *testing.T, authMechanism Mechanism, } func assertAgentAuthenticationDisabled(t *testing.T, authMechanism Mechanism, conn om.Connection, opts Options) { - err := authMechanism.EnableAgentAuthentication(conn, opts, zap.S()) + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + + err := authMechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) require.NoError(t, err) ac, err := conn.ReadAutomationConfig() diff --git a/controllers/operator/authentication/ldap.go b/controllers/operator/authentication/ldap.go index 1cd8a0b6c..9d7a95445 100644 --- a/controllers/operator/authentication/ldap.go +++ b/controllers/operator/authentication/ldap.go @@ -1,10 +1,14 @@ package authentication import ( + "context" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" "github.com/mongodb/mongodb-kubernetes/controllers/operator/ldap" + kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client" "github.com/mongodb/mongodb-kubernetes/pkg/util" "github.com/mongodb/mongodb-kubernetes/pkg/util/stringutil" ) @@ -15,7 +19,7 @@ func (l *ldapAuthMechanism) GetName() MechanismName { return LDAPPlain } -func (l *ldapAuthMechanism) EnableAgentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func (l *ldapAuthMechanism) EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { log.Info("Configuring LDAP authentication") err := conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error { if err := ac.EnsureKeyFileContents(); err != nil { diff --git a/controllers/operator/authentication/ldap_test.go b/controllers/operator/authentication/ldap_test.go index 0b619e3df..54d96336e 100644 --- a/controllers/operator/authentication/ldap_test.go +++ b/controllers/operator/authentication/ldap_test.go @@ -1,14 +1,17 @@ package authentication import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" "github.com/mongodb/mongodb-kubernetes/controllers/operator/ldap" + "github.com/mongodb/mongodb-kubernetes/controllers/operator/mock" ) var ldapPlainMechanism = getMechanismByName(LDAPPlain) @@ -45,6 +48,10 @@ func TestLdapDeploymentMechanism(t *testing.T) { } func TestLdapEnableAgentAuthentication(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + conn := om.NewMockedOmConnection(om.NewDeployment()) opts := Options{ AgentMechanism: "LDAP", @@ -55,7 +62,7 @@ func TestLdapEnableAgentAuthentication(t *testing.T) { AutoPwd: "LDAPPassword.", } - err := ldapPlainMechanism.EnableAgentAuthentication(conn, opts, zap.S()) + err := ldapPlainMechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) require.NoError(t, err) ac, err := conn.ReadAutomationConfig() diff --git a/controllers/operator/authentication/oidc.go b/controllers/operator/authentication/oidc.go index 7e9bf4c2c..dec32e27f 100644 --- a/controllers/operator/authentication/oidc.go +++ b/controllers/operator/authentication/oidc.go @@ -1,16 +1,19 @@ package authentication import ( + "context" "fmt" "slices" "strings" "go.uber.org/zap" "golang.org/x/xerrors" + "k8s.io/apimachinery/pkg/types" mdbv1 "github.com/mongodb/mongodb-kubernetes/api/v1/mdb" "github.com/mongodb/mongodb-kubernetes/controllers/om" "github.com/mongodb/mongodb-kubernetes/controllers/operator/oidc" + kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client" "github.com/mongodb/mongodb-kubernetes/pkg/util/stringutil" ) @@ -20,7 +23,7 @@ func (o *oidcAuthMechanism) GetName() MechanismName { return MongoDBOIDC } -func (o *oidcAuthMechanism) EnableAgentAuthentication(_ om.Connection, _ Options, _ *zap.SugaredLogger) error { +func (o *oidcAuthMechanism) EnableAgentAuthentication(_ kubernetesClient.Client, _ context.Context, _ *types.NamespacedName, _ om.Connection, _ Options, _ *zap.SugaredLogger) error { return xerrors.Errorf("OIDC agent authentication is not supported") } diff --git a/controllers/operator/authentication/oidc_test.go b/controllers/operator/authentication/oidc_test.go index 6460db803..5191eaf0e 100644 --- a/controllers/operator/authentication/oidc_test.go +++ b/controllers/operator/authentication/oidc_test.go @@ -1,14 +1,17 @@ package authentication import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" "github.com/mongodb/mongodb-kubernetes/controllers/om" + "github.com/mongodb/mongodb-kubernetes/controllers/operator/mock" "github.com/mongodb/mongodb-kubernetes/controllers/operator/oidc" ) @@ -77,6 +80,10 @@ func TestOIDC_EnableDeploymentAuthentication(t *testing.T) { } func TestOIDC_EnableAgentAuthentication(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + conn := om.NewMockedOmConnection(om.NewDeployment()) opts := Options{ Mechanisms: []string{string(MongoDBOIDC)}, @@ -88,7 +95,7 @@ func TestOIDC_EnableAgentAuthentication(t *testing.T) { configured := mongoDBOIDCMechanism.IsAgentAuthenticationConfigured(ac, opts) assert.False(t, configured) - err = mongoDBOIDCMechanism.EnableAgentAuthentication(conn, opts, zap.S()) + err = mongoDBOIDCMechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) require.Error(t, err) err = mongoDBOIDCMechanism.DisableAgentAuthentication(conn, zap.S()) diff --git a/controllers/operator/authentication/scramsha.go b/controllers/operator/authentication/scramsha.go index ee186b869..b03b8b94d 100644 --- a/controllers/operator/authentication/scramsha.go +++ b/controllers/operator/authentication/scramsha.go @@ -1,9 +1,13 @@ package authentication import ( + "context" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" + kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client" "github.com/mongodb/mongodb-kubernetes/pkg/util" "github.com/mongodb/mongodb-kubernetes/pkg/util/stringutil" ) @@ -18,9 +22,9 @@ func (s *automationConfigScramSha) GetName() MechanismName { return s.MechanismName } -func (s *automationConfigScramSha) EnableAgentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func (s *automationConfigScramSha) EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { return conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error { - if err := configureScramAgentUsers(ac, opts); err != nil { + if err := configureScramAgentUsers(client, ctx, mdbNamespacedName, ac, opts); err != nil { return err } if err := ac.EnsureKeyFileContents(); err != nil { @@ -91,8 +95,8 @@ func (s *automationConfigScramSha) IsDeploymentAuthenticationEnabled(ac *om.Auto } // configureScramAgentUsers makes sure that the given automation config always has the correct SCRAM-SHA users -func configureScramAgentUsers(ac *om.AutomationConfig, authOpts Options) error { - agentPassword, err := ac.EnsurePassword() +func configureScramAgentUsers(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, ac *om.AutomationConfig, authOpts Options) error { + agentPassword, err := ac.EnsurePassword(client, ctx, mdbNamespacedName) if err != nil { return err } diff --git a/controllers/operator/authentication/scramsha_test.go b/controllers/operator/authentication/scramsha_test.go index 1c97e9943..f998f7153 100644 --- a/controllers/operator/authentication/scramsha_test.go +++ b/controllers/operator/authentication/scramsha_test.go @@ -1,13 +1,16 @@ package authentication import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" + "github.com/mongodb/mongodb-kubernetes/controllers/operator/mock" "github.com/mongodb/mongodb-kubernetes/pkg/util" ) @@ -34,6 +37,10 @@ func TestAgentsAuthentication(t *testing.T) { } for testName, testConfig := range tests { t.Run(testName, func(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + conn := om.NewMockedOmConnection(om.NewDeployment()) s := testConfig.mechanism @@ -43,7 +50,7 @@ func TestAgentsAuthentication(t *testing.T) { CAFilePath: util.CAFilePathInContainer, } - err := s.EnableAgentAuthentication(conn, opts, zap.S()) + err := s.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) require.NoError(t, err) err = s.EnableDeploymentAuthentication(conn, opts, zap.S()) diff --git a/controllers/operator/authentication/x509.go b/controllers/operator/authentication/x509.go index e863b7780..02e429ce5 100644 --- a/controllers/operator/authentication/x509.go +++ b/controllers/operator/authentication/x509.go @@ -1,11 +1,14 @@ package authentication import ( + "context" "regexp" "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" + kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client" "github.com/mongodb/mongodb-kubernetes/pkg/util" "github.com/mongodb/mongodb-kubernetes/pkg/util/stringutil" ) @@ -16,7 +19,7 @@ func (x *connectionX509) GetName() MechanismName { return MongoDBX509 } -func (x *connectionX509) EnableAgentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func (x *connectionX509) EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { log.Info("Configuring x509 authentication") err := conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error { if err := ac.EnsureKeyFileContents(); err != nil { diff --git a/controllers/operator/authentication/x509_test.go b/controllers/operator/authentication/x509_test.go index f342b6702..b7022f57e 100644 --- a/controllers/operator/authentication/x509_test.go +++ b/controllers/operator/authentication/x509_test.go @@ -1,20 +1,27 @@ package authentication import ( + "context" "fmt" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" "github.com/mongodb/mongodb-kubernetes/controllers/om" + "github.com/mongodb/mongodb-kubernetes/controllers/operator/mock" "github.com/mongodb/mongodb-kubernetes/pkg/util" ) var mongoDBX509Mechanism = getMechanismByName(MongoDBX509) func TestX509EnableAgentAuthentication(t *testing.T) { + ctx := context.Background() + kubeClient, _ := mock.NewDefaultFakeClient() + mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + conn := om.NewMockedOmConnection(om.NewDeployment()) options := Options{ @@ -25,7 +32,7 @@ func TestX509EnableAgentAuthentication(t *testing.T) { }, AuthoritativeSet: true, } - if err := mongoDBX509Mechanism.EnableAgentAuthentication(conn, options, zap.S()); err != nil { + if err := mongoDBX509Mechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, options, zap.S()); err != nil { t.Fatal(err) } diff --git a/controllers/operator/common_controller.go b/controllers/operator/common_controller.go index e76cf4e81..72babde36 100644 --- a/controllers/operator/common_controller.go +++ b/controllers/operator/common_controller.go @@ -514,7 +514,7 @@ func (r *ReconcileCommonController) updateOmAuthentication(ctx context.Context, authOpts.UserOptions = userOpts } - if err := authentication.Configure(conn, authOpts, isRecovering, log); err != nil { + if err := authentication.Configure(r.client, ctx, &types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, isRecovering, log); err != nil { return workflow.Failed(err), false } } else if wantToEnableAuthentication { @@ -533,7 +533,7 @@ func (r *ReconcileCommonController) updateOmAuthentication(ctx context.Context, } authOpts.UserOptions = userOpts - if err := authentication.Disable(conn, authOpts, false, log); err != nil { + if err := authentication.Disable(r.client, ctx, &types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, false, log); err != nil { return workflow.Failed(err), false } } @@ -597,7 +597,7 @@ func (r *ReconcileCommonController) clearProjectAuthenticationSettings(ctx conte UserOptions: userOpts, } - return authentication.Disable(conn, disableOpts, true, log) + return authentication.Disable(r.client, ctx, &types.NamespacedName{Namespace: mdb.Namespace, Name: mdb.Name}, conn, disableOpts, true, log) } // ensureX509SecretAndCheckTLSType checks if the secrets containing the certificates are present and whether the certificate are of kubernetes.io/tls type. diff --git a/controllers/operator/mongodbmultireplicaset_controller.go b/controllers/operator/mongodbmultireplicaset_controller.go index 386ce8a6b..119d5cf12 100644 --- a/controllers/operator/mongodbmultireplicaset_controller.go +++ b/controllers/operator/mongodbmultireplicaset_controller.go @@ -1236,7 +1236,7 @@ func (r *ReconcileMongoDbMultiReplicaSet) cleanOpsManagerState(ctx context.Conte ProcessNames: processNames, } - if err := authentication.Disable(conn, opts, true, log); err != nil { + if err := authentication.Disable(r.client, ctx, &types.NamespacedName{Namespace: mrs.GetNamespace(), Name: mrs.GetName()}, conn, opts, true, log); err != nil { return err } log.Infof("Removed deployment %s from Ops Manager at %s", mrs.Name, conn.BaseURL()) diff --git a/controllers/operator/mongodbreplicaset_controller_test.go b/controllers/operator/mongodbreplicaset_controller_test.go index 803de4f3b..6c39fdeab 100644 --- a/controllers/operator/mongodbreplicaset_controller_test.go +++ b/controllers/operator/mongodbreplicaset_controller_test.go @@ -61,7 +61,7 @@ func TestCreateReplicaSet(t *testing.T) { assert.Len(t, mock.GetMapForObject(client, &corev1.Service{}), 1) assert.Len(t, mock.GetMapForObject(client, &appsv1.StatefulSet{}), 1) - assert.Len(t, mock.GetMapForObject(client, &corev1.Secret{}), 2) + assert.Len(t, mock.GetMapForObject(client, &corev1.Secret{}), 3) sts, err := client.GetStatefulSet(ctx, rs.ObjectKey()) assert.NoError(t, err) diff --git a/controllers/operator/mongodbshardedcluster_controller_test.go b/controllers/operator/mongodbshardedcluster_controller_test.go index d7b2aefe4..15cc1c459 100644 --- a/controllers/operator/mongodbshardedcluster_controller_test.go +++ b/controllers/operator/mongodbshardedcluster_controller_test.go @@ -81,7 +81,7 @@ func TestReconcileCreateShardedCluster(t *testing.T) { require.NoError(t, err) checkReconcileSuccessful(ctx, t, reconciler, sc, c) - assert.Len(t, mock.GetMapForObject(c, &corev1.Secret{}), 2) + assert.Len(t, mock.GetMapForObject(c, &corev1.Secret{}), 3) assert.Len(t, mock.GetMapForObject(c, &corev1.Service{}), 3) assert.Len(t, mock.GetMapForObject(c, &appsv1.StatefulSet{}), 4) assert.Equal(t, getStsReplicas(ctx, c, kube.ObjectKey(sc.Namespace, sc.ConfigRsName()), t), int32(sc.Spec.ConfigServerCount)) diff --git a/controllers/operator/mongodbstandalone_controller_test.go b/controllers/operator/mongodbstandalone_controller_test.go index 69bdfbb87..a9c6bd8f4 100644 --- a/controllers/operator/mongodbstandalone_controller_test.go +++ b/controllers/operator/mongodbstandalone_controller_test.go @@ -71,7 +71,7 @@ func TestOnAddStandalone(t *testing.T) { assert.Len(t, mock.GetMapForObject(kubeClient, &corev1.Service{}), 1) assert.Len(t, mock.GetMapForObject(kubeClient, &appsv1.StatefulSet{}), 1) assert.Equal(t, *mock.GetMapForObject(kubeClient, &appsv1.StatefulSet{})[st.ObjectKey()].(*appsv1.StatefulSet).Spec.Replicas, int32(1)) - assert.Len(t, mock.GetMapForObject(kubeClient, &corev1.Secret{}), 2) + assert.Len(t, mock.GetMapForObject(kubeClient, &corev1.Secret{}), 3) omConn.(*om.MockedOmConnection).CheckDeployment(t, createDeploymentFromStandalone(st), "auth", "tls") omConn.(*om.MockedOmConnection).CheckNumberOfUpdateRequests(t, 1) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-scram-sha-256-switch-project.yaml new file mode 100644 index 000000000..1bf83d70d --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-scram-sha-256-switch-project.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: sharded-cluster-scram-sha-256-switch-project +spec: + shardCount: 1 + mongodsPerShardCount: 1 + mongosCount: 1 + configServerCount: 1 + version: 4.4.0 + type: ShardedCluster + + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + + persistent: true + security: + authentication: + enabled: true + modes: ["SCRAM"] + + diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py new file mode 100644 index 000000000..8086e8d50 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py @@ -0,0 +1,112 @@ +import pytest + +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ShardedClusterTester +from kubetester.phase import Phase + +from kubetester import ( + read_configmap, + random_k8s_name, + create_or_update_configmap, +) + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + +MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-256-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.fixture(scope="module") +def sharded_cluster(namespace: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the sharded cluster. + + Dynamically updates the resource Ops Manager reference based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + return resource + + + +@pytest.mark.e2e_sharded_cluster_scram_sha_256_switch_project +class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for sharded cluster creation and switching Ops Manager project reference. + """ + + def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): + """ + Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. + """ + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_sharded_cluster_connectivity(self): + """ + Verify connectivity to the original sharded cluster. + """ + ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original cluster. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() + + def test_switch_sharded_cluster_project( + self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + sharded_cluster.load() + sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_moved_sharded_cluster_connectivity(self): + """ + Verify connectivity to the sharded cluster after project switch. + """ + ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() diff --git a/public/samples/community/setup b/public/samples/community/setup new file mode 100644 index 000000000..10301541e --- /dev/null +++ b/public/samples/community/setup @@ -0,0 +1,236 @@ +cat < Date: Mon, 3 Nov 2025 09:28:56 +0100 Subject: [PATCH 2/9] improvments --- .evergreen-tasks.yml | 5 + .evergreen.yml | 1 + ...lica-set-scram-sha-256-switch-project.yaml | 19 ++ ...eplica_set_scram_sha_256_switch_project.py | 113 +++++++++ public/samples/community/setup | 236 ------------------ 5 files changed, 138 insertions(+), 236 deletions(-) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-scram-sha-256-switch-project.yaml create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py delete mode 100644 public/samples/community/setup diff --git a/.evergreen-tasks.yml b/.evergreen-tasks.yml index 8e5259c62..72a8a8763 100644 --- a/.evergreen-tasks.yml +++ b/.evergreen-tasks.yml @@ -590,6 +590,11 @@ tasks: commands: - func: "e2e_test" + - name: e2e_replica_set_scram_sha_256_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + - name: e2e_sharded_cluster_scram_sha_1_user_connectivity tags: [ "patch-run" ] commands: diff --git a/.evergreen.yml b/.evergreen.yml index 7a90bc1e1..8fe1c06e6 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -711,6 +711,7 @@ task_groups: - e2e_sharded_cluster_scram_sha_1_upgrade - e2e_sharded_cluster_scram_sha_256_user_connectivity - e2e_sharded_cluster_scram_sha_256_switch_project + - e2e_replica_set_scram_sha_256_switch_project - e2e_sharded_cluster_scram_sha_1_user_connectivity - e2e_sharded_cluster_scram_x509_ic_manual_certs - e2e_sharded_cluster_external_access diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-scram-sha-256-switch-project.yaml new file mode 100644 index 000000000..be90421fc --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-scram-sha-256-switch-project.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: replica-set-scram-sha-256-switch-project +spec: + members: 3 + version: 4.4.0 + type: ReplicaSet + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + logLevel: DEBUG + persistent: false + security: + authentication: + enabled: true + modes: ["SCRAM"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py new file mode 100644 index 000000000..ff05148bb --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -0,0 +1,113 @@ +import pytest + +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ReplicaSetTester +from kubetester.phase import Phase + +from kubetester import ( + random_k8s_name, + create_or_update_configmap, + read_configmap +) + +# Constants +MDB_RESOURCE_NAME = "replica-set-scram-sha-256-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + + + +@pytest.fixture(scope="module") +def replica_set(namespace: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the replica set. + + Dynamically updates the resource configuration based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + return resource + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.mark.e2e_replica_set_scram_sha_256_switch_project +class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for replica set creation and user connectivity with SCRAM-SHA-256 authentication. + """ + + def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): + """ + Test replica set creation ensuring resources are applied correctly and set reaches Running phase. + """ + replica_set.set_version(custom_mdb_version) + replica_set.update() + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_replica_set_connectivity(self): + """ + Verify connectivity to the original replica set. + """ + ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() # Adjust node count as appropriate + + def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original replica set. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() + + def test_switch_replica_set_project( + self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + replica_set.load() + replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + replica_set.set_version(custom_mdb_version) + replica_set.update() + + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_moved_replica_set_connectivity(self): + """ + Verify connectivity to the replica set after switching projects. + """ + ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() # Adjust node count as appropriate + + def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() diff --git a/public/samples/community/setup b/public/samples/community/setup deleted file mode 100644 index 10301541e..000000000 --- a/public/samples/community/setup +++ /dev/null @@ -1,236 +0,0 @@ -cat < Date: Tue, 4 Nov 2025 15:02:24 +0100 Subject: [PATCH 3/9] tests + lint --- .evergreen-tasks.yml | 40 +++- .evergreen.yml | 8 +- controllers/om/automation_config.go | 15 +- ...eplica-set-scram-sha-1-switch-project.yaml | 23 ++ ...lica-set-scram-sha-256-switch-project.yaml | 0 .../replica-set-x509-switch-project.yaml | 23 ++ ...ed-cluster-scram-sha-1-switch-project.yaml | 26 +++ ...-cluster-scram-sha-256-switch-project.yaml | 0 .../sharded-cluster-x509-switch-project.yaml | 27 +++ .../replica_set_scram_sha_1_switch_project.py | 110 +++++++++ ...eplica_set_scram_sha_256_switch_project.py | 219 +++++++++--------- .../replica_set_x509_switch_project.py | 114 +++++++++ ...rded_cluster_scram_sha_1_switch_project.py | 113 +++++++++ ...ed_cluster_scram_sha_256_switch_project.py | 219 +++++++++--------- .../sharded_cluster_x509_switch_project.py | 124 ++++++++++ 15 files changed, 821 insertions(+), 240 deletions(-) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml rename docker/mongodb-kubernetes-tests/tests/authentication/fixtures/{ => switch-project}/replica-set-scram-sha-256-switch-project.yaml (100%) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml rename docker/mongodb-kubernetes-tests/tests/authentication/fixtures/{ => switch-project}/sharded-cluster-scram-sha-256-switch-project.yaml (100%) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py diff --git a/.evergreen-tasks.yml b/.evergreen-tasks.yml index 72a8a8763..4a8de81e5 100644 --- a/.evergreen-tasks.yml +++ b/.evergreen-tasks.yml @@ -585,16 +585,6 @@ tasks: commands: - func: "e2e_test" - - name: e2e_sharded_cluster_scram_sha_256_switch_project - tags: [ "patch-run" ] - commands: - - func: "e2e_test" - - - name: e2e_replica_set_scram_sha_256_switch_project - tags: [ "patch-run" ] - commands: - - func: "e2e_test" - - name: e2e_sharded_cluster_scram_sha_1_user_connectivity tags: [ "patch-run" ] commands: @@ -700,6 +690,36 @@ tasks: commands: - func: "e2e_test" + - name: e2e_sharded_cluster_scram_sha_256_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + + - name: e2e_sharded_cluster_scram_sha_1_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + + - name: e2e_sharded_cluster_x509_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + + - name: e2e_replica_set_scram_sha_256_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + + - name: e2e_replica_set_scram_sha_1_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + + - name: e2e_replica_set_x509_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + # TODO: not used in any variant - name: e2e_replica_set_scram_x509_internal_cluster tags: [ "patch-run" ] diff --git a/.evergreen.yml b/.evergreen.yml index 8fe1c06e6..6205479f4 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -710,11 +710,15 @@ task_groups: - e2e_replica_set_scram_x509_ic_manual_certs - e2e_sharded_cluster_scram_sha_1_upgrade - e2e_sharded_cluster_scram_sha_256_user_connectivity - - e2e_sharded_cluster_scram_sha_256_switch_project - - e2e_replica_set_scram_sha_256_switch_project - e2e_sharded_cluster_scram_sha_1_user_connectivity - e2e_sharded_cluster_scram_x509_ic_manual_certs - e2e_sharded_cluster_external_access + - e2e_sharded_cluster_scram_sha_256_switch_project + - e2e_sharded_cluster_scram_sha_1_switch_project + - e2e_sharded_cluster_x509_switch_project + - e2e_replica_set_scram_sha_256_switch_project + - e2e_replica_set_scram_sha_1_switch_project + - e2e_replica_set_x509_switch_project # e2e_auth_transitions_task_group - e2e_replica_set_scram_sha_and_x509 - e2e_replica_set_x509_to_scram_transition diff --git a/controllers/om/automation_config.go b/controllers/om/automation_config.go index f0f0835cb..9582cd77d 100644 --- a/controllers/om/automation_config.go +++ b/controllers/om/automation_config.go @@ -20,8 +20,9 @@ import ( ) // The constants for the authentication secret -const agentAuthenticationSecretSuffix = "-agent-auth-secret" -const autoPwdSecretKey = "automation-agent-password" +const ( + autoPwdSecretKey = "automation-agent-password" +) // AutomationConfig maintains the raw map in the Deployment field // and constructs structs to make use of go's type safety @@ -435,6 +436,12 @@ func (ac *AutomationConfig) EnsureKeyFileContents() error { return nil } +// AuthSecretName for a given mdbName (`mdbName`) returns the name of +// the secret associated with it. +func AuthSecretName(mdbName string) string { + return fmt.Sprintf("%s-agent-auth-secre", mdbName) +} + // EnsurePassword makes sure that there is an Automation Agent password // that the agents will use to communicate with the deployments. The password // is returned, so it can be provided to the other agents @@ -442,8 +449,8 @@ func (ac *AutomationConfig) EnsureKeyFileContents() error { // that the agents will use to communicate with the deployments. The password // is returned, so it can be provided to the other agents. func (ac *AutomationConfig) EnsurePassword(k8sClient secret.GetUpdateCreator, ctx context.Context, mdbNamespacedName *types.NamespacedName) (string, error) { - secretNamespacedName := client.ObjectKey{Name: mdbNamespacedName.Name + agentAuthenticationSecretSuffix, Namespace: mdbNamespacedName.Namespace} - + secretName := AuthSecretName(mdbNamespacedName.Name) + secretNamespacedName := client.ObjectKey{Name: secretName, Namespace: mdbNamespacedName.Namespace} var password string data, err := secret.ReadStringData(ctx, k8sClient, secretNamespacedName) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml new file mode 100644 index 000000000..c4cf66ea5 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: replica-set-scram-sha-1-switch-project +spec: + members: 3 + version: 5.0.5 + type: ReplicaSet + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + logLevel: DEBUG + persistent: false + security: + authentication: + agents: + # This may look weird, but without it we'll get this from OpsManager: + # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode + mode: MONGODB-CR + enabled: true + modes: ["SCRAM-SHA-1", "MONGODB-CR"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-256-switch-project.yaml similarity index 100% rename from docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-scram-sha-256-switch-project.yaml rename to docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-256-switch-project.yaml diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml new file mode 100644 index 000000000..ee79c38f9 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: replica-set-x509-switch-project +spec: + members: 3 + version: 4.4.0-ent + type: ReplicaSet + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + logLevel: DEBUG + persistent: false + security: + tls: + enabled: true + authentication: + agents: + mode: X509 + enabled: true + modes: ["X509"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml new file mode 100644 index 000000000..837ff206e --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: sharded-cluster-scram-sha-1-switch-project +spec: + shardCount: 1 + type: ShardedCluster + mongodsPerShardCount: 1 + mongosCount: 1 + configServerCount: 1 + version: 5.0.5 + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + logLevel: DEBUG + persistent: true + security: + authentication: + agents: + # This may look weird, but without it we'll get this from OpsManager: + # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode + mode: MONGODB-CR + enabled: true + modes: ["SCRAM-SHA-1", "MONGODB-CR"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml similarity index 100% rename from docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-scram-sha-256-switch-project.yaml rename to docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml new file mode 100644 index 000000000..2169679fc --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: sharded-cluster-x509-switch-project +spec: + shardCount: 1 + mongodsPerShardCount: 1 + mongosCount: 1 + configServerCount: 1 + version: 4.4.0-ent + type: ShardedCluster + + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + + persistent: true + security: + tls: + enabled: true + authentication: + agents: + mode: X509 + enabled: true + modes: ["X509"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py new file mode 100644 index 000000000..5cf39477e --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py @@ -0,0 +1,110 @@ +import pytest +from kubetester import create_or_update_configmap, random_k8s_name, read_configmap +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ReplicaSetTester +from kubetester.phase import Phase + +# Constants +MDB_RESOURCE_NAME = "replica-set-scram-sha-1-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + + +@pytest.fixture(scope="module") +def replica_set(namespace: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the replica set. + + Dynamically updates the resource configuration based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + return resource + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.mark.e2e_replica_set_scram_sha_1_switch_project +class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for replica set creation, user connectivity with SCRAM-SHA-1 authentication and switching Ops Manager project reference. + """ + + def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): + """ + Test replica set creation ensuring resources are applied correctly and set reaches Running phase. + """ + replica_set.set_version(custom_mdb_version) + replica_set.update() + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_replica_set_connectivity(self): + """ + Verify connectivity to the original replica set. + """ + ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original replica set. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-CR") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled(2) + tester.assert_expected_users(0) + + def test_switch_replica_set_project( + self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + replica_set.load() + replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + replica_set.set_version(custom_mdb_version) + replica_set.update() + + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_moved_replica_set_connectivity(self): + """ + Verify connectivity to the replica set after switching projects. + """ + ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-CR") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled(2) + tester.assert_expected_users(0) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py index ff05148bb..8269df337 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -1,113 +1,106 @@ -import pytest - -from kubetester.kubetester import KubernetesTester -from kubetester.kubetester import fixture as load_fixture -from kubetester.mongodb import MongoDB -from kubetester.mongotester import ReplicaSetTester -from kubetester.phase import Phase - -from kubetester import ( - random_k8s_name, - create_or_update_configmap, - read_configmap -) - -# Constants -MDB_RESOURCE_NAME = "replica-set-scram-sha-256-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - - - -@pytest.fixture(scope="module") -def replica_set(namespace: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the replica set. - - Dynamically updates the resource configuration based on the test context. - """ - resource = MongoDB.from_yaml(load_fixture(f"{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) - return resource - - -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") - - -@pytest.mark.e2e_replica_set_scram_sha_256_switch_project -class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): - """ - E2E test suite for replica set creation and user connectivity with SCRAM-SHA-256 authentication. - """ - - def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): - """ - Test replica set creation ensuring resources are applied correctly and set reaches Running phase. - """ - replica_set.set_version(custom_mdb_version) - replica_set.update() - replica_set.assert_reaches_phase(Phase.Running, timeout=600) - - def test_replica_set_connectivity(self): - """ - Verify connectivity to the original replica set. - """ - ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() # Adjust node count as appropriate - - def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original replica set. - """ - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() - - def test_switch_replica_set_project( - self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. - """ - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], - }, - ) - - replica_set.load() - replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.set_version(custom_mdb_version) - replica_set.update() - - replica_set.assert_reaches_phase(Phase.Running, timeout=600) - - def test_moved_replica_set_connectivity(self): - """ - Verify connectivity to the replica set after switching projects. - """ - ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() # Adjust node count as appropriate - - def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. - """ - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() +import pytest +from kubetester import create_or_update_configmap, random_k8s_name, read_configmap +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ReplicaSetTester +from kubetester.phase import Phase + +# Constants +MDB_RESOURCE_NAME = "replica-set-scram-sha-256-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + + +@pytest.fixture(scope="module") +def replica_set(namespace: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the replica set. + + Dynamically updates the resource configuration based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + return resource + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.mark.e2e_replica_set_scram_sha_256_switch_project +class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for replica set creation, user connectivity with SCRAM-SHA-256 authentication and switching Ops Manager project reference. + """ + + def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): + """ + Test replica set creation ensuring resources are applied correctly and set reaches Running phase. + """ + replica_set.set_version(custom_mdb_version) + replica_set.update() + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_replica_set_connectivity(self): + """ + Verify connectivity to the original replica set. + """ + ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original replica set. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() + + def test_switch_replica_set_project( + self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + replica_set.load() + replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + replica_set.set_version(custom_mdb_version) + replica_set.update() + + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_moved_replica_set_connectivity(self): + """ + Verify connectivity to the replica set after switching projects. + """ + ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py new file mode 100644 index 000000000..7b23a901d --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py @@ -0,0 +1,114 @@ +import pytest +from kubetester import create_or_update_configmap, random_k8s_name, read_configmap +from kubetester.certs import ( + ISSUER_CA_NAME, + create_agent_tls_certs, + create_mongodb_tls_certs, +) +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ReplicaSetTester +from kubetester.phase import Phase + +# Constants +MDB_RESOURCE_NAME = "replica-set-x509-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + + +@pytest.fixture(scope="module") +def replica_set(namespace: str, server_certs: str, agent_certs: str, issuer_ca_configmap: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the replica set. + + Dynamically updates the resource configuration based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + resource["spec"]["security"]["tls"]["ca"] = issuer_ca_configmap + return resource + + +@pytest.fixture(scope="module") +def server_certs(issuer: str, namespace: str): + return create_mongodb_tls_certs(ISSUER_CA_NAME, namespace, MDB_RESOURCE_NAME, f"{MDB_RESOURCE_NAME}-cert") + + +@pytest.fixture(scope="module") +def agent_certs(issuer: str, namespace: str) -> str: + return create_agent_tls_certs(issuer, namespace, MDB_RESOURCE_NAME) + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.mark.e2e_replica_set_x509_switch_project +class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for replica set creation, user connectivity with X509 authentication and switching Ops Manager project reference. + """ + + def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): + """ + Test replica set creation ensuring resources are applied correctly and set reaches Running phase. + """ + replica_set.set_version(custom_mdb_version) + replica_set.update() + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original replica set. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-X509") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled() + tester.assert_expected_users(0) + + def test_switch_replica_set_project( + self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + replica_set.load() + replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + replica_set.set_version(custom_mdb_version) + replica_set.update() + + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. + """ + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-X509") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled() + tester.assert_expected_users(0) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py new file mode 100644 index 000000000..f950758ca --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py @@ -0,0 +1,113 @@ +import pytest +from kubetester import ( + create_or_update_configmap, + random_k8s_name, + read_configmap, +) +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ShardedClusterTester +from kubetester.phase import Phase + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + +MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-1-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.fixture(scope="module") +def sharded_cluster(namespace: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the sharded cluster. + + Dynamically updates the resource Ops Manager reference based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + return resource + + +@pytest.mark.e2e_sharded_cluster_scram_sha_1_switch_project +class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for sharded cluster creation, user connectivity with SCRAM-SHA-1 authentication and switching Ops Manager project reference. + """ + + def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): + """ + Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. + """ + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_sharded_cluster_connectivity(self): + """ + Verify connectivity to the original sharded cluster. + """ + ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original cluster. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-CR") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled(2) + tester.assert_expected_users(0) + + def test_switch_sharded_cluster_project( + self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + sharded_cluster.load() + sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_moved_sharded_cluster_connectivity(self): + """ + Verify connectivity to the sharded cluster after project switch. + """ + ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-CR") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled(2) + tester.assert_expected_users(0) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py index 8086e8d50..6bf798388 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py @@ -1,112 +1,109 @@ -import pytest - -from kubetester.kubetester import KubernetesTester -from kubetester.kubetester import fixture as load_fixture -from kubetester.mongodb import MongoDB -from kubetester.mongotester import ShardedClusterTester -from kubetester.phase import Phase - -from kubetester import ( - read_configmap, - random_k8s_name, - create_or_update_configmap, -) - -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - -MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-256-switch-project" +import pytest +from kubetester import ( + create_or_update_configmap, + random_k8s_name, + read_configmap, +) +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ShardedClusterTester +from kubetester.phase import Phase + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + +MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-256-switch-project" MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - - -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") - - -@pytest.fixture(scope="module") -def sharded_cluster(namespace: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the sharded cluster. - - Dynamically updates the resource Ops Manager reference based on the test context. - """ - resource = MongoDB.from_yaml(load_fixture(f"{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) - return resource - - - -@pytest.mark.e2e_sharded_cluster_scram_sha_256_switch_project -class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): - """ - E2E test suite for sharded cluster creation and switching Ops Manager project reference. - """ - - def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): - """ - Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. - """ - sharded_cluster.set_version(custom_mdb_version) - sharded_cluster.update() - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) - - def test_sharded_cluster_connectivity(self): - """ - Verify connectivity to the original sharded cluster. - """ - ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original cluster. - """ - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() - - def test_switch_sharded_cluster_project( - self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. - """ - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], - }, - ) - - sharded_cluster.load() - sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.set_version(custom_mdb_version) - sharded_cluster.update() - - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) - - def test_moved_sharded_cluster_connectivity(self): - """ - Verify connectivity to the sharded cluster after project switch. - """ - ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. - """ - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.fixture(scope="module") +def sharded_cluster(namespace: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the sharded cluster. + + Dynamically updates the resource Ops Manager reference based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + return resource + + +@pytest.mark.e2e_sharded_cluster_scram_sha_256_switch_project +class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for sharded cluster creation, user connectivity with SCRAM-SHA-256 authentication and switching Ops Manager project reference. + """ + + def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): + """ + Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. + """ + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_sharded_cluster_connectivity(self): + """ + Verify connectivity to the original sharded cluster. + """ + ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original cluster. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() + + def test_switch_sharded_cluster_project( + self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + sharded_cluster.load() + sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_moved_sharded_cluster_connectivity(self): + """ + Verify connectivity to the sharded cluster after project switch. + """ + ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + + def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") + tester.assert_authentication_enabled() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py new file mode 100644 index 000000000..7138be3a6 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py @@ -0,0 +1,124 @@ +import pytest +from kubetester import ( + create_or_update_configmap, + random_k8s_name, + read_configmap, +) +from kubetester.certs import ( + ISSUER_CA_NAME, + create_sharded_cluster_certs, + create_x509_agent_tls_certs, +) +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as load_fixture +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ShardedClusterTester +from kubetester.phase import Phase + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + +MDB_RESOURCE_NAME = "sharded-cluster-x509-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.fixture(scope="module") +def sharded_cluster(namespace: str, server_certs: str, agent_certs: str, issuer_ca_configmap: str) -> MongoDB: + """ + Fixture to initialize the MongoDB resource for the sharded cluster. + + Dynamically updates the resource Ops Manager reference based on the test context. + """ + resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + resource["spec"]["security"]["tls"]["ca"] = issuer_ca_configmap + return resource + + +@pytest.fixture(scope="module") +def server_certs(issuer: str, namespace: str): + create_sharded_cluster_certs( + namespace, + MDB_RESOURCE_NAME, + shards=1, + mongod_per_shard=1, + config_servers=1, + mongos=1, + ) + + +@pytest.fixture(scope="module") +def agent_certs(issuer: str, namespace: str) -> str: + return create_x509_agent_tls_certs(issuer, namespace, MDB_RESOURCE_NAME) + + +@pytest.mark.e2e_sharded_cluster_x509_switch_project +class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): + """ + E2E test suite for sharded cluster creation, user connectivity with X509 authentication and switching Ops Manager project reference. + """ + + def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): + """ + Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. + """ + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the original cluster. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-X509") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled() + tester.assert_expected_users(0) + + def test_switch_sharded_cluster_project( + self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str + ): + """ + Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + sharded_cluster.load() + sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + sharded_cluster.set_version(custom_mdb_version) + sharded_cluster.update() + + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): + """ + Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. + """ + tester = sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled("MONGODB-X509") + tester.assert_authoritative_set(True) + tester.assert_authentication_enabled() + tester.assert_expected_users(0) From 5db3adb263e026a739031ac7c225e9d29524b4ff Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Thu, 6 Nov 2025 10:47:44 +0100 Subject: [PATCH 4/9] tests: refactoring+improvements --- .evergreen-tasks.yml | 10 + .evergreen.yml | 2 + controllers/om/automation_config.go | 2 +- .../replica-set-ldap-switch-project.yaml | 29 +++ .../sharded-cluster-ldap-switch-project.yaml | 33 ++++ ...-cluster-scram-sha-256-switch-project.yaml | 2 - .../replica_set_ldap_switch_project.py | 174 ++++++++++++++++++ .../replica_set_scram_sha_1_switch_project.py | 60 +++++- ...eplica_set_scram_sha_256_switch_project.py | 59 +++++- .../sharded_cluster_ldap_switch_project.py | 163 ++++++++++++++++ ...rded_cluster_scram_sha_1_switch_project.py | 56 +++++- ...ed_cluster_scram_sha_256_switch_project.py | 56 +++++- 12 files changed, 637 insertions(+), 9 deletions(-) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py diff --git a/.evergreen-tasks.yml b/.evergreen-tasks.yml index 4a8de81e5..2b1b8e989 100644 --- a/.evergreen-tasks.yml +++ b/.evergreen-tasks.yml @@ -720,6 +720,16 @@ tasks: commands: - func: "e2e_test" + - name: e2e_replica_set_ldap_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + + - name: e2e_sharded_cluster_ldap_switch_project + tags: [ "patch-run" ] + commands: + - func: "e2e_test" + # TODO: not used in any variant - name: e2e_replica_set_scram_x509_internal_cluster tags: [ "patch-run" ] diff --git a/.evergreen.yml b/.evergreen.yml index 6205479f4..d760e779e 100644 --- a/.evergreen.yml +++ b/.evergreen.yml @@ -719,6 +719,8 @@ task_groups: - e2e_replica_set_scram_sha_256_switch_project - e2e_replica_set_scram_sha_1_switch_project - e2e_replica_set_x509_switch_project + - e2e_replica_set_ldap_switch_project + - e2e_sharded_cluster_ldap_switch_project # e2e_auth_transitions_task_group - e2e_replica_set_scram_sha_and_x509 - e2e_replica_set_x509_to_scram_transition diff --git a/controllers/om/automation_config.go b/controllers/om/automation_config.go index 9582cd77d..cfc8f49c2 100644 --- a/controllers/om/automation_config.go +++ b/controllers/om/automation_config.go @@ -439,7 +439,7 @@ func (ac *AutomationConfig) EnsureKeyFileContents() error { // AuthSecretName for a given mdbName (`mdbName`) returns the name of // the secret associated with it. func AuthSecretName(mdbName string) string { - return fmt.Sprintf("%s-agent-auth-secre", mdbName) + return fmt.Sprintf("%s-agent-auth-secret", mdbName) } // EnsurePassword makes sure that there is an Automation Agent password diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml new file mode 100644 index 000000000..84574130a --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: replica-set-ldap-switch-project +spec: + type: ReplicaSet + members: 3 + version: 4.4.0-ent + + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + + security: + authentication: + agents: + mode: "SCRAM" + enabled: true + # Enabled LDAP and SCRAM Authentication Mode + modes: ["LDAP", "SCRAM"] + ldap: + servers: "" + transportSecurity: "" + bindQueryUser: "" + bindQueryPasswordSecretRef: + name: "" + \ No newline at end of file diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml new file mode 100644 index 000000000..5ddf246e3 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: mongodb.com/v1 +kind: MongoDB +metadata: + name: sharded-cluster-ldap-switch-project +spec: + type: ShardedCluster + + shardCount: 1 + mongodsPerShardCount: 1 + mongosCount: 1 + configServerCount: 1 + + version: 4.4.0-ent + + opsManager: + configMapRef: + name: my-project + credentials: my-credentials + + security: + authentication: + enabled: true + # Enabled LDAP Authentication Mode + modes: ["LDAP"] + ldap: + servers: "" + transportSecurity: "tls" + # Specify the LDAP Distinguished Name to which + # MongoDB binds when connecting to the LDAP server + bindQueryUser: "cn=admin,dc=example,dc=org" + bindQueryPasswordSecretRef: + name: "" \ No newline at end of file diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml index 1bf83d70d..ff558d3a6 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml @@ -21,5 +21,3 @@ spec: authentication: enabled: true modes: ["SCRAM"] - - diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py new file mode 100644 index 000000000..b3f76e345 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py @@ -0,0 +1,174 @@ +import tempfile +from typing import List + +import pytest +from kubetester import ( + create_or_update_configmap, + create_secret, + find_fixture, + random_k8s_name, + read_configmap, +) +from kubetester.certs import create_mongodb_tls_certs, create_x509_user_cert +from kubetester.kubetester import KubernetesTester +from kubetester.ldap import LDAP_AUTHENTICATION_MECHANISM, LDAPUser, OpenLDAP +from kubetester.mongodb import MongoDB +from kubetester.mongodb_user import MongoDBUser, Role, generic_user +from kubetester.phase import Phase + +MDB_RESOURCE_NAME = "replica-set-ldap-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + """ + Generates a random Kubernetes project name prefix based on the namespace. + + Ensures test isolation in a multi-namespace test environment. + """ + return random_k8s_name(f"{namespace}-project-") + + +@pytest.fixture(scope="module") +def server_certs(namespace: str, issuer: str): + create_mongodb_tls_certs(issuer, namespace, MDB_RESOURCE_NAME, "certs-" + MDB_RESOURCE_NAME + "-cert") + return "certs" + + +@pytest.fixture(scope="module") +def replica_set( + openldap: OpenLDAP, + issuer_ca_configmap: str, + ldap_mongodb_agent_user: LDAPUser, + server_certs: str, + namespace: str, +) -> MongoDB: + resource = MongoDB.from_yaml(find_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + + secret_name = "bind-query-password" + create_secret(namespace, secret_name, {"password": openldap.admin_password}) + ac_secret_name = "automation-config-password" + create_secret( + namespace, + ac_secret_name, + {"automationConfigPassword": ldap_mongodb_agent_user.password}, + ) + + resource["spec"]["security"] = { + "tls": { + "enabled": True, + "ca": issuer_ca_configmap, + }, + "certsSecretPrefix": server_certs, + "authentication": { + "enabled": True, + "modes": ["LDAP", "SCRAM", "X509"], + "ldap": { + "servers": [openldap.servers], + "bindQueryUser": "cn=admin,dc=example,dc=org", + "bindQueryPasswordSecretRef": {"name": secret_name}, + }, + "agents": { + "mode": "LDAP", + "automationPasswordSecretRef": { + "name": ac_secret_name, + "key": "automationConfigPassword", + }, + "automationUserName": ldap_mongodb_agent_user.uid, + }, + }, + } + + return resource + + +@pytest.fixture(scope="module") +def user_ldap(replica_set: MongoDB, namespace: str, ldap_mongodb_users: List[LDAPUser]) -> MongoDBUser: + mongodb_user = ldap_mongodb_users[0] + user = generic_user( + namespace, + username=mongodb_user.username, + db="$external", + password=mongodb_user.password, + mongodb_resource=replica_set, + ) + user.add_roles( + [ + Role(db="admin", role="clusterAdmin"), + Role(db="admin", role="readWriteAnyDatabase"), + Role(db="admin", role="dbAdminAnyDatabase"), + ] + ) + + return user.create() + + +@pytest.mark.e2e_replica_set_ldap_switch_project +class TestReplicaSetLDAPProjectSwitch(KubernetesTester): + + def test_create_replica_set(self, replica_set: MongoDB, ldap_mongodb_users: List[LDAPUser]): + replica_set.update() + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_create_ldap_user(self, replica_set: MongoDB, user_ldap: MongoDBUser): + user_ldap.assert_reaches_phase(Phase.Updated) + + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=True) + tester.assert_expected_users(1) + + def test_new_mdb_users_are_created_and_can_authenticate( + self, replica_set: MongoDB, user_ldap: MongoDBUser, ca_path: str + ): + tester = replica_set.tester() + + tester.assert_ldap_authentication( + username=user_ldap["spec"]["username"], + password=user_ldap.password, + tls_ca_file=ca_path, + attempts=10, + ) + + def test_switch_replica_set_project( + self, replica_set: MongoDB, namespace: str, project_name_prefix: str, user_ldap: MongoDBUser + ): + """ + Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. + """ + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + replica_set.load() + replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + replica_set.update() + + replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_correctly_updated_in_moved_cluster(self, replica_set: MongoDB, user_ldap: MongoDBUser, ca_path: str): + tester = replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=True) + # tester.assert_expected_users(1) + + # tester = replica_set.tester() + # tester.assert_ldap_authentication( + # username=user_ldap["spec"]["username"], + # password=user_ldap.password, + # tls_ca_file=ca_path, + # attempts=10, + # ) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py index 5cf39477e..4a55c52a6 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py @@ -1,8 +1,14 @@ import pytest -from kubetester import create_or_update_configmap, random_k8s_name, read_configmap +from kubetester import ( + create_or_update_configmap, + create_or_update_secret, + random_k8s_name, + read_configmap, +) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB +from kubetester.mongodb_user import MongoDBUser from kubetester.mongotester import ReplicaSetTester from kubetester.phase import Phase @@ -44,6 +50,10 @@ class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): E2E test suite for replica set creation, user connectivity with SCRAM-SHA-1 authentication and switching Ops Manager project reference. """ + PASSWORD_SECRET_NAME = "mms-user-1-password" + USER_PASSWORD = "my-password" + USER_NAME = "mms-user-1" + def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): """ Test replica set creation ensuring resources are applied correctly and set reaches Running phase. @@ -68,6 +78,40 @@ def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replic tester.assert_authentication_enabled(2) tester.assert_expected_users(0) + def test_create_secret(self): + print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") + + create_or_update_secret( + KubernetesTester.get_namespace(), + self.PASSWORD_SECRET_NAME, + { + "password": self.USER_PASSWORD, + }, + ) + + def test_create_user(self, namespace: str): + mdb = MongoDBUser.from_yaml( + load_fixture("scram-sha-user.yaml"), + namespace=namespace, + ) + mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME + + mdb.update() + mdb.assert_reaches_phase(Phase.Updated, timeout=150) + + def test_ops_manager_state_with_users_correctly_updated(self, replica_set: MongoDB): + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + + tester = replica_set.get_automation_config_tester() + tester.assert_has_user(self.USER_NAME) + tester.assert_user_has_roles(self.USER_NAME, expected_roles) + tester.assert_expected_users(1) + def test_switch_replica_set_project( self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str ): @@ -107,4 +151,16 @@ def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_ tester.assert_authentication_mechanism_enabled("MONGODB-CR") tester.assert_authoritative_set(True) tester.assert_authentication_enabled(2) - tester.assert_expected_users(0) + + def test_ops_manager_state_with_users_correctly_updated_after_switch(self, replica_set: MongoDB): + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + + tester = replica_set.get_automation_config_tester() + tester.assert_has_user(self.USER_NAME) + tester.assert_user_has_roles(self.USER_NAME, expected_roles) + tester.assert_expected_users(1) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py index 8269df337..c9be17391 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -1,8 +1,14 @@ import pytest -from kubetester import create_or_update_configmap, random_k8s_name, read_configmap +from kubetester import ( + create_or_update_configmap, + create_or_update_secret, + random_k8s_name, + read_configmap, +) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB +from kubetester.mongodb_user import MongoDBUser from kubetester.mongotester import ReplicaSetTester from kubetester.phase import Phase @@ -43,6 +49,10 @@ class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for replica set creation, user connectivity with SCRAM-SHA-256 authentication and switching Ops Manager project reference. """ + + PASSWORD_SECRET_NAME = "mms-user-1-password" + USER_PASSWORD = "my-password" + USER_NAME = "mms-user-1" def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): """ @@ -66,6 +76,40 @@ def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replic tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() + def test_create_secret(self): + print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") + + create_or_update_secret( + KubernetesTester.get_namespace(), + self.PASSWORD_SECRET_NAME, + { + "password": self.USER_PASSWORD, + }, + ) + + def test_create_user(self, namespace: str): + mdb = MongoDBUser.from_yaml( + load_fixture("scram-sha-user.yaml"), + namespace=namespace, + ) + mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME + + mdb.update() + mdb.assert_reaches_phase(Phase.Updated, timeout=150) + + def test_ops_manager_state_with_users_correctly_updated(self, replica_set: MongoDB): + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + + tester = replica_set.get_automation_config_tester() + tester.assert_has_user(self.USER_NAME) + tester.assert_user_has_roles(self.USER_NAME, expected_roles) + tester.assert_expected_users(1) + def test_switch_replica_set_project( self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str ): @@ -104,3 +148,16 @@ def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_ tester = replica_set.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() + + def test_ops_manager_state_with_users_correctly_updated_after_switch(self, replica_set: MongoDB): + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + + tester = replica_set.get_automation_config_tester() + tester.assert_has_user(self.USER_NAME) + tester.assert_user_has_roles(self.USER_NAME, expected_roles) + tester.assert_expected_users(1) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py new file mode 100644 index 000000000..3c6039054 --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py @@ -0,0 +1,163 @@ +import time +from typing import Dict, List + +import pytest +from kubetester import ( + create_or_update_configmap, + create_secret, + find_fixture, + random_k8s_name, + read_configmap, + wait_until, +) +from kubetester.kubetester import KubernetesTester +from kubetester.kubetester import fixture as yaml_fixture +from kubetester.ldap import LDAP_AUTHENTICATION_MECHANISM, LDAPUser, OpenLDAP +from kubetester.mongodb import MongoDB +from kubetester.mongodb_user import MongoDBUser, Role, generic_user +from kubetester.mongotester import ShardedClusterTester +from kubetester.phase import Phase + +CONFIG_MAP_KEYS = { + "BASE_URL": "baseUrl", + "PROJECT_NAME": "projectName", + "ORG_ID": "orgId", +} + +MDB_RESOURCE_NAME = "sharded-cluster-ldap-switch-project" +MDB_FIXTURE_NAME = MDB_RESOURCE_NAME + + +@pytest.fixture(scope="module") +def operator_installation_config(operator_installation_config_quick_recovery: Dict[str, str]) -> Dict[str, str]: + return operator_installation_config_quick_recovery + + +@pytest.fixture(scope="module") +def project_name_prefix(namespace: str) -> str: + return random_k8s_name(f"{namespace}-project-") + + +@pytest.fixture(scope="module") +def sharded_cluster(namespace: str, openldap_tls: OpenLDAP, issuer_ca_configmap: str) -> MongoDB: + + bind_query_password_secret = "bind-query-password" + resource = MongoDB.from_yaml(find_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + + KubernetesTester.create_secret(namespace, bind_query_password_secret, {"password": openldap_tls.admin_password}) + + resource["spec"]["security"]["authentication"]["ldap"] = { + "servers": [openldap_tls.servers], + "bindQueryPasswordSecretRef": {"name": bind_query_password_secret}, + "transportSecurity": "none", # For testing CLOUDP-229222 + "caConfigMapRef": {"name": issuer_ca_configmap, "key": "ca-pem"}, + } + resource["spec"]["security"]["authentication"]["agents"] = {"mode": "SCRAM"} + resource["spec"]["security"]["authentication"]["modes"] = ["LDAP", "SCRAM"] + + return resource + + +@pytest.fixture(scope="module") +def ldap_user_mongodb(sharded_cluster: MongoDB, namespace: str, ldap_mongodb_user_tls: LDAPUser) -> MongoDBUser: + """Returns a list of MongoDBUsers (already created) and their corresponding passwords.""" + user = generic_user( + namespace, + username=ldap_mongodb_user_tls.username, + db="$external", + mongodb_resource=sharded_cluster, + password=ldap_mongodb_user_tls.password, + ) + user.add_roles( + [ + Role(db="admin", role="clusterAdmin"), + Role(db="admin", role="readWriteAnyDatabase"), + Role(db="admin", role="dbAdminAnyDatabase"), + ] + ) + + return user.create() + + +@pytest.mark.e2e_sharded_cluster_ldap_switch_project +class TestShardedClusterLDAPProjectSwitch(KubernetesTester): + + def test_create_sharded_cluster(self, sharded_cluster: MongoDB): + sharded_cluster.update() + sharded_cluster.assert_reaches_phase(Phase.Pending, timeout=600) + + def test_sharded_cluster_turn_tls_on_CLOUDP_229222(self, sharded_cluster: MongoDB): + """ + This function tests CLOUDP-229222. The user attempts to fix the AutomationConfig. + Before updating the AutomationConfig, we need to ensure the operator pushed the wrong one to Ops Manager. + """ + + def wait_for_ac_exists() -> bool: + ac = sharded_cluster.get_automation_config_tester().automation_config + try: + _ = ac["ldap"]["transportSecurity"] + _ = ac["version"] + return True + except KeyError: + return False + + wait_until(wait_for_ac_exists, timeout=800) + current_version = sharded_cluster.get_automation_config_tester().automation_config["version"] + + def wait_for_ac_pushed() -> bool: + ac = sharded_cluster.get_automation_config_tester().automation_config + try: + transport_security = ac["ldap"]["transportSecurity"] + new_version = ac["version"] + if transport_security != "none": + return False + if new_version <= current_version: + return False + return True + except KeyError: + return False + + wait_until(wait_for_ac_pushed, timeout=800) + + resource = sharded_cluster.load() + resource["spec"]["security"]["authentication"]["ldap"]["transportSecurity"] = "tls" + resource.update() + + def test_sharded_cluster_CLOUDP_229222(self, sharded_cluster: MongoDB, ldap_mongodb_users: List[LDAPUser]): + """ + This function tests CLOUDP-229222. The recovery mechanism kicks in and pushes Automation Config. The ReplicaSet + goes into running state. + """ + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) + + def test_ops_manager_state_correctly_updated_in_initial_cluster( + self, sharded_cluster: MongoDB, ldap_user_mongodb: MongoDBUser + ): + + ldap_user_mongodb.assert_reaches_phase(Phase.Updated) + ac_tester = sharded_cluster.get_automation_config_tester() + ac_tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=False) + ac_tester.assert_expected_users(1) + + def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str): + original_configmap = read_configmap(namespace=namespace, name="my-project") + new_project_name = f"{project_name_prefix}-second" + new_project_configmap = create_or_update_configmap( + namespace=namespace, + name=new_project_name, + data={ + CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], + CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, + CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + }, + ) + + sharded_cluster.reload() + sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + sharded_cluster.update() + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): + ac_tester = sharded_cluster.get_automation_config_tester() + ac_tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=False) + # ac_tester.assert_expected_users(1) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py index f950758ca..5b908b0b7 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py @@ -1,12 +1,14 @@ import pytest from kubetester import ( create_or_update_configmap, + create_or_update_secret, random_k8s_name, read_configmap, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB +from kubetester.mongodb_user import MongoDBUser from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase @@ -47,6 +49,10 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): E2E test suite for sharded cluster creation, user connectivity with SCRAM-SHA-1 authentication and switching Ops Manager project reference. """ + PASSWORD_SECRET_NAME = "mms-user-1-password" + USER_PASSWORD = "my-password" + USER_NAME = "mms-user-1" + def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): """ Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. @@ -71,6 +77,40 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl tester.assert_authentication_enabled(2) tester.assert_expected_users(0) + # def test_create_secret(self): + # print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") + + # create_or_update_secret( + # KubernetesTester.get_namespace(), + # self.PASSWORD_SECRET_NAME, + # { + # "password": self.USER_PASSWORD, + # }, + # ) + + # def test_create_user(self, namespace: str): + # mdb = MongoDBUser.from_yaml( + # load_fixture("scram-sha-user.yaml"), + # namespace=namespace, + # ) + # mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME + + # mdb.update() + # mdb.assert_reaches_phase(Phase.Updated, timeout=150) + + # def test_ops_manager_state_with_users_correctly_updated(self, sharded_cluster: MongoDB): + # expected_roles = { + # ("admin", "clusterAdmin"), + # ("admin", "userAdminAnyDatabase"), + # ("admin", "readWrite"), + # ("admin", "userAdminAnyDatabase"), + # } + + # tester = sharded_cluster.get_automation_config_tester() + # tester.assert_has_user(self.USER_NAME) + # tester.assert_user_has_roles(self.USER_NAME, expected_roles) + # tester.assert_expected_users(1) + def test_switch_sharded_cluster_project( self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str ): @@ -94,7 +134,7 @@ def test_switch_sharded_cluster_project( sharded_cluster.set_version(custom_mdb_version) sharded_cluster.update() - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) def test_moved_sharded_cluster_connectivity(self): """ @@ -110,4 +150,16 @@ def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_clus tester.assert_authentication_mechanism_enabled("MONGODB-CR") tester.assert_authoritative_set(True) tester.assert_authentication_enabled(2) - tester.assert_expected_users(0) + + # def test_ops_manager_state_with_users_correctly_updated_after_switch(self, sharded_cluster: MongoDB): + # expected_roles = { + # ("admin", "clusterAdmin"), + # ("admin", "userAdminAnyDatabase"), + # ("admin", "readWrite"), + # ("admin", "userAdminAnyDatabase"), + # } + + # tester = sharded_cluster.get_automation_config_tester() + # tester.assert_has_user(self.USER_NAME) + # tester.assert_user_has_roles(self.USER_NAME, expected_roles) + # tester.assert_expected_users(1) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py index 6bf798388..4089cd045 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py @@ -1,12 +1,15 @@ import pytest from kubetester import ( create_or_update_configmap, + create_or_update_secret, random_k8s_name, read_configmap, + try_load, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB +from kubetester.mongodb_user import MongoDBUser from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase @@ -47,6 +50,10 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): E2E test suite for sharded cluster creation, user connectivity with SCRAM-SHA-256 authentication and switching Ops Manager project reference. """ + PASSWORD_SECRET_NAME = "mms-user-1-password" + USER_PASSWORD = "my-password" + USER_NAME = "mms-user-1" + def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): """ Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. @@ -69,6 +76,40 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() + # def test_create_secret(self): + # print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") + + # create_or_update_secret( + # KubernetesTester.get_namespace(), + # self.PASSWORD_SECRET_NAME, + # { + # "password": self.USER_PASSWORD, + # }, + # ) + + # def test_create_user(self, namespace: str): + # mdb = MongoDBUser.from_yaml( + # load_fixture("scram-sha-user.yaml"), + # namespace=namespace, + # ) + # mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME + + # mdb.update() + # mdb.assert_reaches_phase(Phase.Updated, timeout=150) + + # def test_ops_manager_state_with_users_correctly_updated(self, sharded_cluster: MongoDB): + # expected_roles = { + # ("admin", "clusterAdmin"), + # ("admin", "userAdminAnyDatabase"), + # ("admin", "readWrite"), + # ("admin", "userAdminAnyDatabase"), + # } + + # tester = sharded_cluster.get_automation_config_tester() + # tester.assert_has_user(self.USER_NAME) + # tester.assert_user_has_roles(self.USER_NAME, expected_roles) + # tester.assert_expected_users(1) + def test_switch_sharded_cluster_project( self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str ): @@ -92,7 +133,7 @@ def test_switch_sharded_cluster_project( sharded_cluster.set_version(custom_mdb_version) sharded_cluster.update() - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) def test_moved_sharded_cluster_connectivity(self): """ @@ -107,3 +148,16 @@ def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_clus tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() + + # def test_ops_manager_state_with_users_correctly_updated_after_switch(self, sharded_cluster: MongoDB): + # expected_roles = { + # ("admin", "clusterAdmin"), + # ("admin", "userAdminAnyDatabase"), + # ("admin", "readWrite"), + # ("admin", "userAdminAnyDatabase"), + # } + + # tester = sharded_cluster.get_automation_config_tester() + # tester.assert_has_user(self.USER_NAME) + # tester.assert_user_has_roles(self.USER_NAME, expected_roles) + # tester.assert_expected_users(1) From 863e34748140abffc943ce483fe5fb40db8621ac Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Thu, 6 Nov 2025 10:49:00 +0100 Subject: [PATCH 5/9] lint --- .../tests/authentication/replica_set_ldap_switch_project.py | 4 +++- .../replica_set_scram_sha_256_switch_project.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py index b3f76e345..224cfff50 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py @@ -160,7 +160,9 @@ def test_switch_replica_set_project( replica_set.assert_reaches_phase(Phase.Running, timeout=600) - def test_ops_manager_state_correctly_updated_in_moved_cluster(self, replica_set: MongoDB, user_ldap: MongoDBUser, ca_path: str): + def test_ops_manager_state_correctly_updated_in_moved_cluster( + self, replica_set: MongoDB, user_ldap: MongoDBUser, ca_path: str + ): tester = replica_set.get_automation_config_tester() tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=True) # tester.assert_expected_users(1) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py index c9be17391..5cb9de414 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -49,7 +49,7 @@ class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for replica set creation, user connectivity with SCRAM-SHA-256 authentication and switching Ops Manager project reference. """ - + PASSWORD_SECRET_NAME = "mms-user-1-password" USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" From a91328194876a8a85ae4830cfd6a01852bac068e Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Mon, 10 Nov 2025 11:09:33 +0100 Subject: [PATCH 6/9] remove new fixtures and use existing ones instead --- controllers/om/automation_config.go | 2 +- .../operator/appdbreplicaset_controller.go | 2 +- .../operator/authentication/authentication.go | 12 ++-- .../authentication_mechanism.go | 2 +- .../configure_authentication_test.go | 16 ++--- controllers/operator/authentication/ldap.go | 2 +- .../operator/authentication/ldap_test.go | 4 +- controllers/operator/authentication/oidc.go | 2 +- .../operator/authentication/oidc_test.go | 4 +- .../operator/authentication/scramsha.go | 8 +-- .../operator/authentication/scramsha_test.go | 4 +- controllers/operator/authentication/x509.go | 2 +- .../operator/authentication/x509_test.go | 4 +- controllers/operator/common_controller.go | 6 +- .../mongodbmultireplicaset_controller.go | 2 +- .../replica-set-explicit-scram-sha-1.yaml | 2 +- .../sharded-cluster-explicit-scram-sha-1.yaml | 2 +- .../replica-set-ldap-switch-project.yaml | 29 -------- ...eplica-set-scram-sha-1-switch-project.yaml | 23 ------- ...lica-set-scram-sha-256-switch-project.yaml | 19 ------ .../replica-set-x509-switch-project.yaml | 23 ------- .../sharded-cluster-ldap-switch-project.yaml | 33 ---------- ...ed-cluster-scram-sha-1-switch-project.yaml | 26 -------- ...-cluster-scram-sha-256-switch-project.yaml | 23 ------- .../sharded-cluster-x509-switch-project.yaml | 27 -------- .../replica_set_ldap_switch_project.py | 45 ++++--------- .../authentication/replica_set_ldap_tls.py | 9 +-- .../replica_set_scram_sha_1_switch_project.py | 63 ++++-------------- ...eplica_set_scram_sha_256_switch_project.py | 63 ++++-------------- .../replica_set_x509_switch_project.py | 51 ++++++-------- .../sharded_cluster_ldap_switch_project.py | 47 +++++-------- ...rded_cluster_scram_sha_1_switch_project.py | 66 +++++-------------- ...ed_cluster_scram_sha_256_switch_project.py | 66 ++++--------------- .../sharded_cluster_x509_switch_project.py | 64 ++++++------------ 34 files changed, 162 insertions(+), 591 deletions(-) delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-256-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml delete mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml diff --git a/controllers/om/automation_config.go b/controllers/om/automation_config.go index cfc8f49c2..060d42b86 100644 --- a/controllers/om/automation_config.go +++ b/controllers/om/automation_config.go @@ -448,7 +448,7 @@ func AuthSecretName(mdbName string) string { // EnsurePassword makes sure that there is an Automation Agent password // that the agents will use to communicate with the deployments. The password // is returned, so it can be provided to the other agents. -func (ac *AutomationConfig) EnsurePassword(k8sClient secret.GetUpdateCreator, ctx context.Context, mdbNamespacedName *types.NamespacedName) (string, error) { +func (ac *AutomationConfig) EnsurePassword(ctx context.Context, k8sClient secret.GetUpdateCreator, mdbNamespacedName types.NamespacedName) (string, error) { secretName := AuthSecretName(mdbNamespacedName.Name) secretNamespacedName := client.ObjectKey{Name: secretName, Namespace: mdbNamespacedName.Namespace} var password string diff --git a/controllers/operator/appdbreplicaset_controller.go b/controllers/operator/appdbreplicaset_controller.go index d2fe09d0d..c208ae314 100644 --- a/controllers/operator/appdbreplicaset_controller.go +++ b/controllers/operator/appdbreplicaset_controller.go @@ -1667,7 +1667,7 @@ func (r *ReconcileAppDbReplicaSet) tryConfigureMonitoringInOpsManager(ctx contex AutoPEMKeyFilePath: agentCertPath, CAFilePath: util.CAFilePathInContainer, } - err = authentication.Configure(r.client, ctx, &types.NamespacedName{Namespace: opsManager.Namespace, Name: opsManager.Name}, conn, opts, false, log) + err = authentication.Configure(r.client, ctx, types.NamespacedName{Namespace: opsManager.Namespace, Name: opsManager.Name}, conn, opts, false, log) if err != nil { log.Errorf("Could not set Automation Authentication options in Ops/Cloud Manager for the Application Database. "+ "Application Database is always configured with authentication enabled, but this will not be "+ diff --git a/controllers/operator/authentication/authentication.go b/controllers/operator/authentication/authentication.go index 6858414a4..7a0ef3bf2 100644 --- a/controllers/operator/authentication/authentication.go +++ b/controllers/operator/authentication/authentication.go @@ -86,7 +86,7 @@ type UserOptions struct { // Configure will configure all the specified authentication Mechanisms. We need to ensure we wait for // the agents to reach ready state after each operation as prematurely updating the automation config can cause the agents to get stuck. -func Configure(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, isRecovering bool, log *zap.SugaredLogger) error { +func Configure(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, isRecovering bool, log *zap.SugaredLogger) error { log.Infow("ensuring correct deployment mechanisms", "ProcessNames", opts.ProcessNames, "Mechanisms", opts.Mechanisms) // In case we're recovering, we can push all changes at once, because the mechanism is triggered after 20min by default. @@ -155,7 +155,7 @@ func Configure(client kubernetesClient.Client, ctx context.Context, mdbNamespace // Disable disables all authentication mechanisms, and waits for the agents to reach goal state. It is still required to provide // automation agent username, password and keyfile contents to ensure a valid Automation Config. -func Disable(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, deleteUsers bool, log *zap.SugaredLogger) error { +func Disable(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, deleteUsers bool, log *zap.SugaredLogger) error { ac, err := conn.ReadAutomationConfig() if err != nil { return xerrors.Errorf("error reading automation config: %w", err) @@ -185,7 +185,7 @@ func Disable(client kubernetesClient.Client, ctx context.Context, mdbNamespacedN if err := ac.EnsureKeyFileContents(); err != nil { return xerrors.Errorf("error ensuring keyfile contents: %w", err) } - if _, err := ac.EnsurePassword(client, ctx, mdbNamespacedName); err != nil { + if _, err := ac.EnsurePassword(ctx, client, mdbNamespacedName); err != nil { return xerrors.Errorf("error ensuring agent password: %w", err) } @@ -262,7 +262,7 @@ func removeUnsupportedAgentMechanisms(conn om.Connection, opts Options, log *zap // enableAgentAuthentication determines which agent authentication mechanism should be configured // and enables it in Ops Manager -func enableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func enableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { ac, err := conn.ReadAutomationConfig() if err != nil { return xerrors.Errorf("error reading automation config: %w", err) @@ -369,14 +369,14 @@ func addOrRemoveAgentClientCertificate(conn om.Connection, opts Options, log *za } // ensureAgentAuthenticationIsConfigured will configure the agent authentication settings based on the desiredAgentAuthMechanism -func ensureAgentAuthenticationIsConfigured(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error { +func ensureAgentAuthenticationIsConfigured(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error { if mechanism.IsAgentAuthenticationConfigured(ac, opts) { log.Infof("Agent authentication mechanism %s is already configured", mechanism.GetName()) return nil } log.Infof("Enabling %s agent authentication", mechanism.GetName()) - return mechanism.EnableAgentAuthentication(client, ctx, mdbNamespacedName, conn, opts, log) + return mechanism.EnableAgentAuthentication(ctx, client, mdbNamespacedName, conn, opts, log) } // ensureDeploymentMechanisms configures the given AutomationConfig to allow deployments to diff --git a/controllers/operator/authentication/authentication_mechanism.go b/controllers/operator/authentication/authentication_mechanism.go index ba65e1324..773526c8b 100644 --- a/controllers/operator/authentication/authentication_mechanism.go +++ b/controllers/operator/authentication/authentication_mechanism.go @@ -16,7 +16,7 @@ import ( // Mechanism is an interface that needs to be implemented for any Ops Manager authentication mechanism type Mechanism interface { - EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error + EnableAgentAuthentication(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error DisableAgentAuthentication(conn om.Connection, log *zap.SugaredLogger) error EnableDeploymentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error DisableDeploymentAuthentication(conn om.Connection, log *zap.SugaredLogger) error diff --git a/controllers/operator/authentication/configure_authentication_test.go b/controllers/operator/authentication/configure_authentication_test.go index 5a6dcc79e..1a13893d9 100644 --- a/controllers/operator/authentication/configure_authentication_test.go +++ b/controllers/operator/authentication/configure_authentication_test.go @@ -22,7 +22,7 @@ func init() { func TestConfigureScramSha256(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -50,7 +50,7 @@ func TestConfigureScramSha256(t *testing.T) { func TestConfigureX509(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -82,7 +82,7 @@ func TestConfigureX509(t *testing.T) { func TestConfigureScramSha1(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -108,7 +108,7 @@ func TestConfigureScramSha1(t *testing.T) { func TestConfigureMultipleAuthenticationMechanisms(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -145,7 +145,7 @@ func TestConfigureMultipleAuthenticationMechanisms(t *testing.T) { func TestDisableAuthentication(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} dep := om.NewDeployment() conn := om.NewMockedOmConnection(dep) @@ -156,7 +156,7 @@ func TestDisableAuthentication(t *testing.T) { return nil }, zap.S()) - if err := Disable(kubeClient, ctx, mdbNamespacedName, conn, Options{}, true, zap.S()); err != nil { + if err := Disable(ctx, kubeClient, mdbNamespacedName, conn, Options{}, true, zap.S()); err != nil { t.Fatal(err) } @@ -237,9 +237,9 @@ func assertDeploymentMechanismsConfigured(t *testing.T, authMechanism Mechanism, func assertAgentAuthenticationDisabled(t *testing.T, authMechanism Mechanism, conn om.Connection, opts Options) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} - err := authMechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) + err := authMechanism.EnableAgentAuthentication(ctx, kubeClient, mdbNamespacedName, conn, opts, zap.S()) require.NoError(t, err) ac, err := conn.ReadAutomationConfig() diff --git a/controllers/operator/authentication/ldap.go b/controllers/operator/authentication/ldap.go index 9d7a95445..3ac056c99 100644 --- a/controllers/operator/authentication/ldap.go +++ b/controllers/operator/authentication/ldap.go @@ -19,7 +19,7 @@ func (l *ldapAuthMechanism) GetName() MechanismName { return LDAPPlain } -func (l *ldapAuthMechanism) EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func (l *ldapAuthMechanism) EnableAgentAuthentication(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { log.Info("Configuring LDAP authentication") err := conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error { if err := ac.EnsureKeyFileContents(); err != nil { diff --git a/controllers/operator/authentication/ldap_test.go b/controllers/operator/authentication/ldap_test.go index 54d96336e..2472e7086 100644 --- a/controllers/operator/authentication/ldap_test.go +++ b/controllers/operator/authentication/ldap_test.go @@ -50,7 +50,7 @@ func TestLdapDeploymentMechanism(t *testing.T) { func TestLdapEnableAgentAuthentication(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} conn := om.NewMockedOmConnection(om.NewDeployment()) opts := Options{ @@ -62,7 +62,7 @@ func TestLdapEnableAgentAuthentication(t *testing.T) { AutoPwd: "LDAPPassword.", } - err := ldapPlainMechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) + err := ldapPlainMechanism.EnableAgentAuthentication(ctx, kubeClient, mdbNamespacedName, conn, opts, zap.S()) require.NoError(t, err) ac, err := conn.ReadAutomationConfig() diff --git a/controllers/operator/authentication/oidc.go b/controllers/operator/authentication/oidc.go index dec32e27f..583109722 100644 --- a/controllers/operator/authentication/oidc.go +++ b/controllers/operator/authentication/oidc.go @@ -23,7 +23,7 @@ func (o *oidcAuthMechanism) GetName() MechanismName { return MongoDBOIDC } -func (o *oidcAuthMechanism) EnableAgentAuthentication(_ kubernetesClient.Client, _ context.Context, _ *types.NamespacedName, _ om.Connection, _ Options, _ *zap.SugaredLogger) error { +func (o *oidcAuthMechanism) EnableAgentAuthentication(_ context.Context, _ kubernetesClient.Client, _ types.NamespacedName, _ om.Connection, _ Options, _ *zap.SugaredLogger) error { return xerrors.Errorf("OIDC agent authentication is not supported") } diff --git a/controllers/operator/authentication/oidc_test.go b/controllers/operator/authentication/oidc_test.go index 5191eaf0e..c5ac89e2b 100644 --- a/controllers/operator/authentication/oidc_test.go +++ b/controllers/operator/authentication/oidc_test.go @@ -82,7 +82,7 @@ func TestOIDC_EnableDeploymentAuthentication(t *testing.T) { func TestOIDC_EnableAgentAuthentication(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} conn := om.NewMockedOmConnection(om.NewDeployment()) opts := Options{ @@ -95,7 +95,7 @@ func TestOIDC_EnableAgentAuthentication(t *testing.T) { configured := mongoDBOIDCMechanism.IsAgentAuthenticationConfigured(ac, opts) assert.False(t, configured) - err = mongoDBOIDCMechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) + err = mongoDBOIDCMechanism.EnableAgentAuthentication(ctx, kubeClient, mdbNamespacedName, conn, opts, zap.S()) require.Error(t, err) err = mongoDBOIDCMechanism.DisableAgentAuthentication(conn, zap.S()) diff --git a/controllers/operator/authentication/scramsha.go b/controllers/operator/authentication/scramsha.go index b03b8b94d..bf293026e 100644 --- a/controllers/operator/authentication/scramsha.go +++ b/controllers/operator/authentication/scramsha.go @@ -22,9 +22,9 @@ func (s *automationConfigScramSha) GetName() MechanismName { return s.MechanismName } -func (s *automationConfigScramSha) EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func (s *automationConfigScramSha) EnableAgentAuthentication(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { return conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error { - if err := configureScramAgentUsers(client, ctx, mdbNamespacedName, ac, opts); err != nil { + if err := configureScramAgentUsers(ctx, client, mdbNamespacedName, ac, opts); err != nil { return err } if err := ac.EnsureKeyFileContents(); err != nil { @@ -95,8 +95,8 @@ func (s *automationConfigScramSha) IsDeploymentAuthenticationEnabled(ac *om.Auto } // configureScramAgentUsers makes sure that the given automation config always has the correct SCRAM-SHA users -func configureScramAgentUsers(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, ac *om.AutomationConfig, authOpts Options) error { - agentPassword, err := ac.EnsurePassword(client, ctx, mdbNamespacedName) +func configureScramAgentUsers(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, ac *om.AutomationConfig, authOpts Options) error { + agentPassword, err := ac.EnsurePassword(ctx, client, mdbNamespacedName) if err != nil { return err } diff --git a/controllers/operator/authentication/scramsha_test.go b/controllers/operator/authentication/scramsha_test.go index f998f7153..2fd600a08 100644 --- a/controllers/operator/authentication/scramsha_test.go +++ b/controllers/operator/authentication/scramsha_test.go @@ -39,7 +39,7 @@ func TestAgentsAuthentication(t *testing.T) { t.Run(testName, func(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} conn := om.NewMockedOmConnection(om.NewDeployment()) @@ -50,7 +50,7 @@ func TestAgentsAuthentication(t *testing.T) { CAFilePath: util.CAFilePathInContainer, } - err := s.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, opts, zap.S()) + err := s.EnableAgentAuthentication(ctx, kubeClient, mdbNamespacedName, conn, opts, zap.S()) require.NoError(t, err) err = s.EnableDeploymentAuthentication(conn, opts, zap.S()) diff --git a/controllers/operator/authentication/x509.go b/controllers/operator/authentication/x509.go index 02e429ce5..3814641f4 100644 --- a/controllers/operator/authentication/x509.go +++ b/controllers/operator/authentication/x509.go @@ -19,7 +19,7 @@ func (x *connectionX509) GetName() MechanismName { return MongoDBX509 } -func (x *connectionX509) EnableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName *types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func (x *connectionX509) EnableAgentAuthentication(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { log.Info("Configuring x509 authentication") err := conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error { if err := ac.EnsureKeyFileContents(); err != nil { diff --git a/controllers/operator/authentication/x509_test.go b/controllers/operator/authentication/x509_test.go index b7022f57e..09fa54a15 100644 --- a/controllers/operator/authentication/x509_test.go +++ b/controllers/operator/authentication/x509_test.go @@ -20,7 +20,7 @@ var mongoDBX509Mechanism = getMechanismByName(MongoDBX509) func TestX509EnableAgentAuthentication(t *testing.T) { ctx := context.Background() kubeClient, _ := mock.NewDefaultFakeClient() - mdbNamespacedName := &types.NamespacedName{Namespace: "test", Name: "test"} + mdbNamespacedName := types.NamespacedName{Namespace: "test", Name: "test"} conn := om.NewMockedOmConnection(om.NewDeployment()) @@ -32,7 +32,7 @@ func TestX509EnableAgentAuthentication(t *testing.T) { }, AuthoritativeSet: true, } - if err := mongoDBX509Mechanism.EnableAgentAuthentication(kubeClient, ctx, mdbNamespacedName, conn, options, zap.S()); err != nil { + if err := mongoDBX509Mechanism.EnableAgentAuthentication(ctx, kubeClient, mdbNamespacedName, conn, options, zap.S()); err != nil { t.Fatal(err) } diff --git a/controllers/operator/common_controller.go b/controllers/operator/common_controller.go index 72babde36..0438197e6 100644 --- a/controllers/operator/common_controller.go +++ b/controllers/operator/common_controller.go @@ -514,7 +514,7 @@ func (r *ReconcileCommonController) updateOmAuthentication(ctx context.Context, authOpts.UserOptions = userOpts } - if err := authentication.Configure(r.client, ctx, &types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, isRecovering, log); err != nil { + if err := authentication.Configure(r.client, ctx, types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, isRecovering, log); err != nil { return workflow.Failed(err), false } } else if wantToEnableAuthentication { @@ -533,7 +533,7 @@ func (r *ReconcileCommonController) updateOmAuthentication(ctx context.Context, } authOpts.UserOptions = userOpts - if err := authentication.Disable(r.client, ctx, &types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, false, log); err != nil { + if err := authentication.Disable(ctx, r.client, types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, false, log); err != nil { return workflow.Failed(err), false } } @@ -597,7 +597,7 @@ func (r *ReconcileCommonController) clearProjectAuthenticationSettings(ctx conte UserOptions: userOpts, } - return authentication.Disable(r.client, ctx, &types.NamespacedName{Namespace: mdb.Namespace, Name: mdb.Name}, conn, disableOpts, true, log) + return authentication.Disable(ctx, r.client, types.NamespacedName{Namespace: mdb.Namespace, Name: mdb.Name}, conn, disableOpts, true, log) } // ensureX509SecretAndCheckTLSType checks if the secrets containing the certificates are present and whether the certificate are of kubernetes.io/tls type. diff --git a/controllers/operator/mongodbmultireplicaset_controller.go b/controllers/operator/mongodbmultireplicaset_controller.go index 119d5cf12..2a90289ea 100644 --- a/controllers/operator/mongodbmultireplicaset_controller.go +++ b/controllers/operator/mongodbmultireplicaset_controller.go @@ -1236,7 +1236,7 @@ func (r *ReconcileMongoDbMultiReplicaSet) cleanOpsManagerState(ctx context.Conte ProcessNames: processNames, } - if err := authentication.Disable(r.client, ctx, &types.NamespacedName{Namespace: mrs.GetNamespace(), Name: mrs.GetName()}, conn, opts, true, log); err != nil { + if err := authentication.Disable(ctx, r.client, types.NamespacedName{Namespace: mrs.GetNamespace(), Name: mrs.GetName()}, conn, opts, true, log); err != nil { return err } log.Infof("Removed deployment %s from Ops Manager at %s", mrs.Name, conn.BaseURL()) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-explicit-scram-sha-1.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-explicit-scram-sha-1.yaml index 6f675c15b..5b7e816b1 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-explicit-scram-sha-1.yaml +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/replica-set-explicit-scram-sha-1.yaml @@ -17,7 +17,7 @@ spec: authentication: agents: # This may look weird, but without it we'll get this from OpsManager: - # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode + # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in the Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode mode: MONGODB-CR enabled: true modes: ["SCRAM-SHA-1", "MONGODB-CR"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-explicit-scram-sha-1.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-explicit-scram-sha-1.yaml index f4070ad60..330e3f026 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-explicit-scram-sha-1.yaml +++ b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/sharded-cluster-explicit-scram-sha-1.yaml @@ -20,7 +20,7 @@ spec: authentication: agents: # This may look weird, but without it we'll get this from OpsManager: - # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode + # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in the Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode mode: MONGODB-CR enabled: true modes: ["SCRAM-SHA-1", "MONGODB-CR"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml deleted file mode 100644 index 84574130a..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-ldap-switch-project.yaml +++ /dev/null @@ -1,29 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: replica-set-ldap-switch-project -spec: - type: ReplicaSet - members: 3 - version: 4.4.0-ent - - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - - security: - authentication: - agents: - mode: "SCRAM" - enabled: true - # Enabled LDAP and SCRAM Authentication Mode - modes: ["LDAP", "SCRAM"] - ldap: - servers: "" - transportSecurity: "" - bindQueryUser: "" - bindQueryPasswordSecretRef: - name: "" - \ No newline at end of file diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml deleted file mode 100644 index c4cf66ea5..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-1-switch-project.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: replica-set-scram-sha-1-switch-project -spec: - members: 3 - version: 5.0.5 - type: ReplicaSet - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - logLevel: DEBUG - persistent: false - security: - authentication: - agents: - # This may look weird, but without it we'll get this from OpsManager: - # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode - mode: MONGODB-CR - enabled: true - modes: ["SCRAM-SHA-1", "MONGODB-CR"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-256-switch-project.yaml deleted file mode 100644 index be90421fc..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-scram-sha-256-switch-project.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: replica-set-scram-sha-256-switch-project -spec: - members: 3 - version: 4.4.0 - type: ReplicaSet - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - logLevel: DEBUG - persistent: false - security: - authentication: - enabled: true - modes: ["SCRAM"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml deleted file mode 100644 index ee79c38f9..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/replica-set-x509-switch-project.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: replica-set-x509-switch-project -spec: - members: 3 - version: 4.4.0-ent - type: ReplicaSet - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - logLevel: DEBUG - persistent: false - security: - tls: - enabled: true - authentication: - agents: - mode: X509 - enabled: true - modes: ["X509"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml deleted file mode 100644 index 5ddf246e3..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-ldap-switch-project.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: sharded-cluster-ldap-switch-project -spec: - type: ShardedCluster - - shardCount: 1 - mongodsPerShardCount: 1 - mongosCount: 1 - configServerCount: 1 - - version: 4.4.0-ent - - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - - security: - authentication: - enabled: true - # Enabled LDAP Authentication Mode - modes: ["LDAP"] - ldap: - servers: "" - transportSecurity: "tls" - # Specify the LDAP Distinguished Name to which - # MongoDB binds when connecting to the LDAP server - bindQueryUser: "cn=admin,dc=example,dc=org" - bindQueryPasswordSecretRef: - name: "" \ No newline at end of file diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml deleted file mode 100644 index 837ff206e..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-1-switch-project.yaml +++ /dev/null @@ -1,26 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: sharded-cluster-scram-sha-1-switch-project -spec: - shardCount: 1 - type: ShardedCluster - mongodsPerShardCount: 1 - mongosCount: 1 - configServerCount: 1 - version: 5.0.5 - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - logLevel: DEBUG - persistent: true - security: - authentication: - agents: - # This may look weird, but without it we'll get this from OpsManager: - # Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode","reason":"Cannot configure SCRAM-SHA-1 without using MONGODB-CR in te Agent Mode - mode: MONGODB-CR - enabled: true - modes: ["SCRAM-SHA-1", "MONGODB-CR"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml deleted file mode 100644 index ff558d3a6..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-scram-sha-256-switch-project.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: sharded-cluster-scram-sha-256-switch-project -spec: - shardCount: 1 - mongodsPerShardCount: 1 - mongosCount: 1 - configServerCount: 1 - version: 4.4.0 - type: ShardedCluster - - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - - persistent: true - security: - authentication: - enabled: true - modes: ["SCRAM"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml b/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml deleted file mode 100644 index 2169679fc..000000000 --- a/docker/mongodb-kubernetes-tests/tests/authentication/fixtures/switch-project/sharded-cluster-x509-switch-project.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -apiVersion: mongodb.com/v1 -kind: MongoDB -metadata: - name: sharded-cluster-x509-switch-project -spec: - shardCount: 1 - mongodsPerShardCount: 1 - mongosCount: 1 - configServerCount: 1 - version: 4.4.0-ent - type: ShardedCluster - - opsManager: - configMapRef: - name: my-project - credentials: my-credentials - - persistent: true - security: - tls: - enabled: true - authentication: - agents: - mode: X509 - enabled: true - modes: ["X509"] diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py index 224cfff50..d7c77cac5 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py @@ -6,8 +6,8 @@ create_or_update_configmap, create_secret, find_fixture, - random_k8s_name, read_configmap, + try_load, ) from kubetester.certs import create_mongodb_tls_certs, create_x509_user_cert from kubetester.kubetester import KubernetesTester @@ -17,23 +17,6 @@ from kubetester.phase import Phase MDB_RESOURCE_NAME = "replica-set-ldap-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - - -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") @pytest.fixture(scope="module") @@ -50,7 +33,12 @@ def replica_set( server_certs: str, namespace: str, ) -> MongoDB: - resource = MongoDB.from_yaml(find_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + resource = MongoDB.from_yaml( + find_fixture("ldap/ldap-replica-set.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + + if try_load(resource): + return resource secret_name = "bind-query-password" create_secret(namespace, secret_name, {"password": openldap.admin_password}) @@ -86,7 +74,7 @@ def replica_set( }, } - return resource + return resource.update() @pytest.fixture(scope="module") @@ -114,7 +102,6 @@ def user_ldap(replica_set: MongoDB, namespace: str, ldap_mongodb_users: List[LDA class TestReplicaSetLDAPProjectSwitch(KubernetesTester): def test_create_replica_set(self, replica_set: MongoDB, ldap_mongodb_users: List[LDAPUser]): - replica_set.update() replica_set.assert_reaches_phase(Phase.Running, timeout=600) def test_create_ldap_user(self, replica_set: MongoDB, user_ldap: MongoDBUser): @@ -136,25 +123,19 @@ def test_new_mdb_users_are_created_and_can_authenticate( attempts=10, ) - def test_switch_replica_set_project( - self, replica_set: MongoDB, namespace: str, project_name_prefix: str, user_ldap: MongoDBUser - ): - """ - Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. - """ + def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str, user_ldap: MongoDBUser): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - replica_set.load() replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap replica_set.update() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_tls.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_tls.py index e7359205b..34ed24791 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_tls.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_tls.py @@ -50,8 +50,7 @@ def replica_set( "caConfigMapRef": {"name": issuer_ca_configmap, "key": "ca-pem"}, } - resource.update() - return resource + return resource.update() @fixture(scope="module") @@ -106,9 +105,8 @@ def wait_for_ac_pushed() -> bool: wait_until(wait_for_ac_pushed, timeout=200) - resource = replica_set.load() - resource["spec"]["security"]["authentication"]["ldap"]["transportSecurity"] = "tls" - resource.update() + replica_set["spec"]["security"]["authentication"]["ldap"]["transportSecurity"] = "tls" + replica_set.update() @mark.e2e_replica_set_ldap_tls @@ -140,7 +138,6 @@ def test_new_ldap_users_can_authenticate(replica_set: MongoDB, ldap_user_mongodb def test_remove_ldap_settings(replica_set: MongoDB): replica_set.assert_reaches_phase(Phase.Running, timeout=400) - replica_set.load() replica_set["spec"]["security"]["authentication"]["ldap"] = None replica_set["spec"]["security"]["authentication"]["modes"] = ["SCRAM"] replica_set.update() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py index 4a55c52a6..59d011fd6 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py @@ -2,8 +2,8 @@ from kubetester import ( create_or_update_configmap, create_or_update_secret, - random_k8s_name, read_configmap, + try_load, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture @@ -14,13 +14,6 @@ # Constants MDB_RESOURCE_NAME = "replica-set-scram-sha-1-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} @pytest.fixture(scope="module") @@ -30,18 +23,14 @@ def replica_set(namespace: str) -> MongoDB: Dynamically updates the resource configuration based on the test context. """ - resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) - return resource + resource = MongoDB.from_yaml( + load_fixture("replica-set-explicit-scram-sha-1.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + if try_load(resource): + return resource -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") + return resource.update() @pytest.mark.e2e_replica_set_scram_sha_1_switch_project @@ -54,24 +43,13 @@ class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" - def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): - """ - Test replica set creation ensuring resources are applied correctly and set reaches Running phase. - """ - replica_set.set_version(custom_mdb_version) - replica_set.update() + def test_create_replica_set(self, replica_set: MongoDB): replica_set.assert_reaches_phase(Phase.Running, timeout=600) def test_replica_set_connectivity(self): - """ - Verify connectivity to the original replica set. - """ ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original replica set. - """ tester = replica_set.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("MONGODB-CR") tester.assert_authoritative_set(True) @@ -79,8 +57,6 @@ def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replic tester.assert_expected_users(0) def test_create_secret(self): - print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") - create_or_update_secret( KubernetesTester.get_namespace(), self.PASSWORD_SECRET_NAME, @@ -112,41 +88,28 @@ def test_ops_manager_state_with_users_correctly_updated(self, replica_set: Mongo tester.assert_user_has_roles(self.USER_NAME, expected_roles) tester.assert_expected_users(1) - def test_switch_replica_set_project( - self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. - """ + def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - replica_set.load() replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.set_version(custom_mdb_version) replica_set.update() replica_set.assert_reaches_phase(Phase.Running, timeout=600) def test_moved_replica_set_connectivity(self): - """ - Verify connectivity to the replica set after switching projects. - """ ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. - """ tester = replica_set.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("MONGODB-CR") tester.assert_authoritative_set(True) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py index 5cb9de414..4831f5379 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -2,8 +2,8 @@ from kubetester import ( create_or_update_configmap, create_or_update_secret, - random_k8s_name, read_configmap, + try_load, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture @@ -14,13 +14,6 @@ # Constants MDB_RESOURCE_NAME = "replica-set-scram-sha-256-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} @pytest.fixture(scope="module") @@ -30,18 +23,14 @@ def replica_set(namespace: str) -> MongoDB: Dynamically updates the resource configuration based on the test context. """ - resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) - return resource + resource = MongoDB.from_yaml( + load_fixture("replica-set-scram-sha-256.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + if try_load(resource): + return resource -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") + return resource.update() @pytest.mark.e2e_replica_set_scram_sha_256_switch_project @@ -54,31 +43,18 @@ class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" - def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): - """ - Test replica set creation ensuring resources are applied correctly and set reaches Running phase. - """ - replica_set.set_version(custom_mdb_version) - replica_set.update() + def test_create_replica_set(self, replica_set: MongoDB): replica_set.assert_reaches_phase(Phase.Running, timeout=600) def test_replica_set_connectivity(self): - """ - Verify connectivity to the original replica set. - """ ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original replica set. - """ tester = replica_set.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() def test_create_secret(self): - print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") - create_or_update_secret( KubernetesTester.get_namespace(), self.PASSWORD_SECRET_NAME, @@ -110,41 +86,28 @@ def test_ops_manager_state_with_users_correctly_updated(self, replica_set: Mongo tester.assert_user_has_roles(self.USER_NAME, expected_roles) tester.assert_expected_users(1) - def test_switch_replica_set_project( - self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. - """ + def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - replica_set.load() replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.set_version(custom_mdb_version) replica_set.update() replica_set.assert_reaches_phase(Phase.Running, timeout=600) def test_moved_replica_set_connectivity(self): - """ - Verify connectivity to the replica set after switching projects. - """ ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. - """ tester = replica_set.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py index 7b23a901d..1ad8885ec 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py @@ -1,5 +1,9 @@ import pytest -from kubetester import create_or_update_configmap, random_k8s_name, read_configmap +from kubetester import ( + create_or_update_configmap, + read_configmap, + try_load, +) from kubetester.certs import ( ISSUER_CA_NAME, create_agent_tls_certs, @@ -13,13 +17,6 @@ # Constants MDB_RESOURCE_NAME = "replica-set-x509-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} @pytest.fixture(scope="module") @@ -29,9 +26,15 @@ def replica_set(namespace: str, server_certs: str, agent_certs: str, issuer_ca_c Dynamically updates the resource configuration based on the test context. """ - resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + resource = MongoDB.from_yaml( + load_fixture("replica-set-x509-to-scram-256.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + + if try_load(resource): + return resource + resource["spec"]["security"]["tls"]["ca"] = issuer_ca_configmap - return resource + return resource.update() @pytest.fixture(scope="module") @@ -44,28 +47,16 @@ def agent_certs(issuer: str, namespace: str) -> str: return create_agent_tls_certs(issuer, namespace, MDB_RESOURCE_NAME) -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") - - @pytest.mark.e2e_replica_set_x509_switch_project class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for replica set creation, user connectivity with X509 authentication and switching Ops Manager project reference. """ - def test_create_replica_set(self, custom_mdb_version: str, replica_set: MongoDB): + def test_create_replica_set(self, replica_set: MongoDB): """ Test replica set creation ensuring resources are applied correctly and set reaches Running phase. """ - replica_set.set_version(custom_mdb_version) - replica_set.update() replica_set.assert_reaches_phase(Phase.Running, timeout=600) def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): @@ -78,27 +69,23 @@ def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replic tester.assert_authentication_enabled() tester.assert_expected_users(0) - def test_switch_replica_set_project( - self, custom_mdb_version: str, replica_set: MongoDB, namespace: str, project_name_prefix: str - ): + def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str): """ Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. """ original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - replica_set.load() replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.set_version(custom_mdb_version) replica_set.update() replica_set.assert_reaches_phase(Phase.Running, timeout=600) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py index 3c6039054..bf24d88fc 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py @@ -6,8 +6,8 @@ create_or_update_configmap, create_secret, find_fixture, - random_k8s_name, read_configmap, + try_load, wait_until, ) from kubetester.kubetester import KubernetesTester @@ -18,14 +18,7 @@ from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - MDB_RESOURCE_NAME = "sharded-cluster-ldap-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME @pytest.fixture(scope="module") @@ -33,16 +26,16 @@ def operator_installation_config(operator_installation_config_quick_recovery: Di return operator_installation_config_quick_recovery -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - return random_k8s_name(f"{namespace}-project-") - - @pytest.fixture(scope="module") def sharded_cluster(namespace: str, openldap_tls: OpenLDAP, issuer_ca_configmap: str) -> MongoDB: bind_query_password_secret = "bind-query-password" - resource = MongoDB.from_yaml(find_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + resource = MongoDB.from_yaml( + find_fixture("ldap/ldap-sharded-cluster.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + + if try_load(resource): + return resource KubernetesTester.create_secret(namespace, bind_query_password_secret, {"password": openldap_tls.admin_password}) @@ -55,7 +48,7 @@ def sharded_cluster(namespace: str, openldap_tls: OpenLDAP, issuer_ca_configmap: resource["spec"]["security"]["authentication"]["agents"] = {"mode": "SCRAM"} resource["spec"]["security"]["authentication"]["modes"] = ["LDAP", "SCRAM"] - return resource + return resource.update() @pytest.fixture(scope="module") @@ -87,10 +80,6 @@ def test_create_sharded_cluster(self, sharded_cluster: MongoDB): sharded_cluster.assert_reaches_phase(Phase.Pending, timeout=600) def test_sharded_cluster_turn_tls_on_CLOUDP_229222(self, sharded_cluster: MongoDB): - """ - This function tests CLOUDP-229222. The user attempts to fix the AutomationConfig. - Before updating the AutomationConfig, we need to ensure the operator pushed the wrong one to Ops Manager. - """ def wait_for_ac_exists() -> bool: ac = sharded_cluster.get_automation_config_tester().automation_config @@ -119,15 +108,10 @@ def wait_for_ac_pushed() -> bool: wait_until(wait_for_ac_pushed, timeout=800) - resource = sharded_cluster.load() - resource["spec"]["security"]["authentication"]["ldap"]["transportSecurity"] = "tls" - resource.update() + sharded_cluster["spec"]["security"]["authentication"]["ldap"]["transportSecurity"] = "tls" + sharded_cluster.update() def test_sharded_cluster_CLOUDP_229222(self, sharded_cluster: MongoDB, ldap_mongodb_users: List[LDAPUser]): - """ - This function tests CLOUDP-229222. The recovery mechanism kicks in and pushes Automation Config. The ReplicaSet - goes into running state. - """ sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) def test_ops_manager_state_correctly_updated_in_initial_cluster( @@ -139,20 +123,19 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster( ac_tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=False) ac_tester.assert_expected_users(1) - def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str): + def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - sharded_cluster.reload() sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap sharded_cluster.update() sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py index 5b908b0b7..6ef224baa 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py @@ -2,8 +2,8 @@ from kubetester import ( create_or_update_configmap, create_or_update_secret, - random_k8s_name, read_configmap, + try_load, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture @@ -12,24 +12,7 @@ from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-1-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - - -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") @pytest.fixture(scope="module") @@ -39,8 +22,14 @@ def sharded_cluster(namespace: str) -> MongoDB: Dynamically updates the resource Ops Manager reference based on the test context. """ - resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) - return resource + resource = MongoDB.from_yaml( + load_fixture("sharded-cluster-explicit-scram-sha-1.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + + if try_load(resource): + return resource + + return resource.update() @pytest.mark.e2e_sharded_cluster_scram_sha_1_switch_project @@ -53,24 +42,13 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" - def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): - """ - Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. - """ - sharded_cluster.set_version(custom_mdb_version) - sharded_cluster.update() + def test_create_sharded_cluster(self, sharded_cluster: MongoDB): sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) def test_sharded_cluster_connectivity(self): - """ - Verify connectivity to the original sharded cluster. - """ ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original cluster. - """ tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("MONGODB-CR") tester.assert_authoritative_set(True) @@ -78,7 +56,6 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl tester.assert_expected_users(0) # def test_create_secret(self): - # print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") # create_or_update_secret( # KubernetesTester.get_namespace(), @@ -111,41 +88,28 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl # tester.assert_user_has_roles(self.USER_NAME, expected_roles) # tester.assert_expected_users(1) - def test_switch_sharded_cluster_project( - self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. - """ + def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - sharded_cluster.load() sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.set_version(custom_mdb_version) sharded_cluster.update() sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) def test_moved_sharded_cluster_connectivity(self): - """ - Verify connectivity to the sharded cluster after project switch. - """ ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. - """ tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("MONGODB-CR") tester.assert_authoritative_set(True) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py index 4089cd045..537651d17 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py @@ -2,7 +2,6 @@ from kubetester import ( create_or_update_configmap, create_or_update_secret, - random_k8s_name, read_configmap, try_load, ) @@ -13,24 +12,7 @@ from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-256-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - - -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") @pytest.fixture(scope="module") @@ -40,8 +22,14 @@ def sharded_cluster(namespace: str) -> MongoDB: Dynamically updates the resource Ops Manager reference based on the test context. """ - resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) - return resource + resource = MongoDB.from_yaml( + load_fixture("sharded-cluster-scram-sha-256.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace + ) + + if try_load(resource): + return resource + + return resource.update() @pytest.mark.e2e_sharded_cluster_scram_sha_256_switch_project @@ -54,31 +42,18 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" - def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): - """ - Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. - """ - sharded_cluster.set_version(custom_mdb_version) - sharded_cluster.update() + def test_create_sharded_cluster(self, sharded_cluster: MongoDB): sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) def test_sharded_cluster_connectivity(self): - """ - Verify connectivity to the original sharded cluster. - """ ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original cluster. - """ tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() # def test_create_secret(self): - # print(f"creating password for MongoDBUser {self.USER_NAME} in secret/{self.PASSWORD_SECRET_NAME} ") - # create_or_update_secret( # KubernetesTester.get_namespace(), # self.PASSWORD_SECRET_NAME, @@ -110,41 +85,28 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl # tester.assert_user_has_roles(self.USER_NAME, expected_roles) # tester.assert_expected_users(1) - def test_switch_sharded_cluster_project( - self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. - """ + def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - sharded_cluster.load() sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.set_version(custom_mdb_version) sharded_cluster.update() sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) def test_moved_sharded_cluster_connectivity(self): - """ - Verify connectivity to the sharded cluster after project switch. - """ ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. - """ tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") tester.assert_authentication_enabled() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py index 7138be3a6..65db1fdef 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py @@ -1,8 +1,8 @@ import pytest from kubetester import ( create_or_update_configmap, - random_k8s_name, read_configmap, + try_load, ) from kubetester.certs import ( ISSUER_CA_NAME, @@ -15,24 +15,7 @@ from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase -CONFIG_MAP_KEYS = { - "BASE_URL": "baseUrl", - "PROJECT_NAME": "projectName", - "ORG_ID": "orgId", -} - MDB_RESOURCE_NAME = "sharded-cluster-x509-switch-project" -MDB_FIXTURE_NAME = MDB_RESOURCE_NAME - - -@pytest.fixture(scope="module") -def project_name_prefix(namespace: str) -> str: - """ - Generates a random Kubernetes project name prefix based on the namespace. - - Ensures test isolation in a multi-namespace test environment. - """ - return random_k8s_name(f"{namespace}-project-") @pytest.fixture(scope="module") @@ -42,9 +25,17 @@ def sharded_cluster(namespace: str, server_certs: str, agent_certs: str, issuer_ Dynamically updates the resource Ops Manager reference based on the test context. """ - resource = MongoDB.from_yaml(load_fixture(f"switch-project/{MDB_FIXTURE_NAME}.yaml"), namespace=namespace) + resource = MongoDB.from_yaml( + load_fixture("sharded-cluster-x509-internal-cluster-auth-transition.yaml"), + name=MDB_RESOURCE_NAME, + namespace=namespace, + ) + + if try_load(resource): + return resource + resource["spec"]["security"]["tls"]["ca"] = issuer_ca_configmap - return resource + return resource.update() @pytest.fixture(scope="module") @@ -52,8 +43,8 @@ def server_certs(issuer: str, namespace: str): create_sharded_cluster_certs( namespace, MDB_RESOURCE_NAME, - shards=1, - mongod_per_shard=1, + shards=2, + mongod_per_shard=3, config_servers=1, mongos=1, ) @@ -70,53 +61,36 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): E2E test suite for sharded cluster creation, user connectivity with X509 authentication and switching Ops Manager project reference. """ - def test_create_sharded_cluster(self, custom_mdb_version: str, sharded_cluster: MongoDB): - """ - Test cluster creation ensuring resources are applied correctly and cluster reaches Running phase. - """ - sharded_cluster.set_version(custom_mdb_version) + def test_create_sharded_cluster(self, sharded_cluster: MongoDB): sharded_cluster.update() sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original cluster. - """ tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("MONGODB-X509") tester.assert_authoritative_set(True) tester.assert_authentication_enabled() tester.assert_expected_users(0) - def test_switch_sharded_cluster_project( - self, custom_mdb_version: str, sharded_cluster: MongoDB, namespace: str, project_name_prefix: str - ): - """ - Modify the sharded cluster to switch its Ops Manager reference to a new project and verify lifecycle. - """ + def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = f"{project_name_prefix}-second" + new_project_name = namespace + "-" + "second" new_project_configmap = create_or_update_configmap( namespace=namespace, name=new_project_name, data={ - CONFIG_MAP_KEYS["BASE_URL"]: original_configmap[CONFIG_MAP_KEYS["BASE_URL"]], - CONFIG_MAP_KEYS["PROJECT_NAME"]: new_project_name, - CONFIG_MAP_KEYS["ORG_ID"]: original_configmap[CONFIG_MAP_KEYS["ORG_ID"]], + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], }, ) - sharded_cluster.load() sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.set_version(custom_mdb_version) sharded_cluster.update() sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved cluster after the project switch. - """ tester = sharded_cluster.get_automation_config_tester() tester.assert_authentication_mechanism_enabled("MONGODB-X509") tester.assert_authoritative_set(True) From 4f00574165cab24c6d02c78b4d2e85415dcf40e2 Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Mon, 10 Nov 2025 15:52:51 +0100 Subject: [PATCH 7/9] add replicaset helper class --- .../replica_set_ldap_switch_project.py | 56 +++++----- .../replica_set_scram_sha_1_switch_project.py | 102 +++++++++--------- ...eplica_set_scram_sha_256_switch_project.py | 94 ++++++++-------- .../replica_set_switch_project_helper.py | 58 ++++++++++ .../replica_set_x509_switch_project.py | 74 +++++-------- 5 files changed, 209 insertions(+), 175 deletions(-) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py index d7c77cac5..9c2b0222e 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py @@ -3,19 +3,22 @@ import pytest from kubetester import ( - create_or_update_configmap, create_secret, find_fixture, read_configmap, try_load, ) -from kubetester.certs import create_mongodb_tls_certs, create_x509_user_cert +from kubetester.certs import create_mongodb_tls_certs from kubetester.kubetester import KubernetesTester from kubetester.ldap import LDAP_AUTHENTICATION_MECHANISM, LDAPUser, OpenLDAP from kubetester.mongodb import MongoDB from kubetester.mongodb_user import MongoDBUser, Role, generic_user from kubetester.phase import Phase +from .replica_set_switch_project_helper import ( + ReplicaSetCreationAndProjectSwitchTestHelper, +) + MDB_RESOURCE_NAME = "replica-set-ldap-switch-project" @@ -98,18 +101,29 @@ def user_ldap(replica_set: MongoDB, namespace: str, ldap_mongodb_users: List[LDA return user.create() +@pytest.fixture(scope="module") +def test_helper(replica_set: MongoDB, namespace: str) -> ReplicaSetCreationAndProjectSwitchTestHelper: + return ReplicaSetCreationAndProjectSwitchTestHelper( + replica_set=replica_set, + namespace=namespace, + authentication_mechanism=LDAP_AUTHENTICATION_MECHANISM, + expected_num_deployment_auth_mechanisms=3, + ) + + @pytest.mark.e2e_replica_set_ldap_switch_project class TestReplicaSetLDAPProjectSwitch(KubernetesTester): - def test_create_replica_set(self, replica_set: MongoDB, ldap_mongodb_users: List[LDAPUser]): - replica_set.assert_reaches_phase(Phase.Running, timeout=600) + def test_create_replica_set(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_create_replica_set() - def test_create_ldap_user(self, replica_set: MongoDB, user_ldap: MongoDBUser): + def test_create_ldap_user(self, user_ldap: MongoDBUser): user_ldap.assert_reaches_phase(Phase.Updated) - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=True) - tester.assert_expected_users(1) + def test_ops_manager_state_correctly_updated_in_initial_replica_set( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=1) def test_new_mdb_users_are_created_and_can_authenticate( self, replica_set: MongoDB, user_ldap: MongoDBUser, ca_path: str @@ -123,29 +137,19 @@ def test_new_mdb_users_are_created_and_can_authenticate( attempts=10, ) - def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str, user_ldap: MongoDBUser): + def test_switch_replica_set_project( + self, namespace: str, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, + test_helper.test_switch_replica_set_project( + original_configmap, new_project_configmap_name=namespace + "-" + "second" ) - replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.update() - - replica_set.assert_reaches_phase(Phase.Running, timeout=600) - def test_ops_manager_state_correctly_updated_in_moved_cluster( - self, replica_set: MongoDB, user_ldap: MongoDBUser, ca_path: str + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper ): - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=True) + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) + # tester.assert_expected_users(1) # tester = replica_set.tester() diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py index 59d011fd6..93025ebe3 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py @@ -1,6 +1,5 @@ import pytest from kubetester import ( - create_or_update_configmap, create_or_update_secret, read_configmap, try_load, @@ -9,9 +8,12 @@ from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB from kubetester.mongodb_user import MongoDBUser -from kubetester.mongotester import ReplicaSetTester from kubetester.phase import Phase +from .replica_set_switch_project_helper import ( + ReplicaSetCreationAndProjectSwitchTestHelper, +) + # Constants MDB_RESOURCE_NAME = "replica-set-scram-sha-1-switch-project" @@ -33,35 +35,39 @@ def replica_set(namespace: str) -> MongoDB: return resource.update() +@pytest.fixture(scope="module") +def test_helper(replica_set: MongoDB, namespace: str) -> ReplicaSetCreationAndProjectSwitchTestHelper: + return ReplicaSetCreationAndProjectSwitchTestHelper( + replica_set=replica_set, + namespace=namespace, + authentication_mechanism="MONGODB-CR", + expected_num_deployment_auth_mechanisms=2, + ) + + @pytest.mark.e2e_replica_set_scram_sha_1_switch_project class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for replica set creation, user connectivity with SCRAM-SHA-1 authentication and switching Ops Manager project reference. """ - PASSWORD_SECRET_NAME = "mms-user-1-password" - USER_PASSWORD = "my-password" - USER_NAME = "mms-user-1" + def test_create_replica_set(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_create_replica_set() - def test_create_replica_set(self, replica_set: MongoDB): - replica_set.assert_reaches_phase(Phase.Running, timeout=600) + def test_replica_set_connectivity(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_replica_set_connectivity(3) - def test_replica_set_connectivity(self): - ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-CR") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled(2) - tester.assert_expected_users(0) + def test_ops_manager_state_correctly_updated_in_initial_replica_set( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) def test_create_secret(self): create_or_update_secret( KubernetesTester.get_namespace(), - self.PASSWORD_SECRET_NAME, + "mms-user-1-password", { - "password": self.USER_PASSWORD, + "password": "my-password", }, ) @@ -71,59 +77,49 @@ def test_create_user(self, namespace: str): namespace=namespace, ) mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME - mdb.update() mdb.assert_reaches_phase(Phase.Updated, timeout=150) - def test_ops_manager_state_with_users_correctly_updated(self, replica_set: MongoDB): + def test_ops_manager_state_with_users_correctly_updated( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" expected_roles = { ("admin", "clusterAdmin"), ("admin", "userAdminAnyDatabase"), ("admin", "readWrite"), ("admin", "userAdminAnyDatabase"), } + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) - tester = replica_set.get_automation_config_tester() - tester.assert_has_user(self.USER_NAME) - tester.assert_user_has_roles(self.USER_NAME, expected_roles) - tester.assert_expected_users(1) - - def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str): + def test_switch_replica_set_project( + self, namespace: str, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, + test_helper.test_switch_replica_set_project( + original_configmap, new_project_configmap_name=namespace + "-" + "second" ) - replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.update() + def test_replica_set_connectivity_after_switch(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_replica_set_connectivity(3) - replica_set.assert_reaches_phase(Phase.Running, timeout=600) + def test_ops_manager_state_correctly_updated_after_switch( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=1) - def test_moved_replica_set_connectivity(self): - ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-CR") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled(2) - - def test_ops_manager_state_with_users_correctly_updated_after_switch(self, replica_set: MongoDB): + def test_ops_manager_state_with_users_correctly_updated_after_switch( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" expected_roles = { ("admin", "clusterAdmin"), ("admin", "userAdminAnyDatabase"), ("admin", "readWrite"), ("admin", "userAdminAnyDatabase"), } - - tester = replica_set.get_automation_config_tester() - tester.assert_has_user(self.USER_NAME) - tester.assert_user_has_roles(self.USER_NAME, expected_roles) - tester.assert_expected_users(1) + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py index 4831f5379..05735c97c 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -1,6 +1,5 @@ import pytest from kubetester import ( - create_or_update_configmap, create_or_update_secret, read_configmap, try_load, @@ -9,9 +8,12 @@ from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB from kubetester.mongodb_user import MongoDBUser -from kubetester.mongotester import ReplicaSetTester from kubetester.phase import Phase +from .replica_set_switch_project_helper import ( + ReplicaSetCreationAndProjectSwitchTestHelper, +) + # Constants MDB_RESOURCE_NAME = "replica-set-scram-sha-256-switch-project" @@ -33,33 +35,34 @@ def replica_set(namespace: str) -> MongoDB: return resource.update() +@pytest.fixture(scope="module") +def test_helper(replica_set: MongoDB, namespace: str) -> ReplicaSetCreationAndProjectSwitchTestHelper: + return ReplicaSetCreationAndProjectSwitchTestHelper( + replica_set=replica_set, namespace=namespace, authentication_mechanism="SCRAM-SHA-256" + ) + + @pytest.mark.e2e_replica_set_scram_sha_256_switch_project class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for replica set creation, user connectivity with SCRAM-SHA-256 authentication and switching Ops Manager project reference. """ - PASSWORD_SECRET_NAME = "mms-user-1-password" - USER_PASSWORD = "my-password" - USER_NAME = "mms-user-1" + def test_create_replica_set(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_create_replica_set() - def test_create_replica_set(self, replica_set: MongoDB): - replica_set.assert_reaches_phase(Phase.Running, timeout=600) + def test_replica_set_connectivity(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_replica_set_connectivity(3) - def test_replica_set_connectivity(self): - ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() + def test_ops_manager_state_correctly_updated(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) def test_create_secret(self): create_or_update_secret( KubernetesTester.get_namespace(), - self.PASSWORD_SECRET_NAME, + "mms-user-1-password", { - "password": self.USER_PASSWORD, + "password": "my-password", }, ) @@ -69,58 +72,49 @@ def test_create_user(self, namespace: str): namespace=namespace, ) mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME - mdb.update() mdb.assert_reaches_phase(Phase.Updated, timeout=150) - def test_ops_manager_state_with_users_correctly_updated(self, replica_set: MongoDB): + def test_ops_manager_state_with_users_correctly_updated( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" expected_roles = { ("admin", "clusterAdmin"), ("admin", "userAdminAnyDatabase"), ("admin", "readWrite"), ("admin", "userAdminAnyDatabase"), } + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) - tester = replica_set.get_automation_config_tester() - tester.assert_has_user(self.USER_NAME) - tester.assert_user_has_roles(self.USER_NAME, expected_roles) - tester.assert_expected_users(1) - - def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str): + def test_switch_replica_set_project( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper, namespace: str + ): original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, + test_helper.test_switch_replica_set_project( + original_configmap, new_project_configmap_name=namespace + "-" + "second" ) - replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.update() + def test_replica_set_connectivity_after_switch(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_replica_set_connectivity(3) - replica_set.assert_reaches_phase(Phase.Running, timeout=600) + def test_ops_manager_state_correctly_updated_after_switch( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=1) - def test_moved_replica_set_connectivity(self): - ReplicaSetTester(MDB_RESOURCE_NAME, 3).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() - - def test_ops_manager_state_with_users_correctly_updated_after_switch(self, replica_set: MongoDB): + def test_ops_manager_state_with_users_correctly_updated_after_switch( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" expected_roles = { ("admin", "clusterAdmin"), ("admin", "userAdminAnyDatabase"), ("admin", "readWrite"), ("admin", "userAdminAnyDatabase"), } - - tester = replica_set.get_automation_config_tester() - tester.assert_has_user(self.USER_NAME) - tester.assert_user_has_roles(self.USER_NAME, expected_roles) - tester.assert_expected_users(1) + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py new file mode 100644 index 000000000..cb3221dad --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py @@ -0,0 +1,58 @@ +from kubetester import ( + create_or_update_configmap, +) +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ReplicaSetTester +from kubetester.phase import Phase + + +class ReplicaSetCreationAndProjectSwitchTestHelper: + def __init__( + self, + replica_set: MongoDB, + namespace: str, + authentication_mechanism: str, + expected_num_deployment_auth_mechanisms=1, + active_auth_mechanism=True, + ): + self.replica_set = replica_set + self.namespace = namespace + self.authentication_mechanism = authentication_mechanism + self.expected_num_deployment_auth_mechanisms = expected_num_deployment_auth_mechanisms + self.active_auth_mechanism = active_auth_mechanism + + def test_create_replica_set(self): + self.replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_replica_set_connectivity(self, replica_set_size): + ReplicaSetTester(self.replica_set.name, replica_set_size).assert_connectivity() + + def test_ops_manager_state_with_expected_authentication(self, expected_users: int): + tester = self.replica_set.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled(self.authentication_mechanism, self.active_auth_mechanism) + tester.assert_authentication_enabled(self.expected_num_deployment_auth_mechanisms) + tester.assert_expected_users(expected_users) + + if self.authentication_mechanism == "MONGODB-X509": + tester.assert_authoritative_set(True) + + def test_switch_replica_set_project(self, original_configmap: dict, new_project_configmap_name: str): + new_project_name = self.namespace + "-second" + new_project_configmap = create_or_update_configmap( + namespace=self.namespace, + name=new_project_configmap_name, + data={ + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], + }, + ) + self.replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + self.replica_set.update() + self.replica_set.assert_reaches_phase(Phase.Running, timeout=600) + + def test_ops_manager_state_with_users(self, user_name: str, expected_roles: set, expected_users: int): + tester = self.replica_set.get_automation_config_tester() + tester.assert_has_user(user_name) + tester.assert_user_has_roles(user_name, expected_roles) + tester.assert_expected_users(expected_users) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py index 1ad8885ec..0033574c1 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py @@ -1,6 +1,5 @@ import pytest from kubetester import ( - create_or_update_configmap, read_configmap, try_load, ) @@ -12,8 +11,10 @@ from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB -from kubetester.mongotester import ReplicaSetTester -from kubetester.phase import Phase + +from .replica_set_switch_project_helper import ( + ReplicaSetCreationAndProjectSwitchTestHelper, +) # Constants MDB_RESOURCE_NAME = "replica-set-x509-switch-project" @@ -47,55 +48,36 @@ def agent_certs(issuer: str, namespace: str) -> str: return create_agent_tls_certs(issuer, namespace, MDB_RESOURCE_NAME) +@pytest.fixture(scope="module") +def test_helper(replica_set: MongoDB, namespace: str) -> ReplicaSetCreationAndProjectSwitchTestHelper: + return ReplicaSetCreationAndProjectSwitchTestHelper( + replica_set=replica_set, namespace=namespace, authentication_mechanism="MONGODB-X509" + ) + + @pytest.mark.e2e_replica_set_x509_switch_project class TestReplicaSetCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for replica set creation, user connectivity with X509 authentication and switching Ops Manager project reference. """ - def test_create_replica_set(self, replica_set: MongoDB): - """ - Test replica set creation ensuring resources are applied correctly and set reaches Running phase. - """ - replica_set.assert_reaches_phase(Phase.Running, timeout=600) - - def test_ops_manager_state_correctly_updated_in_initial_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the original replica set. - """ - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-X509") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled() - tester.assert_expected_users(0) - - def test_switch_replica_set_project(self, replica_set: MongoDB, namespace: str): - """ - Modify the replica set to switch its Ops Manager reference to a new project and verify lifecycle. - """ - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, - ) + def test_create_replica_set(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_create_replica_set() - replica_set["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - replica_set.update() + def test_ops_manager_state_correctly_updated_in_initial_replica_set( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) - replica_set.assert_reaches_phase(Phase.Running, timeout=600) + def test_switch_replica_set_project( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper, namespace: str + ): + original_configmap = read_configmap(namespace=namespace, name="my-project") + test_helper.test_switch_replica_set_project( + original_configmap, new_project_configmap_name=namespace + "-" + "second" + ) - def test_ops_manager_state_correctly_updated_in_moved_replica_set(self, replica_set: MongoDB): - """ - Ensure Ops Manager state is correctly updated in the moved replica set after the project switch. - """ - tester = replica_set.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-X509") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled() - tester.assert_expected_users(0) + def test_ops_manager_state_correctly_updated_in_moved_replica_set( + self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) From 7032528b09e7d6f014c08cceb54ad1f6b553de91 Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Tue, 11 Nov 2025 10:51:47 +0100 Subject: [PATCH 8/9] refactoring helper classes --- ...y => helper_replica_set_switch_project.py} | 10 +- .../helper_sharded_cluster_switch_project.py | 62 ++++++++++ .../replica_set_ldap_switch_project.py | 26 +---- .../replica_set_scram_sha_1_switch_project.py | 17 +-- ...eplica_set_scram_sha_256_switch_project.py | 17 +-- .../replica_set_x509_switch_project.py | 19 +--- .../sharded_cluster_ldap_switch_project.py | 62 +++++----- ...rded_cluster_scram_sha_1_switch_project.py | 107 ++++++++---------- ...ed_cluster_scram_sha_256_switch_project.py | 103 ++++++++--------- .../sharded_cluster_x509_switch_project.py | 72 +++++------- 10 files changed, 240 insertions(+), 255 deletions(-) rename docker/mongodb-kubernetes-tests/tests/authentication/{replica_set_switch_project_helper.py => helper_replica_set_switch_project.py} (90%) create mode 100644 docker/mongodb-kubernetes-tests/tests/authentication/helper_sharded_cluster_switch_project.py diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py b/docker/mongodb-kubernetes-tests/tests/authentication/helper_replica_set_switch_project.py similarity index 90% rename from docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py rename to docker/mongodb-kubernetes-tests/tests/authentication/helper_replica_set_switch_project.py index cb3221dad..7c0241924 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_switch_project_helper.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/helper_replica_set_switch_project.py @@ -1,5 +1,6 @@ from kubetester import ( create_or_update_configmap, + read_configmap, ) from kubetester.mongodb import MongoDB from kubetester.mongotester import ReplicaSetTester @@ -32,15 +33,16 @@ def test_ops_manager_state_with_expected_authentication(self, expected_users: in tester.assert_authentication_mechanism_enabled(self.authentication_mechanism, self.active_auth_mechanism) tester.assert_authentication_enabled(self.expected_num_deployment_auth_mechanisms) tester.assert_expected_users(expected_users) - + if self.authentication_mechanism == "MONGODB-X509": tester.assert_authoritative_set(True) - def test_switch_replica_set_project(self, original_configmap: dict, new_project_configmap_name: str): - new_project_name = self.namespace + "-second" + def test_switch_replica_set_project(self): + original_configmap = read_configmap(namespace=self.namespace, name="my-project") + new_project_name = f"{self.namespace}-second" new_project_configmap = create_or_update_configmap( namespace=self.namespace, - name=new_project_configmap_name, + name=new_project_name, data={ "baseUrl": original_configmap["baseUrl"], "projectName": new_project_name, diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/helper_sharded_cluster_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/helper_sharded_cluster_switch_project.py new file mode 100644 index 000000000..55469b40b --- /dev/null +++ b/docker/mongodb-kubernetes-tests/tests/authentication/helper_sharded_cluster_switch_project.py @@ -0,0 +1,62 @@ +from kubetester import ( + create_or_update_configmap, + read_configmap, +) +from kubetester.mongodb import MongoDB +from kubetester.mongotester import ShardedClusterTester +from kubetester.phase import Phase + + +class ShardedClusterCreationAndProjectSwitchTestHelper: + def __init__( + self, + sharded_cluster: MongoDB, + namespace: str, + authentication_mechanism: str, + expected_num_deployment_auth_mechanisms=2, + active_auth_mechanism=True, + ): + self.sharded_cluster = sharded_cluster + self.namespace = namespace + self.authentication_mechanism = authentication_mechanism + self.expected_num_deployment_auth_mechanisms = expected_num_deployment_auth_mechanisms + self.active_auth_mechanism = active_auth_mechanism + + def test_create_sharded_cluster(self): + self.sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) + + def test_sharded_cluster_connectivity(self, shard_count): + ShardedClusterTester(self.sharded_cluster.name, shard_count).assert_connectivity() + + def test_ops_manager_state_with_expected_authentication(self, expected_users: int): + tester = self.sharded_cluster.get_automation_config_tester() + tester.assert_authentication_mechanism_enabled(self.authentication_mechanism, self.active_auth_mechanism) + tester.assert_authentication_enabled(self.expected_num_deployment_auth_mechanisms) + tester.assert_expected_users(expected_users) + + if self.authentication_mechanism == "MONGODB-X509": + tester.assert_authoritative_set(True) + + def test_switch_sharded_cluster_project(self): + original_configmap = read_configmap(namespace=self.namespace, name="my-project") + new_project_name = f"{self.namespace}-second" + + new_project_configmap = create_or_update_configmap( + namespace=self.namespace, + name=new_project_name, + data={ + "baseUrl": original_configmap["baseUrl"], + "projectName": new_project_name, + "orgId": original_configmap["orgId"], + }, + ) + + self.sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap + self.sharded_cluster.update() + self.sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) + + def test_ops_manager_state_with_users(self, user_name: str, expected_roles: set, expected_users: int): + tester = self.sharded_cluster.get_automation_config_tester() + tester.assert_has_user(user_name) + tester.assert_user_has_roles(user_name, expected_roles) + tester.assert_expected_users(expected_users) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py index 9c2b0222e..dec7606fd 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_ldap_switch_project.py @@ -1,11 +1,9 @@ -import tempfile from typing import List import pytest from kubetester import ( create_secret, find_fixture, - read_configmap, try_load, ) from kubetester.certs import create_mongodb_tls_certs @@ -15,7 +13,7 @@ from kubetester.mongodb_user import MongoDBUser, Role, generic_user from kubetester.phase import Phase -from .replica_set_switch_project_helper import ( +from .helper_replica_set_switch_project import ( ReplicaSetCreationAndProjectSwitchTestHelper, ) @@ -137,25 +135,11 @@ def test_new_mdb_users_are_created_and_can_authenticate( attempts=10, ) - def test_switch_replica_set_project( - self, namespace: str, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper - ): - original_configmap = read_configmap(namespace=namespace, name="my-project") - test_helper.test_switch_replica_set_project( - original_configmap, new_project_configmap_name=namespace + "-" + "second" - ) + def test_switch_replica_set_project(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_switch_replica_set_project() - def test_ops_manager_state_correctly_updated_in_moved_cluster( + def test_ops_manager_state_with_users_correctly_updated_after_switch( self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper ): test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) - - # tester.assert_expected_users(1) - - # tester = replica_set.tester() - # tester.assert_ldap_authentication( - # username=user_ldap["spec"]["username"], - # password=user_ldap.password, - # tls_ca_file=ca_path, - # attempts=10, - # ) + # There should be one user (the previously created user should still exist in the automation configuration). We need to investigate further to understand why the user is not being picked up. diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py index 93025ebe3..8e36716c0 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_1_switch_project.py @@ -1,7 +1,6 @@ import pytest from kubetester import ( create_or_update_secret, - read_configmap, try_load, ) from kubetester.kubetester import KubernetesTester @@ -10,21 +9,16 @@ from kubetester.mongodb_user import MongoDBUser from kubetester.phase import Phase -from .replica_set_switch_project_helper import ( +from .helper_replica_set_switch_project import ( ReplicaSetCreationAndProjectSwitchTestHelper, ) -# Constants MDB_RESOURCE_NAME = "replica-set-scram-sha-1-switch-project" @pytest.fixture(scope="module") def replica_set(namespace: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the replica set. - Dynamically updates the resource configuration based on the test context. - """ resource = MongoDB.from_yaml( load_fixture("replica-set-explicit-scram-sha-1.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace ) @@ -94,13 +88,8 @@ def test_ops_manager_state_with_users_correctly_updated( user_name=user_name, expected_roles=expected_roles, expected_users=1 ) - def test_switch_replica_set_project( - self, namespace: str, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper - ): - original_configmap = read_configmap(namespace=namespace, name="my-project") - test_helper.test_switch_replica_set_project( - original_configmap, new_project_configmap_name=namespace + "-" + "second" - ) + def test_switch_replica_set_project(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_switch_replica_set_project() def test_replica_set_connectivity_after_switch(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): test_helper.test_replica_set_connectivity(3) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py index 05735c97c..8abbc39de 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_scram_sha_256_switch_project.py @@ -1,7 +1,6 @@ import pytest from kubetester import ( create_or_update_secret, - read_configmap, try_load, ) from kubetester.kubetester import KubernetesTester @@ -10,21 +9,16 @@ from kubetester.mongodb_user import MongoDBUser from kubetester.phase import Phase -from .replica_set_switch_project_helper import ( +from .helper_replica_set_switch_project import ( ReplicaSetCreationAndProjectSwitchTestHelper, ) -# Constants MDB_RESOURCE_NAME = "replica-set-scram-sha-256-switch-project" @pytest.fixture(scope="module") def replica_set(namespace: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the replica set. - Dynamically updates the resource configuration based on the test context. - """ resource = MongoDB.from_yaml( load_fixture("replica-set-scram-sha-256.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace ) @@ -89,13 +83,8 @@ def test_ops_manager_state_with_users_correctly_updated( user_name=user_name, expected_roles=expected_roles, expected_users=1 ) - def test_switch_replica_set_project( - self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper, namespace: str - ): - original_configmap = read_configmap(namespace=namespace, name="my-project") - test_helper.test_switch_replica_set_project( - original_configmap, new_project_configmap_name=namespace + "-" + "second" - ) + def test_switch_replica_set_project(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_switch_replica_set_project() def test_replica_set_connectivity_after_switch(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): test_helper.test_replica_set_connectivity(3) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py index 0033574c1..f5c5d5273 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/replica_set_x509_switch_project.py @@ -1,6 +1,5 @@ import pytest from kubetester import ( - read_configmap, try_load, ) from kubetester.certs import ( @@ -12,21 +11,16 @@ from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB -from .replica_set_switch_project_helper import ( +from .helper_replica_set_switch_project import ( ReplicaSetCreationAndProjectSwitchTestHelper, ) -# Constants MDB_RESOURCE_NAME = "replica-set-x509-switch-project" @pytest.fixture(scope="module") def replica_set(namespace: str, server_certs: str, agent_certs: str, issuer_ca_configmap: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the replica set. - Dynamically updates the resource configuration based on the test context. - """ resource = MongoDB.from_yaml( load_fixture("replica-set-x509-to-scram-256.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace ) @@ -69,15 +63,10 @@ def test_ops_manager_state_correctly_updated_in_initial_replica_set( ): test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) - def test_switch_replica_set_project( - self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper, namespace: str - ): - original_configmap = read_configmap(namespace=namespace, name="my-project") - test_helper.test_switch_replica_set_project( - original_configmap, new_project_configmap_name=namespace + "-" + "second" - ) + def test_switch_replica_set_project(self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper): + test_helper.test_switch_replica_set_project() - def test_ops_manager_state_correctly_updated_in_moved_replica_set( + def test_ops_manager_state_with_users_correctly_updated_after_switch( self, test_helper: ReplicaSetCreationAndProjectSwitchTestHelper ): test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py index bf24d88fc..c3d8d48c4 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_ldap_switch_project.py @@ -1,23 +1,21 @@ -import time from typing import Dict, List import pytest from kubetester import ( - create_or_update_configmap, - create_secret, find_fixture, - read_configmap, try_load, wait_until, ) from kubetester.kubetester import KubernetesTester -from kubetester.kubetester import fixture as yaml_fixture from kubetester.ldap import LDAP_AUTHENTICATION_MECHANISM, LDAPUser, OpenLDAP from kubetester.mongodb import MongoDB from kubetester.mongodb_user import MongoDBUser, Role, generic_user -from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase +from .helper_sharded_cluster_switch_project import ( + ShardedClusterCreationAndProjectSwitchTestHelper, +) + MDB_RESOURCE_NAME = "sharded-cluster-ldap-switch-project" @@ -72,11 +70,21 @@ def ldap_user_mongodb(sharded_cluster: MongoDB, namespace: str, ldap_mongodb_use return user.create() +@pytest.fixture(scope="module") +def test_helper(sharded_cluster: MongoDB, namespace: str) -> ShardedClusterCreationAndProjectSwitchTestHelper: + return ShardedClusterCreationAndProjectSwitchTestHelper( + sharded_cluster=sharded_cluster, + namespace=namespace, + authentication_mechanism=LDAP_AUTHENTICATION_MECHANISM, + expected_num_deployment_auth_mechanisms=2, + active_auth_mechanism=False, + ) + + @pytest.mark.e2e_sharded_cluster_ldap_switch_project class TestShardedClusterLDAPProjectSwitch(KubernetesTester): - def test_create_sharded_cluster(self, sharded_cluster: MongoDB): - sharded_cluster.update() + def test_create_sharded_cluster(self, sharded_cluster): sharded_cluster.assert_reaches_phase(Phase.Pending, timeout=600) def test_sharded_cluster_turn_tls_on_CLOUDP_229222(self, sharded_cluster: MongoDB): @@ -114,33 +122,19 @@ def wait_for_ac_pushed() -> bool: def test_sharded_cluster_CLOUDP_229222(self, sharded_cluster: MongoDB, ldap_mongodb_users: List[LDAPUser]): sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) + def test_new_mdb_users_are_created(self, ldap_user_mongodb: MongoDBUser): + ldap_user_mongodb.assert_reaches_phase(Phase.Updated) + def test_ops_manager_state_correctly_updated_in_initial_cluster( - self, sharded_cluster: MongoDB, ldap_user_mongodb: MongoDBUser + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=1) - ldap_user_mongodb.assert_reaches_phase(Phase.Updated) - ac_tester = sharded_cluster.get_automation_config_tester() - ac_tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=False) - ac_tester.assert_expected_users(1) - - def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, - ) - - sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.update() - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + def test_switch_sharded_cluster_project(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_switch_sharded_cluster_project() - def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - ac_tester = sharded_cluster.get_automation_config_tester() - ac_tester.assert_authentication_mechanism_enabled(LDAP_AUTHENTICATION_MECHANISM, active_auth_mechanism=False) - # ac_tester.assert_expected_users(1) + def test_ops_manager_state_correctly_updated_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) + # There should be one user (the previously created user should still exist in the automation configuration). We need to investigate further to understand why the user is not being picked up. diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py index 6ef224baa..907a93aa1 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py @@ -1,27 +1,24 @@ import pytest from kubetester import ( - create_or_update_configmap, create_or_update_secret, - read_configmap, try_load, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB from kubetester.mongodb_user import MongoDBUser -from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase +from .helper_sharded_cluster_switch_project import ( + ShardedClusterCreationAndProjectSwitchTestHelper, +) + MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-1-switch-project" @pytest.fixture(scope="module") def sharded_cluster(namespace: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the sharded cluster. - Dynamically updates the resource Ops Manager reference based on the test context. - """ resource = MongoDB.from_yaml( load_fixture("sharded-cluster-explicit-scram-sha-1.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace ) @@ -32,6 +29,16 @@ def sharded_cluster(namespace: str) -> MongoDB: return resource.update() +@pytest.fixture(scope="module") +def test_helper(sharded_cluster: MongoDB, namespace: str) -> ShardedClusterCreationAndProjectSwitchTestHelper: + return ShardedClusterCreationAndProjectSwitchTestHelper( + sharded_cluster=sharded_cluster, + namespace=namespace, + authentication_mechanism="MONGODB-CR", + expected_num_deployment_auth_mechanisms=2, + ) + + @pytest.mark.e2e_sharded_cluster_scram_sha_1_switch_project class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): """ @@ -42,21 +49,18 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" - def test_create_sharded_cluster(self, sharded_cluster: MongoDB): - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + def test_create_sharded_cluster(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_create_sharded_cluster() - def test_sharded_cluster_connectivity(self): - ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + def test_sharded_cluster_connectivity(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_sharded_cluster_connectivity(1) - def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-CR") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled(2) - tester.assert_expected_users(0) + def test_ops_manager_state_correctly_updated_in_initial_sharded_cluster( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(0) # def test_create_secret(self): - # create_or_update_secret( # KubernetesTester.get_namespace(), # self.PASSWORD_SECRET_NAME, @@ -75,55 +79,44 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl # mdb.update() # mdb.assert_reaches_phase(Phase.Updated, timeout=150) - # def test_ops_manager_state_with_users_correctly_updated(self, sharded_cluster: MongoDB): + # def test_ops_manager_state_with_users_correctly_updated( + # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + # ): + # user_name = "mms-user-1" # expected_roles = { # ("admin", "clusterAdmin"), # ("admin", "userAdminAnyDatabase"), # ("admin", "readWrite"), # ("admin", "userAdminAnyDatabase"), # } + # test_helper.test_ops_manager_state_with_users( + # user_name=user_name, expected_roles=expected_roles, expected_users=1 + # ) + + def test_switch_sharded_cluster_project(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_switch_sharded_cluster_project() + + def test_sharded_cluster_connectivity_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_sharded_cluster_connectivity(1) - # tester = sharded_cluster.get_automation_config_tester() - # tester.assert_has_user(self.USER_NAME) - # tester.assert_user_has_roles(self.USER_NAME, expected_roles) - # tester.assert_expected_users(1) - - def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, - ) - - sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.update() - - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) - - def test_moved_sharded_cluster_connectivity(self): - ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-CR") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled(2) - - # def test_ops_manager_state_with_users_correctly_updated_after_switch(self, sharded_cluster: MongoDB): + def test_ops_manager_state_correctly_updated_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) + + # def test_ops_manager_state_with_users_correctly_updated_after_switch( + # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + # ): + # user_name = "mms-user-1" # expected_roles = { # ("admin", "clusterAdmin"), # ("admin", "userAdminAnyDatabase"), # ("admin", "readWrite"), # ("admin", "userAdminAnyDatabase"), # } - - # tester = sharded_cluster.get_automation_config_tester() - # tester.assert_has_user(self.USER_NAME) - # tester.assert_user_has_roles(self.USER_NAME, expected_roles) - # tester.assert_expected_users(1) + # test_helper.test_ops_manager_state_with_users( + # user_name=user_name, expected_roles=expected_roles, expected_users=1 + # ) + # There should be one user (the previously created user should still exist in the automation configuration). We need to investigate further to understand why the user is not being picked up. diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py index 537651d17..ff116ab22 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py @@ -1,27 +1,24 @@ import pytest from kubetester import ( - create_or_update_configmap, create_or_update_secret, - read_configmap, try_load, ) from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB from kubetester.mongodb_user import MongoDBUser -from kubetester.mongotester import ShardedClusterTester from kubetester.phase import Phase +from .helper_sharded_cluster_switch_project import ( + ShardedClusterCreationAndProjectSwitchTestHelper, +) + MDB_RESOURCE_NAME = "sharded-cluster-scram-sha-256-switch-project" @pytest.fixture(scope="module") def sharded_cluster(namespace: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the sharded cluster. - Dynamically updates the resource Ops Manager reference based on the test context. - """ resource = MongoDB.from_yaml( load_fixture("sharded-cluster-scram-sha-256.yaml"), name=MDB_RESOURCE_NAME, namespace=namespace ) @@ -32,6 +29,16 @@ def sharded_cluster(namespace: str) -> MongoDB: return resource.update() +@pytest.fixture(scope="module") +def test_helper(sharded_cluster: MongoDB, namespace: str) -> ShardedClusterCreationAndProjectSwitchTestHelper: + return ShardedClusterCreationAndProjectSwitchTestHelper( + sharded_cluster=sharded_cluster, + namespace=namespace, + authentication_mechanism="SCRAM-SHA-256", + expected_num_deployment_auth_mechanisms=1, + ) + + @pytest.mark.e2e_sharded_cluster_scram_sha_256_switch_project class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): """ @@ -42,16 +49,16 @@ class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): USER_PASSWORD = "my-password" USER_NAME = "mms-user-1" - def test_create_sharded_cluster(self, sharded_cluster: MongoDB): - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) + def test_create_sharded_cluster(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_create_sharded_cluster() - def test_sharded_cluster_connectivity(self): - ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() + def test_sharded_cluster_connectivity(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_sharded_cluster_connectivity(1) - def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() + def test_ops_manager_state_correctly_updated_in_initial_sharded_cluster( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(0) # def test_create_secret(self): # create_or_update_secret( @@ -72,54 +79,44 @@ def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cl # mdb.update() # mdb.assert_reaches_phase(Phase.Updated, timeout=150) - # def test_ops_manager_state_with_users_correctly_updated(self, sharded_cluster: MongoDB): + # def test_ops_manager_state_with_users_correctly_updated( + # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + # ): + # user_name = "mms-user-1" # expected_roles = { # ("admin", "clusterAdmin"), # ("admin", "userAdminAnyDatabase"), # ("admin", "readWrite"), # ("admin", "userAdminAnyDatabase"), # } + # test_helper.test_ops_manager_state_with_users( + # user_name=user_name, expected_roles=expected_roles, expected_users=1 + # ) + + def test_switch_sharded_cluster_project(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_switch_sharded_cluster_project() + + def test_sharded_cluster_connectivity_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_sharded_cluster_connectivity(1) - # tester = sharded_cluster.get_automation_config_tester() - # tester.assert_has_user(self.USER_NAME) - # tester.assert_user_has_roles(self.USER_NAME, expected_roles) - # tester.assert_expected_users(1) - - def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, - ) - - sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.update() - - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=800) - - def test_moved_sharded_cluster_connectivity(self): - ShardedClusterTester(MDB_RESOURCE_NAME, 1).assert_connectivity() - - def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("SCRAM-SHA-256") - tester.assert_authentication_enabled() - - # def test_ops_manager_state_with_users_correctly_updated_after_switch(self, sharded_cluster: MongoDB): + def test_ops_manager_state_correctly_updated_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(0) + + # def test_ops_manager_state_with_users_correctly_updated_after_switch( + # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + # ): + # user_name = "mms-user-1" # expected_roles = { # ("admin", "clusterAdmin"), # ("admin", "userAdminAnyDatabase"), # ("admin", "readWrite"), # ("admin", "userAdminAnyDatabase"), # } - - # tester = sharded_cluster.get_automation_config_tester() - # tester.assert_has_user(self.USER_NAME) - # tester.assert_user_has_roles(self.USER_NAME, expected_roles) - # tester.assert_expected_users(1) + # test_helper.test_ops_manager_state_with_users( + # user_name=user_name, expected_roles=expected_roles, expected_users=1 + # ) + # There should be one user (the previously created user should still exist in the automation configuration). We need to investigate further to understand why the user is not being picked up. diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py index 65db1fdef..030867b11 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_x509_switch_project.py @@ -1,7 +1,5 @@ import pytest from kubetester import ( - create_or_update_configmap, - read_configmap, try_load, ) from kubetester.certs import ( @@ -12,19 +10,17 @@ from kubetester.kubetester import KubernetesTester from kubetester.kubetester import fixture as load_fixture from kubetester.mongodb import MongoDB -from kubetester.mongotester import ShardedClusterTester -from kubetester.phase import Phase + +from .helper_sharded_cluster_switch_project import ( + ShardedClusterCreationAndProjectSwitchTestHelper, +) MDB_RESOURCE_NAME = "sharded-cluster-x509-switch-project" @pytest.fixture(scope="module") def sharded_cluster(namespace: str, server_certs: str, agent_certs: str, issuer_ca_configmap: str) -> MongoDB: - """ - Fixture to initialize the MongoDB resource for the sharded cluster. - Dynamically updates the resource Ops Manager reference based on the test context. - """ resource = MongoDB.from_yaml( load_fixture("sharded-cluster-x509-internal-cluster-auth-transition.yaml"), name=MDB_RESOURCE_NAME, @@ -55,44 +51,34 @@ def agent_certs(issuer: str, namespace: str) -> str: return create_x509_agent_tls_certs(issuer, namespace, MDB_RESOURCE_NAME) +@pytest.fixture(scope="module") +def test_helper(sharded_cluster: MongoDB, namespace: str) -> ShardedClusterCreationAndProjectSwitchTestHelper: + return ShardedClusterCreationAndProjectSwitchTestHelper( + sharded_cluster=sharded_cluster, + namespace=namespace, + authentication_mechanism="MONGODB-X509", + expected_num_deployment_auth_mechanisms=1, + ) + + @pytest.mark.e2e_sharded_cluster_x509_switch_project class TestShardedClusterCreationAndProjectSwitch(KubernetesTester): """ E2E test suite for sharded cluster creation, user connectivity with X509 authentication and switching Ops Manager project reference. """ - def test_create_sharded_cluster(self, sharded_cluster: MongoDB): - sharded_cluster.update() - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) - - def test_ops_manager_state_correctly_updated_in_initial_cluster(self, sharded_cluster: MongoDB): - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-X509") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled() - tester.assert_expected_users(0) - - def test_switch_sharded_cluster_project(self, sharded_cluster: MongoDB, namespace: str): - original_configmap = read_configmap(namespace=namespace, name="my-project") - new_project_name = namespace + "-" + "second" - new_project_configmap = create_or_update_configmap( - namespace=namespace, - name=new_project_name, - data={ - "baseUrl": original_configmap["baseUrl"], - "projectName": new_project_name, - "orgId": original_configmap["orgId"], - }, - ) - - sharded_cluster["spec"]["opsManager"]["configMapRef"]["name"] = new_project_configmap - sharded_cluster.update() - - sharded_cluster.assert_reaches_phase(Phase.Running, timeout=600) - - def test_ops_manager_state_correctly_updated_in_moved_cluster(self, sharded_cluster: MongoDB): - tester = sharded_cluster.get_automation_config_tester() - tester.assert_authentication_mechanism_enabled("MONGODB-X509") - tester.assert_authoritative_set(True) - tester.assert_authentication_enabled() - tester.assert_expected_users(0) + def test_create_sharded_cluster(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_create_sharded_cluster() + + def test_ops_manager_state_correctly_updated_in_initial_sharded_cluster( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(0) + + def test_switch_sharded_cluster_project(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): + test_helper.test_switch_sharded_cluster_project() + + def test_ops_manager_state_correctly_updated_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + test_helper.test_ops_manager_state_with_expected_authentication(0) From 6d572dc7a3f3cd9744739bd0e140a891f52748cc Mon Sep 17 00:00:00 2001 From: filipcirtog Date: Tue, 11 Nov 2025 12:08:00 +0100 Subject: [PATCH 9/9] arg nit: ctx before client --- .../operator/appdbreplicaset_controller.go | 2 +- .../operator/authentication/authentication.go | 10 +- .../configure_authentication_test.go | 8 +- controllers/operator/common_controller.go | 2 +- ...rded_cluster_scram_sha_1_switch_project.py | 95 +++++++++---------- ...ed_cluster_scram_sha_256_switch_project.py | 93 +++++++++--------- 6 files changed, 104 insertions(+), 106 deletions(-) diff --git a/controllers/operator/appdbreplicaset_controller.go b/controllers/operator/appdbreplicaset_controller.go index c208ae314..f4ad1e78e 100644 --- a/controllers/operator/appdbreplicaset_controller.go +++ b/controllers/operator/appdbreplicaset_controller.go @@ -1667,7 +1667,7 @@ func (r *ReconcileAppDbReplicaSet) tryConfigureMonitoringInOpsManager(ctx contex AutoPEMKeyFilePath: agentCertPath, CAFilePath: util.CAFilePathInContainer, } - err = authentication.Configure(r.client, ctx, types.NamespacedName{Namespace: opsManager.Namespace, Name: opsManager.Name}, conn, opts, false, log) + err = authentication.Configure(ctx, r.client, types.NamespacedName{Namespace: opsManager.Namespace, Name: opsManager.Name}, conn, opts, false, log) if err != nil { log.Errorf("Could not set Automation Authentication options in Ops/Cloud Manager for the Application Database. "+ "Application Database is always configured with authentication enabled, but this will not be "+ diff --git a/controllers/operator/authentication/authentication.go b/controllers/operator/authentication/authentication.go index 7a0ef3bf2..f9f1d30c7 100644 --- a/controllers/operator/authentication/authentication.go +++ b/controllers/operator/authentication/authentication.go @@ -86,7 +86,7 @@ type UserOptions struct { // Configure will configure all the specified authentication Mechanisms. We need to ensure we wait for // the agents to reach ready state after each operation as prematurely updating the automation config can cause the agents to get stuck. -func Configure(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, isRecovering bool, log *zap.SugaredLogger) error { +func Configure(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, isRecovering bool, log *zap.SugaredLogger) error { log.Infow("ensuring correct deployment mechanisms", "ProcessNames", opts.ProcessNames, "Mechanisms", opts.Mechanisms) // In case we're recovering, we can push all changes at once, because the mechanism is triggered after 20min by default. @@ -117,7 +117,7 @@ func Configure(client kubernetesClient.Client, ctx context.Context, mdbNamespace // once we have made sure that the deployment authentication mechanism array contains the desired auth mechanism // we can then configure the agent authentication. - if err := enableAgentAuthentication(client, ctx, mdbNamespacedName, conn, opts, log); err != nil { + if err := enableAgentAuthentication(ctx, client, mdbNamespacedName, conn, opts, log); err != nil { return xerrors.Errorf("error enabling agent authentication: %w", err) } if err := waitForReadyStateIfNeeded(); err != nil { @@ -262,7 +262,7 @@ func removeUnsupportedAgentMechanisms(conn om.Connection, opts Options, log *zap // enableAgentAuthentication determines which agent authentication mechanism should be configured // and enables it in Ops Manager -func enableAgentAuthentication(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { +func enableAgentAuthentication(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, log *zap.SugaredLogger) error { ac, err := conn.ReadAutomationConfig() if err != nil { return xerrors.Errorf("error reading automation config: %w", err) @@ -271,7 +271,7 @@ func enableAgentAuthentication(client kubernetesClient.Client, ctx context.Conte // we then configure the agent authentication for that type mechanism := convertToMechanismOrPanic(opts.AgentMechanism, ac) - if err := ensureAgentAuthenticationIsConfigured(client, ctx, mdbNamespacedName, conn, opts, ac, mechanism, log); err != nil { + if err := ensureAgentAuthenticationIsConfigured(ctx, client, mdbNamespacedName, conn, opts, ac, mechanism, log); err != nil { return xerrors.Errorf("error ensuring agent authentication is configured: %w", err) } @@ -369,7 +369,7 @@ func addOrRemoveAgentClientCertificate(conn om.Connection, opts Options, log *za } // ensureAgentAuthenticationIsConfigured will configure the agent authentication settings based on the desiredAgentAuthMechanism -func ensureAgentAuthenticationIsConfigured(client kubernetesClient.Client, ctx context.Context, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error { +func ensureAgentAuthenticationIsConfigured(ctx context.Context, client kubernetesClient.Client, mdbNamespacedName types.NamespacedName, conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error { if mechanism.IsAgentAuthenticationConfigured(ac, opts) { log.Infof("Agent authentication mechanism %s is already configured", mechanism.GetName()) return nil diff --git a/controllers/operator/authentication/configure_authentication_test.go b/controllers/operator/authentication/configure_authentication_test.go index 1a13893d9..4bb918c60 100644 --- a/controllers/operator/authentication/configure_authentication_test.go +++ b/controllers/operator/authentication/configure_authentication_test.go @@ -34,7 +34,7 @@ func TestConfigureScramSha256(t *testing.T) { AgentMechanism: "SCRAM", } - if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { + if err := Configure(ctx, kubeClient, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -66,7 +66,7 @@ func TestConfigureX509(t *testing.T) { }, } - if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { + if err := Configure(ctx, kubeClient, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -94,7 +94,7 @@ func TestConfigureScramSha1(t *testing.T) { AgentMechanism: "SCRAM-SHA-1", } - if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { + if err := Configure(ctx, kubeClient, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } @@ -123,7 +123,7 @@ func TestConfigureMultipleAuthenticationMechanisms(t *testing.T) { }, } - if err := Configure(kubeClient, ctx, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { + if err := Configure(ctx, kubeClient, mdbNamespacedName, conn, opts, false, zap.S()); err != nil { t.Fatal(err) } diff --git a/controllers/operator/common_controller.go b/controllers/operator/common_controller.go index 0438197e6..55c3a9032 100644 --- a/controllers/operator/common_controller.go +++ b/controllers/operator/common_controller.go @@ -514,7 +514,7 @@ func (r *ReconcileCommonController) updateOmAuthentication(ctx context.Context, authOpts.UserOptions = userOpts } - if err := authentication.Configure(r.client, ctx, types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, isRecovering, log); err != nil { + if err := authentication.Configure(ctx, r.client, types.NamespacedName{Namespace: ar.GetNamespace(), Name: ar.GetName()}, conn, authOpts, isRecovering, log); err != nil { return workflow.Failed(err), false } } else if wantToEnableAuthentication { diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py index 907a93aa1..4e20f930b 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_1_switch_project.py @@ -60,38 +60,38 @@ def test_ops_manager_state_correctly_updated_in_initial_sharded_cluster( ): test_helper.test_ops_manager_state_with_expected_authentication(0) - # def test_create_secret(self): - # create_or_update_secret( - # KubernetesTester.get_namespace(), - # self.PASSWORD_SECRET_NAME, - # { - # "password": self.USER_PASSWORD, - # }, - # ) - - # def test_create_user(self, namespace: str): - # mdb = MongoDBUser.from_yaml( - # load_fixture("scram-sha-user.yaml"), - # namespace=namespace, - # ) - # mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME - - # mdb.update() - # mdb.assert_reaches_phase(Phase.Updated, timeout=150) - - # def test_ops_manager_state_with_users_correctly_updated( - # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper - # ): - # user_name = "mms-user-1" - # expected_roles = { - # ("admin", "clusterAdmin"), - # ("admin", "userAdminAnyDatabase"), - # ("admin", "readWrite"), - # ("admin", "userAdminAnyDatabase"), - # } - # test_helper.test_ops_manager_state_with_users( - # user_name=user_name, expected_roles=expected_roles, expected_users=1 - # ) + def test_create_secret(self): + create_or_update_secret( + KubernetesTester.get_namespace(), + self.PASSWORD_SECRET_NAME, + { + "password": self.USER_PASSWORD, + }, + ) + + def test_create_user(self, namespace: str): + mdb = MongoDBUser.from_yaml( + load_fixture("scram-sha-user.yaml"), + namespace=namespace, + ) + mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME + + mdb.update() + mdb.assert_reaches_phase(Phase.Updated, timeout=150) + + def test_ops_manager_state_with_users_correctly_updated( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) def test_switch_sharded_cluster_project(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): test_helper.test_switch_sharded_cluster_project() @@ -104,19 +104,18 @@ def test_sharded_cluster_connectivity_after_switch( def test_ops_manager_state_correctly_updated_after_switch( self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper ): - test_helper.test_ops_manager_state_with_expected_authentication(expected_users=0) - - # def test_ops_manager_state_with_users_correctly_updated_after_switch( - # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper - # ): - # user_name = "mms-user-1" - # expected_roles = { - # ("admin", "clusterAdmin"), - # ("admin", "userAdminAnyDatabase"), - # ("admin", "readWrite"), - # ("admin", "userAdminAnyDatabase"), - # } - # test_helper.test_ops_manager_state_with_users( - # user_name=user_name, expected_roles=expected_roles, expected_users=1 - # ) - # There should be one user (the previously created user should still exist in the automation configuration). We need to investigate further to understand why the user is not being picked up. + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=1) + + def test_ops_manager_state_with_users_correctly_updated_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) diff --git a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py index ff116ab22..6f6cbd3d0 100644 --- a/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py +++ b/docker/mongodb-kubernetes-tests/tests/authentication/sharded_cluster_scram_sha_256_switch_project.py @@ -60,38 +60,38 @@ def test_ops_manager_state_correctly_updated_in_initial_sharded_cluster( ): test_helper.test_ops_manager_state_with_expected_authentication(0) - # def test_create_secret(self): - # create_or_update_secret( - # KubernetesTester.get_namespace(), - # self.PASSWORD_SECRET_NAME, - # { - # "password": self.USER_PASSWORD, - # }, - # ) - - # def test_create_user(self, namespace: str): - # mdb = MongoDBUser.from_yaml( - # load_fixture("scram-sha-user.yaml"), - # namespace=namespace, - # ) - # mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME - - # mdb.update() - # mdb.assert_reaches_phase(Phase.Updated, timeout=150) - - # def test_ops_manager_state_with_users_correctly_updated( - # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper - # ): - # user_name = "mms-user-1" - # expected_roles = { - # ("admin", "clusterAdmin"), - # ("admin", "userAdminAnyDatabase"), - # ("admin", "readWrite"), - # ("admin", "userAdminAnyDatabase"), - # } - # test_helper.test_ops_manager_state_with_users( - # user_name=user_name, expected_roles=expected_roles, expected_users=1 - # ) + def test_create_secret(self): + create_or_update_secret( + KubernetesTester.get_namespace(), + self.PASSWORD_SECRET_NAME, + { + "password": self.USER_PASSWORD, + }, + ) + + def test_create_user(self, namespace: str): + mdb = MongoDBUser.from_yaml( + load_fixture("scram-sha-user.yaml"), + namespace=namespace, + ) + mdb["spec"]["mongodbResourceRef"]["name"] = MDB_RESOURCE_NAME + + mdb.update() + mdb.assert_reaches_phase(Phase.Updated, timeout=150) + + def test_ops_manager_state_with_users_correctly_updated( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + ) def test_switch_sharded_cluster_project(self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper): test_helper.test_switch_sharded_cluster_project() @@ -104,19 +104,18 @@ def test_sharded_cluster_connectivity_after_switch( def test_ops_manager_state_correctly_updated_after_switch( self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper ): - test_helper.test_ops_manager_state_with_expected_authentication(0) + test_helper.test_ops_manager_state_with_expected_authentication(expected_users=1) - # def test_ops_manager_state_with_users_correctly_updated_after_switch( - # self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper - # ): - # user_name = "mms-user-1" - # expected_roles = { - # ("admin", "clusterAdmin"), - # ("admin", "userAdminAnyDatabase"), - # ("admin", "readWrite"), - # ("admin", "userAdminAnyDatabase"), - # } - # test_helper.test_ops_manager_state_with_users( - # user_name=user_name, expected_roles=expected_roles, expected_users=1 - # ) - # There should be one user (the previously created user should still exist in the automation configuration). We need to investigate further to understand why the user is not being picked up. + def test_ops_manager_state_with_users_correctly_updated_after_switch( + self, test_helper: ShardedClusterCreationAndProjectSwitchTestHelper + ): + user_name = "mms-user-1" + expected_roles = { + ("admin", "clusterAdmin"), + ("admin", "userAdminAnyDatabase"), + ("admin", "readWrite"), + ("admin", "userAdminAnyDatabase"), + } + test_helper.test_ops_manager_state_with_users( + user_name=user_name, expected_roles=expected_roles, expected_users=1 + )