From 281ea28039b01c170cfd7cd3c3d9ea518f7081ea Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 09:26:14 +0100 Subject: [PATCH 01/17] Update crds. --- .../bases/psmdb.percona.com_perconaservermongodbs.yaml | 1 - deploy/bundle.yaml | 1 - deploy/crd.yaml | 1 - deploy/cw-bundle.yaml | 1 - e2e-tests/version-service/conf/crd.yaml | 1 - pkg/apis/psmdb/v1/psmdb_types.go | 8 ++++---- pkg/apis/psmdb/v1/zz_generated.deepcopy.go | 6 +++++- pkg/controller/perconaservermongodb/custom_users.go | 5 +++++ 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml b/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml index 165e86ff80..c4ee057f3f 100644 --- a/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml +++ b/config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml @@ -18731,7 +18731,6 @@ spec: type: array required: - name - - passwordSecretRef - roles type: object type: array diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 67934c7f15..24fccc355d 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -19413,7 +19413,6 @@ spec: type: array required: - name - - passwordSecretRef - roles type: object type: array diff --git a/deploy/crd.yaml b/deploy/crd.yaml index ba327a0c6d..eeec66cd43 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -19413,7 +19413,6 @@ spec: type: array required: - name - - passwordSecretRef - roles type: object type: array diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index b365d0d673..87fce5042f 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -19413,7 +19413,6 @@ spec: type: array required: - name - - passwordSecretRef - roles type: object type: array diff --git a/e2e-tests/version-service/conf/crd.yaml b/e2e-tests/version-service/conf/crd.yaml index ba327a0c6d..eeec66cd43 100644 --- a/e2e-tests/version-service/conf/crd.yaml +++ b/e2e-tests/version-service/conf/crd.yaml @@ -19413,7 +19413,6 @@ spec: type: array required: - name - - passwordSecretRef - roles type: object type: array diff --git a/pkg/apis/psmdb/v1/psmdb_types.go b/pkg/apis/psmdb/v1/psmdb_types.go index fbc2d6035d..6de12d5abc 100644 --- a/pkg/apis/psmdb/v1/psmdb_types.go +++ b/pkg/apis/psmdb/v1/psmdb_types.go @@ -108,10 +108,10 @@ type SecretKeySelector struct { } type User struct { - Name string `json:"name"` - DB string `json:"db,omitempty"` - PasswordSecretRef SecretKeySelector `json:"passwordSecretRef"` - Roles []UserRole `json:"roles"` + Name string `json:"name"` + DB string `json:"db,omitempty"` + PasswordSecretRef *SecretKeySelector `json:"passwordSecretRef,omitempty"` + Roles []UserRole `json:"roles"` } func (u *User) UserID() string { diff --git a/pkg/apis/psmdb/v1/zz_generated.deepcopy.go b/pkg/apis/psmdb/v1/zz_generated.deepcopy.go index 0070389753..04316f2b64 100644 --- a/pkg/apis/psmdb/v1/zz_generated.deepcopy.go +++ b/pkg/apis/psmdb/v1/zz_generated.deepcopy.go @@ -1931,7 +1931,11 @@ func (in *UpgradeOptions) DeepCopy() *UpgradeOptions { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *User) DeepCopyInto(out *User) { *out = *in - out.PasswordSecretRef = in.PasswordSecretRef + if in.PasswordSecretRef != nil { + in, out := &in.PasswordSecretRef, &out.PasswordSecretRef + *out = new(SecretKeySelector) + **out = **in + } if in.Roles != nil { in, out := &in.Roles, &out.Roles *out = make([]UserRole, len(*in)) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index bd51a1ca12..b42f7ff18e 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -81,6 +81,11 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context continue } + if user.PasswordSecretRef == nil && user.DB != "$external" { + log.Error(nil, "user must have passwordSecretRef or $external DB set", "user", user.Name) + continue + } + if user.DB == "" { user.DB = "admin" } From 6e85b24a09e459bb78f6a09346b8ac4da2f9baaa Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 09:53:17 +0100 Subject: [PATCH 02/17] Generate custom user pass. --- .../perconaservermongodb/custom_users.go | 69 ++++++++++++++++++- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index b42f7ff18e..ca42df3cb6 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -11,12 +11,14 @@ import ( "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" api "github.com/percona/percona-server-mongodb-operator/pkg/apis/psmdb/v1" "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/mongo" + s "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/secret" ) func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context, cr *api.PerconaServerMongoDB) error { @@ -94,12 +96,27 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context user.PasswordSecretRef.Key = "password" } - sec, err := getUserSecret(ctx, r.client, cr, user.PasswordSecretRef.Name) + defaultUserSecretName := fmt.Sprintf("%s-custom-user-secret", cr.Name) + + userSecretName := defaultUserSecretName + userSecretPassKey := user.Name + if user.PasswordSecretRef != nil { + userSecretName = user.PasswordSecretRef.Name + userSecretPassKey = user.PasswordSecretRef.Key + } + + sec, err := getCustomUserSecret(ctx, r.client, cr, userSecretName, defaultUserSecretName, userSecretPassKey) if err != nil { log.Error(err, "failed to get user secret", "user", user) continue } + // sec, err := getUserSecret(ctx, r.client, cr, user.PasswordSecretRef.Name) + // if err != nil { + // log.Error(err, "failed to get user secret", "user", user) + // continue + // } + userInfo, err := cli.GetUserInfo(ctx, user.Name, user.DB) if err != nil { log.Error(err, "get user info") @@ -109,14 +126,14 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context annotationKey := fmt.Sprintf("percona.com/%s-%s-hash", cr.Name, user.Name) if userInfo == nil { - err = createUser(ctx, r.client, cli, &user, &sec, annotationKey) + err = createUser(ctx, r.client, cli, &user, sec, annotationKey) if err != nil { return errors.Wrapf(err, "create user %s", user.Name) } continue } - err = updatePass(ctx, r.client, cli, &user, userInfo, &sec, annotationKey) + err = updatePass(ctx, r.client, cli, &user, userInfo, sec, annotationKey) if err != nil { log.Error(err, "update user pass", "user", user.Name) continue @@ -368,3 +385,49 @@ func createUser( log.Info("User created", "user", user.UserID()) return nil } + +// getCustomUserSecret gets secret by name defined by `user.PasswordSecretRef.Name` or returns a secret +// with newly generated password if name matches defaultName +func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaServerMongoDB, name, defaultName, passKey string) (*corev1.Secret, error) { + log := logf.FromContext(ctx) + + secret := &corev1.Secret{} + err := cl.Get(ctx, types.NamespacedName{Name: name, Namespace: cr.Namespace}, secret) + + if err != nil && name != defaultName { + return nil, errors.Wrap(err, "failed to get user secret") + } + + if err != nil && !k8serrors.IsNotFound(err) && name == defaultName { + return nil, errors.Wrap(err, "failed to get user secret") + } + + if err != nil && k8serrors.IsNotFound(err) { + secret = &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: cr.Namespace, + }, + } + + pass, err := s.GeneratePassword() + if err != nil { + return nil, errors.Wrap(err, "generate custom user password") + } + + if secret.Data == nil { + secret.Data = make(map[string][]byte) + } + secret.Data[passKey] = pass + + err = cl.Create(ctx, secret) + if err != nil { + return nil, fmt.Errorf("create custom users secret: %v", err) + } + + log.Info("Created custom user secrets", "secrets", secret.Name) + return secret, nil + } + + return secret, nil +} From b91a8a11603b0a004011044e62a8be226ceba937 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 10:40:41 +0100 Subject: [PATCH 03/17] Update e2e test. --- .../custom-users-roles/compare/user-gen.json | 21 +++++++++++++++++++ .../custom-users-roles/conf/some-name-rs0.yml | 8 +++++++ e2e-tests/custom-users-roles/run | 7 +++++++ 3 files changed, 36 insertions(+) create mode 100644 e2e-tests/custom-users-roles/compare/user-gen.json diff --git a/e2e-tests/custom-users-roles/compare/user-gen.json b/e2e-tests/custom-users-roles/compare/user-gen.json new file mode 100644 index 0000000000..56798db308 --- /dev/null +++ b/e2e-tests/custom-users-roles/compare/user-gen.json @@ -0,0 +1,21 @@ +switched to db admin +{ + "_id" : "admin.user-gen", + "user" : "user-gen", + "db" : "admin", + "roles" : [ + { + "role" : "clusterAdmin", + "db" : "admin" + }, + { + "role" : "userAdminAnyDatabase", + "db" : "admin" + } + ], + "mechanisms" : [ + "SCRAM-SHA-1", + "SCRAM-SHA-256" + ] +} +bye diff --git a/e2e-tests/custom-users-roles/conf/some-name-rs0.yml b/e2e-tests/custom-users-roles/conf/some-name-rs0.yml index 0002a19ce9..3a1ff7ea45 100644 --- a/e2e-tests/custom-users-roles/conf/some-name-rs0.yml +++ b/e2e-tests/custom-users-roles/conf/some-name-rs0.yml @@ -43,6 +43,14 @@ spec: db: admin - name: userAdminAnyDatabase db: admin + - name: user-gen + db: admin + roles: + - name: clusterAdmin + db: admin + - name: userAdminAnyDatabase + db: admin + backup: enabled: true image: perconalab/percona-server-mongodb-operator:1.1.0-backup diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index 92dc628aaf..df0168e13f 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -46,6 +46,13 @@ userOnePass=$(getSecretData "user-one" "userOnePassKey") compare 'admin' 'db.getUser("user-one")' "$mongoUri" "user-one" check_mongo_auth "$userOne:$userOnePass@$cluster-0.$cluster.$namespace" +generatedUserSecret="$cluster-custom-user-secret" +generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data.user-gen}" | base64 -d) +compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" +check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" + +echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + desc 'delete initial user from CR and create a new one' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ "spec": {"users":[ From 2e90cb96b09c634577c4d8a516bd86aa5569516a Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 11:54:23 +0100 Subject: [PATCH 04/17] Fix check --- pkg/controller/perconaservermongodb/custom_users.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index ca42df3cb6..d62cc48aec 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -83,7 +83,7 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context continue } - if user.PasswordSecretRef == nil && user.DB != "$external" { + if user.PasswordSecretRef != nil && user.DB != "$external" { log.Error(nil, "user must have passwordSecretRef or $external DB set", "user", user.Name) continue } @@ -92,7 +92,7 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context user.DB = "admin" } - if user.PasswordSecretRef.Key == "" { + if user.PasswordSecretRef != nil && user.PasswordSecretRef.Key == "" { user.PasswordSecretRef.Key = "password" } From f204fadef56b1ae05e0a44a8f3d991a83e13f940 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 12:27:56 +0100 Subject: [PATCH 05/17] Remove check --- pkg/controller/perconaservermongodb/custom_users.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index d62cc48aec..974247a5a0 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -83,10 +83,10 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context continue } - if user.PasswordSecretRef != nil && user.DB != "$external" { - log.Error(nil, "user must have passwordSecretRef or $external DB set", "user", user.Name) - continue - } + // if user.PasswordSecretRef == nil && user.DB != "$external" { + // log.Error(nil, "user must have passwordSecretRef or $external DB set", "user", user.Name) + // continue + // } if user.DB == "" { user.DB = "admin" From 1780fb892574eaaf99f7dd0482282c4756721284 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 12:39:45 +0100 Subject: [PATCH 06/17] Log --- pkg/controller/perconaservermongodb/custom_users.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index 974247a5a0..e3e2cf0f0e 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -105,6 +105,9 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context userSecretPassKey = user.PasswordSecretRef.Key } + + log.Info("AAAAAAAAAAAAAAAAAAAA Getting user secret", "user", user.Name, "secret", userSecretName) + sec, err := getCustomUserSecret(ctx, r.client, cr, userSecretName, defaultUserSecretName, userSecretPassKey) if err != nil { log.Error(err, "failed to get user secret", "user", user) @@ -402,6 +405,9 @@ func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaS return nil, errors.Wrap(err, "failed to get user secret") } + + log.Info("XXXXXXXXXX") + if err != nil && k8serrors.IsNotFound(err) { secret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -410,6 +416,8 @@ func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaS }, } + log.Info("CCCCCCCCCCCCCCCCCCCCCC Creating custom user secrets", "secrets", secret.Name) + pass, err := s.GeneratePassword() if err != nil { return nil, errors.Wrap(err, "generate custom user password") From 5dec49390b5071d725b21b9d20badc989a23eac6 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 12:56:02 +0100 Subject: [PATCH 07/17] Fix --- .../perconaservermongodb/custom_users.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index e3e2cf0f0e..21ad3b11b4 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -105,9 +105,6 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context userSecretPassKey = user.PasswordSecretRef.Key } - - log.Info("AAAAAAAAAAAAAAAAAAAA Getting user secret", "user", user.Name, "secret", userSecretName) - sec, err := getCustomUserSecret(ctx, r.client, cr, userSecretName, defaultUserSecretName, userSecretPassKey) if err != nil { log.Error(err, "failed to get user secret", "user", user) @@ -129,6 +126,9 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context annotationKey := fmt.Sprintf("percona.com/%s-%s-hash", cr.Name, user.Name) if userInfo == nil { + + log.Info("AAAAAAAAAAAAAAAAAAAA Creating user", "user", user.Name, "secretttttt", sec) + err = createUser(ctx, r.client, cli, &user, sec, annotationKey) if err != nil { return errors.Wrapf(err, "create user %s", user.Name) @@ -405,9 +405,6 @@ func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaS return nil, errors.Wrap(err, "failed to get user secret") } - - log.Info("XXXXXXXXXX") - if err != nil && k8serrors.IsNotFound(err) { secret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -416,8 +413,6 @@ func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaS }, } - log.Info("CCCCCCCCCCCCCCCCCCCCCC Creating custom user secrets", "secrets", secret.Name) - pass, err := s.GeneratePassword() if err != nil { return nil, errors.Wrap(err, "generate custom user password") @@ -430,11 +425,10 @@ func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaS err = cl.Create(ctx, secret) if err != nil { - return nil, fmt.Errorf("create custom users secret: %v", err) + return nil, errors.Wrap(err, "create custom users secret") } log.Info("Created custom user secrets", "secrets", secret.Name) - return secret, nil } return secret, nil From b9c3932c3090f01b2580d32c78bcb290372d4e42 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 13:15:23 +0100 Subject: [PATCH 08/17] Propper pass key. --- e2e-tests/custom-users-roles/run | 2 +- .../perconaservermongodb/custom_users.go | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index df0168e13f..88d721299d 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -46,7 +46,7 @@ userOnePass=$(getSecretData "user-one" "userOnePassKey") compare 'admin' 'db.getUser("user-one")' "$mongoUri" "user-one" check_mongo_auth "$userOne:$userOnePass@$cluster-0.$cluster.$namespace" -generatedUserSecret="$cluster-custom-user-secret" +generatedUserSecret="$psmdb-custom-user-secret" generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data.user-gen}" | base64 -d) compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index 21ad3b11b4..36426d8692 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -126,17 +126,14 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context annotationKey := fmt.Sprintf("percona.com/%s-%s-hash", cr.Name, user.Name) if userInfo == nil { - - log.Info("AAAAAAAAAAAAAAAAAAAA Creating user", "user", user.Name, "secretttttt", sec) - - err = createUser(ctx, r.client, cli, &user, sec, annotationKey) + err = createUser(ctx, r.client, cli, &user, sec, annotationKey, userSecretPassKey) if err != nil { return errors.Wrapf(err, "create user %s", user.Name) } continue } - err = updatePass(ctx, r.client, cli, &user, userInfo, sec, annotationKey) + err = updatePass(ctx, r.client, cli, &user, userInfo, sec, annotationKey, userSecretPassKey) if err != nil { log.Error(err, "update user pass", "user", user.Name) continue @@ -286,14 +283,14 @@ func updatePass( user *api.User, userInfo *mongo.User, secret *corev1.Secret, - annotationKey string) error { + annotationKey, passKey string) error { log := logf.FromContext(ctx) if userInfo == nil { return nil } - newHash := sha256Hash(secret.Data[user.PasswordSecretRef.Key]) + newHash := sha256Hash(secret.Data[passKey]) hash, ok := secret.Annotations[annotationKey] if ok && hash == newHash { @@ -306,7 +303,7 @@ func updatePass( log.Info("User password changed, updating it.", "user", user.UserID()) - err := mongoCli.UpdateUserPass(ctx, user.DB, user.Name, string(secret.Data[user.PasswordSecretRef.Key])) + err := mongoCli.UpdateUserPass(ctx, user.DB, user.Name, string(secret.Data[passKey])) if err != nil { return errors.Wrapf(err, "update user %s password", user.Name) } @@ -359,7 +356,7 @@ func createUser( mongoCli mongo.Client, user *api.User, secret *corev1.Secret, - annotationKey string) error { + annotationKey, passKey string) error { log := logf.FromContext(ctx) roles := make([]map[string]interface{}, 0) @@ -371,7 +368,7 @@ func createUser( } log.Info("Creating user", "user", user.UserID()) - err := mongoCli.CreateUser(ctx, user.DB, user.Name, string(secret.Data[user.PasswordSecretRef.Key]), roles...) + err := mongoCli.CreateUser(ctx, user.DB, user.Name, string(secret.Data[passKey]), roles...) if err != nil { return err } @@ -380,7 +377,7 @@ func createUser( secret.Annotations = make(map[string]string) } - secret.Annotations[annotationKey] = string(sha256Hash(secret.Data[user.PasswordSecretRef.Key])) + secret.Annotations[annotationKey] = string(sha256Hash(secret.Data[passKey])) if err := cli.Update(ctx, secret); err != nil { return err } From 1de4b2cc1d8055691c306e695b8040f4f58e4c4a Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 15:56:50 +0100 Subject: [PATCH 09/17] Refactor and fix external db user creation. --- .../compare/user-external.json | 21 +++++++++++++ .../custom-users-roles/conf/some-name-rs0.yml | 7 +++++ e2e-tests/custom-users-roles/run | 2 +- .../perconaservermongodb/custom_users.go | 30 +++++++++---------- pkg/psmdb/mongo/mongo.go | 11 +++++-- 5 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 e2e-tests/custom-users-roles/compare/user-external.json diff --git a/e2e-tests/custom-users-roles/compare/user-external.json b/e2e-tests/custom-users-roles/compare/user-external.json new file mode 100644 index 0000000000..4e3c157a60 --- /dev/null +++ b/e2e-tests/custom-users-roles/compare/user-external.json @@ -0,0 +1,21 @@ +switched to db admin +{ + "_id" : "$external.user-gen", + "user" : "user-gen", + "db" : "$external", + "roles" : [ + { + "role" : "clusterAdmin", + "db" : "admin" + }, + { + "role" : "userAdminAnyDatabase", + "db" : "admin" + } + ], + "mechanisms" : [ + "SCRAM-SHA-1", + "SCRAM-SHA-256" + ] +} +bye diff --git a/e2e-tests/custom-users-roles/conf/some-name-rs0.yml b/e2e-tests/custom-users-roles/conf/some-name-rs0.yml index 3a1ff7ea45..98f8e8725f 100644 --- a/e2e-tests/custom-users-roles/conf/some-name-rs0.yml +++ b/e2e-tests/custom-users-roles/conf/some-name-rs0.yml @@ -50,6 +50,13 @@ spec: db: admin - name: userAdminAnyDatabase db: admin + - name: user-external + db: $external + roles: + - name: clusterAdmin + db: admin + - name: userAdminAnyDatabase + db: admin backup: enabled: true diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index 88d721299d..c4c09f4e1c 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -51,7 +51,7 @@ generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data. compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" -echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +compare '$external' 'db.getUser("user-external")' "$mongoUri" "user-external" desc 'delete initial user from CR and create a new one' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index 36426d8692..c42aec4456 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -58,8 +58,19 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context return nil } + err = handleUsers(ctx, cr, cli, r.client) + if err != nil { + return errors.Wrap(err, "handle users") + } + + return nil +} + +func handleUsers(ctx context.Context, cr *api.PerconaServerMongoDB, cli mongo.Client, client client.Client) error { + log := logf.FromContext(ctx) + sysUsersSecret := corev1.Secret{} - err = r.client.Get(ctx, + err := client.Get(ctx, types.NamespacedName{ Namespace: cr.Namespace, Name: api.InternalUserSecretName(cr), @@ -83,11 +94,6 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context continue } - // if user.PasswordSecretRef == nil && user.DB != "$external" { - // log.Error(nil, "user must have passwordSecretRef or $external DB set", "user", user.Name) - // continue - // } - if user.DB == "" { user.DB = "admin" } @@ -105,18 +111,12 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context userSecretPassKey = user.PasswordSecretRef.Key } - sec, err := getCustomUserSecret(ctx, r.client, cr, userSecretName, defaultUserSecretName, userSecretPassKey) + sec, err := getCustomUserSecret(ctx, client, cr, userSecretName, defaultUserSecretName, userSecretPassKey) if err != nil { log.Error(err, "failed to get user secret", "user", user) continue } - // sec, err := getUserSecret(ctx, r.client, cr, user.PasswordSecretRef.Name) - // if err != nil { - // log.Error(err, "failed to get user secret", "user", user) - // continue - // } - userInfo, err := cli.GetUserInfo(ctx, user.Name, user.DB) if err != nil { log.Error(err, "get user info") @@ -126,14 +126,14 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context annotationKey := fmt.Sprintf("percona.com/%s-%s-hash", cr.Name, user.Name) if userInfo == nil { - err = createUser(ctx, r.client, cli, &user, sec, annotationKey, userSecretPassKey) + err = createUser(ctx, client, cli, &user, sec, annotationKey, userSecretPassKey) if err != nil { return errors.Wrapf(err, "create user %s", user.Name) } continue } - err = updatePass(ctx, r.client, cli, &user, userInfo, sec, annotationKey, userSecretPassKey) + err = updatePass(ctx, client, cli, &user, userInfo, sec, annotationKey, userSecretPassKey) if err != nil { log.Error(err, "update user pass", "user", user.Name) continue diff --git a/pkg/psmdb/mongo/mongo.go b/pkg/psmdb/mongo/mongo.go index 60268605d8..125ce51518 100644 --- a/pkg/psmdb/mongo/mongo.go +++ b/pkg/psmdb/mongo/mongo.go @@ -283,11 +283,16 @@ func (client *mongoClient) GetRole(ctx context.Context, db, role string) (*Role, func (client *mongoClient) CreateUser(ctx context.Context, db, user, pwd string, roles ...map[string]interface{}) error { resp := OKResponse{} - res := client.Database(db).RunCommand(ctx, bson.D{ + d := bson.D{ {Key: "createUser", Value: user}, - {Key: "pwd", Value: pwd}, {Key: "roles", Value: roles}, - }) + } + + if db != "$external" { + d = append(d, bson.E{Key: "pwd", Value: pwd}) + } + + res := client.Database(db).RunCommand(ctx, d) if res.Err() != nil { return errors.Wrap(res.Err(), "failed to create user") } From 7eeb1ba26770c9ff8855c939873a760a506fa1f0 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 30 Oct 2024 16:40:34 +0100 Subject: [PATCH 10/17] Update e2e test. --- e2e-tests/custom-users-roles/compare/user-external.json | 9 ++++----- e2e-tests/custom-users-roles/run | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/e2e-tests/custom-users-roles/compare/user-external.json b/e2e-tests/custom-users-roles/compare/user-external.json index 4e3c157a60..9a80fc294b 100644 --- a/e2e-tests/custom-users-roles/compare/user-external.json +++ b/e2e-tests/custom-users-roles/compare/user-external.json @@ -1,7 +1,7 @@ -switched to db admin +switched to db $external { - "_id" : "$external.user-gen", - "user" : "user-gen", + "_id" : "$external.user-external", + "user" : "user-external", "db" : "$external", "roles" : [ { @@ -14,8 +14,7 @@ switched to db admin } ], "mechanisms" : [ - "SCRAM-SHA-1", - "SCRAM-SHA-256" + "external" ] } bye diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index c4c09f4e1c..60bf1bcc1f 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -51,9 +51,11 @@ generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data. compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" +# Only check if $external.user-external user exists, as the password is not known +# since we don't have a external provider set in this test compare '$external' 'db.getUser("user-external")' "$mongoUri" "user-external" -desc 'delete initial user from CR and create a new one' +desc 'delete initial users from CR and create a new one' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ "spec": {"users":[ { From 0c83355c6c8bdb6a632979489b5d261ed3023fb4 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 13 Nov 2024 08:49:44 +0100 Subject: [PATCH 11/17] Update e2e tests. --- .../compare/user-external.json | 20 ++++++++++++++++++ .../compare/user-gen.json | 21 +++++++++++++++++++ .../conf/some-name-rs0.yml | 14 +++++++++++++ e2e-tests/custom-users-roles-sharded/run | 9 ++++++++ 4 files changed, 64 insertions(+) create mode 100644 e2e-tests/custom-users-roles-sharded/compare/user-external.json create mode 100644 e2e-tests/custom-users-roles-sharded/compare/user-gen.json diff --git a/e2e-tests/custom-users-roles-sharded/compare/user-external.json b/e2e-tests/custom-users-roles-sharded/compare/user-external.json new file mode 100644 index 0000000000..9a80fc294b --- /dev/null +++ b/e2e-tests/custom-users-roles-sharded/compare/user-external.json @@ -0,0 +1,20 @@ +switched to db $external +{ + "_id" : "$external.user-external", + "user" : "user-external", + "db" : "$external", + "roles" : [ + { + "role" : "clusterAdmin", + "db" : "admin" + }, + { + "role" : "userAdminAnyDatabase", + "db" : "admin" + } + ], + "mechanisms" : [ + "external" + ] +} +bye diff --git a/e2e-tests/custom-users-roles-sharded/compare/user-gen.json b/e2e-tests/custom-users-roles-sharded/compare/user-gen.json new file mode 100644 index 0000000000..56798db308 --- /dev/null +++ b/e2e-tests/custom-users-roles-sharded/compare/user-gen.json @@ -0,0 +1,21 @@ +switched to db admin +{ + "_id" : "admin.user-gen", + "user" : "user-gen", + "db" : "admin", + "roles" : [ + { + "role" : "clusterAdmin", + "db" : "admin" + }, + { + "role" : "userAdminAnyDatabase", + "db" : "admin" + } + ], + "mechanisms" : [ + "SCRAM-SHA-1", + "SCRAM-SHA-256" + ] +} +bye diff --git a/e2e-tests/custom-users-roles-sharded/conf/some-name-rs0.yml b/e2e-tests/custom-users-roles-sharded/conf/some-name-rs0.yml index bf6682bd62..f69b7413ff 100644 --- a/e2e-tests/custom-users-roles-sharded/conf/some-name-rs0.yml +++ b/e2e-tests/custom-users-roles-sharded/conf/some-name-rs0.yml @@ -43,6 +43,20 @@ spec: db: admin - name: userAdminAnyDatabase db: admin + - name: user-gen + db: admin + roles: + - name: clusterAdmin + db: admin + - name: userAdminAnyDatabase + db: admin + - name: user-external + db: $external + roles: + - name: clusterAdmin + db: admin + - name: userAdminAnyDatabase + db: admin backup: enabled: false diff --git a/e2e-tests/custom-users-roles-sharded/run b/e2e-tests/custom-users-roles-sharded/run index 78f8114bd0..987a3a96e7 100755 --- a/e2e-tests/custom-users-roles-sharded/run +++ b/e2e-tests/custom-users-roles-sharded/run @@ -74,6 +74,15 @@ userOnePass=$(getSecretData "user-one" "userOnePassKey") compare 'admin' 'db.getUser("user-one")' "$mongosUri" "user-one" check_auth "$userOne:$userOnePass@$cluster-mongos.$namespace" +generatedUserSecret="$psmdb-custom-user-secret" +generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data.user-gen}" | base64 -d) +compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" +check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" + +# Only check if $external.user-external user exists, as the password is not known +# since we don't have a external provider set in this test +compare '$external' 'db.getUser("user-external")' "$mongoUri" "user-external" + desc 'delete initial user from CR and create a new one' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ "spec": {"users":[ From 0bc19145f9f9981d73740f8e40224ecf701f8131 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Wed, 13 Nov 2024 09:14:34 +0100 Subject: [PATCH 12/17] Make sure if external DB user is created that we don't handle user secret. --- .../perconaservermongodb/custom_users.go | 86 +++++++++++++++---- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/pkg/controller/perconaservermongodb/custom_users.go b/pkg/controller/perconaservermongodb/custom_users.go index 1b02a0e39a..80b26515b7 100644 --- a/pkg/controller/perconaservermongodb/custom_users.go +++ b/pkg/controller/perconaservermongodb/custom_users.go @@ -33,29 +33,29 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context log := logf.FromContext(ctx) var err error - var cli mongo.Client + var mongoCli mongo.Client if cr.Spec.Sharding.Enabled { - cli, err = r.mongosClientWithRole(ctx, cr, api.RoleUserAdmin) + mongoCli, err = r.mongosClientWithRole(ctx, cr, api.RoleUserAdmin) } else { - cli, err = r.mongoClientWithRole(ctx, cr, cr.Spec.Replsets[0], api.RoleUserAdmin) + mongoCli, err = r.mongoClientWithRole(ctx, cr, cr.Spec.Replsets[0], api.RoleUserAdmin) } if err != nil { return errors.Wrap(err, "failed to get mongo client") } defer func() { - err := cli.Disconnect(ctx) + err := mongoCli.Disconnect(ctx) if err != nil { log.Error(err, "failed to close mongo connection") } }() - handleRoles(ctx, cr, cli) + handleRoles(ctx, cr, mongoCli) if len(cr.Spec.Users) == 0 { return nil } - err = handleUsers(ctx, cr, cli, r.client) + err = handleUsers(ctx, cr, mongoCli, r.client) if err != nil { return errors.Wrap(err, "handle users") } @@ -63,7 +63,7 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCustomUsers(ctx context.Context return nil } -func handleUsers(ctx context.Context, cr *api.PerconaServerMongoDB, cli mongo.Client, client client.Client) error { +func handleUsers(ctx context.Context, cr *api.PerconaServerMongoDB, mongoCli mongo.Client, client client.Client) error { log := logf.FromContext(ctx) sysUsersSecret := corev1.Secret{} @@ -99,6 +99,20 @@ func handleUsers(ctx context.Context, cr *api.PerconaServerMongoDB, cli mongo.Cl user.PasswordSecretRef.Key = "password" } + userInfo, err := mongoCli.GetUserInfo(ctx, user.Name, user.DB) + if err != nil { + log.Error(err, "get user info") + continue + } + + if user.DB == "$external" && userInfo == nil { + err = createExternalUser(ctx, mongoCli, &user) + if err != nil { + return errors.Wrapf(err, "create user %s", user.Name) + } + continue + } + defaultUserSecretName := fmt.Sprintf("%s-custom-user-secret", cr.Name) userSecretName := defaultUserSecretName @@ -114,29 +128,23 @@ func handleUsers(ctx context.Context, cr *api.PerconaServerMongoDB, cli mongo.Cl continue } - userInfo, err := cli.GetUserInfo(ctx, user.Name, user.DB) - if err != nil { - log.Error(err, "get user info") - continue - } - annotationKey := fmt.Sprintf("percona.com/%s-%s-hash", cr.Name, user.Name) if userInfo == nil { - err = createUser(ctx, client, cli, &user, sec, annotationKey, userSecretPassKey) + err = createUser(ctx, client, mongoCli, &user, sec, annotationKey, userSecretPassKey) if err != nil { return errors.Wrapf(err, "create user %s", user.Name) } continue } - err = updatePass(ctx, client, cli, &user, userInfo, sec, annotationKey, userSecretPassKey) + err = updatePass(ctx, client, mongoCli, &user, userInfo, sec, annotationKey, userSecretPassKey) if err != nil { log.Error(err, "update user pass", "user", user.Name) continue } - err = updateRoles(ctx, cli, &user, userInfo) + err = updateRoles(ctx, mongoCli, &user, userInfo) if err != nil { log.Error(err, "update user roles", "user", user.Name) continue @@ -349,6 +357,28 @@ func updateRoles( return nil } +// createExternalUser creates a user with $external database authentication method. +func createExternalUser(ctx context.Context, mongoCli mongo.Client, user *api.User) error { + log := logf.FromContext(ctx) + + roles := make([]map[string]interface{}, 0) + for _, role := range user.Roles { + roles = append(roles, map[string]interface{}{ + "role": role.Name, + "db": role.DB, + }) + } + + log.Info("Creating user", "user", user.UserID()) + err := mongoCli.CreateUser(ctx, user.DB, user.Name, "", roles...) + if err != nil { + return err + } + + log.Info("User created", "user", user.UserID()) + return nil +} + func createUser( ctx context.Context, cli client.Client, @@ -427,5 +457,29 @@ func getCustomUserSecret(ctx context.Context, cl client.Client, cr *api.PerconaS log.Info("Created custom user secrets", "secrets", secret.Name) } + _, hasPass := secret.Data[passKey] + if !hasPass && name == defaultName { + pass, err := s.GeneratePassword() + if err != nil { + return nil, errors.Wrap(err, "generate custom user password") + } + + if secret.Data == nil { + secret.Data = make(map[string][]byte) + } + + secret.Data[passKey] = pass + + err = cl.Update(ctx, secret) + if err != nil { + return nil, errors.Wrap(err, "failed to update user secret") + } + } + + // pass key should be present in the user provided secret + if !hasPass { + return nil, errors.New("password key not found in secret") + } + return secret, nil } From 965cc40fd31097dd87c768edc1f3783d59a1d07e Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Thu, 14 Nov 2024 06:38:45 +0100 Subject: [PATCH 13/17] Fix custom-users-roles-sharded test. --- e2e-tests/custom-users-roles-sharded/run | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e-tests/custom-users-roles-sharded/run b/e2e-tests/custom-users-roles-sharded/run index 987a3a96e7..3ed102fb1a 100755 --- a/e2e-tests/custom-users-roles-sharded/run +++ b/e2e-tests/custom-users-roles-sharded/run @@ -74,14 +74,14 @@ userOnePass=$(getSecretData "user-one" "userOnePassKey") compare 'admin' 'db.getUser("user-one")' "$mongosUri" "user-one" check_auth "$userOne:$userOnePass@$cluster-mongos.$namespace" -generatedUserSecret="$psmdb-custom-user-secret" +generatedUserSecret="$cluster-custom-user-secret" generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data.user-gen}" | base64 -d) -compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" -check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" +compare 'admin' 'db.getUser("user-gen")' "$mongosUri" "user-gen" +check_auth "user-gen:$generatedPass@$cluster-mongos.$namespace" # Only check if $external.user-external user exists, as the password is not known # since we don't have a external provider set in this test -compare '$external' 'db.getUser("user-external")' "$mongoUri" "user-external" +compare '$external' 'db.getUser("user-external")' "$mongosUri" "user-external" desc 'delete initial user from CR and create a new one' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ From 5330f06d241681687db079ff4a09703defa7345a Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Thu, 21 Nov 2024 16:04:29 +0100 Subject: [PATCH 14/17] Order roles for getUser. --- .../custom-users-roles/compare/user-five.json | 8 +-- .../custom-users-roles/compare/user-two.json | 4 +- e2e-tests/custom-users-roles/run | 56 ++++++++++++++----- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/e2e-tests/custom-users-roles/compare/user-five.json b/e2e-tests/custom-users-roles/compare/user-five.json index a25a7b96c9..f0dd32df9a 100644 --- a/e2e-tests/custom-users-roles/compare/user-five.json +++ b/e2e-tests/custom-users-roles/compare/user-five.json @@ -4,13 +4,13 @@ switched to db testAdmin "user" : "user-five", "db" : "testAdmin", "roles" : [ - { - "role" : "role-four", - "db" : "testAdmin1" - }, { "role" : "role-five", "db" : "testAdmin2" + }, + { + "role" : "role-four", + "db" : "testAdmin1" } ], "mechanisms" : [ diff --git a/e2e-tests/custom-users-roles/compare/user-two.json b/e2e-tests/custom-users-roles/compare/user-two.json index 768466e384..c5c9521063 100644 --- a/e2e-tests/custom-users-roles/compare/user-two.json +++ b/e2e-tests/custom-users-roles/compare/user-two.json @@ -5,11 +5,11 @@ switched to db admin "db" : "admin", "roles" : [ { - "role" : "userAdminAnyDatabase", + "role" : "clusterAdmin", "db" : "admin" }, { - "role" : "clusterAdmin", + "role" : "userAdminAnyDatabase", "db" : "admin" } ], diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index 60bf1bcc1f..4fa92456b2 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -8,15 +8,41 @@ compare() { local uri="$3" local target="$4" + echo "===================" + echo "${command}" + echo "===================" + run_mongo "use ${database}\n ${command}" "$uri" "mongodb" \ | egrep -v 'I NETWORK|W NETWORK|F NETWORK|Error saving history file|Percona Server for MongoDB|connecting to:|Unable to reach primary for set|Implicit session:|versions do not match|Error saving history file:' \ | $sed -re 's/ObjectId\("[0-9a-f]+"\)//; s/-[0-9]+.svc/-xxxesvc/' \ | sed '/"userId"/d' \ >$tmp_dir/${target} - diff ${test_dir}/compare/${target}.json $tmp_dir/${target} + # diff ${test_dir}/compare/${target}.json $tmp_dir/${target} + cp $tmp_dir/${target} ${test_dir}/compare/${target}.json + +} + +get_user_cmd() { + local user="$1" + + cmd="(function() { + var user = db.getUser(${user}); + var roles = user.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + user.roles = roles; + printjson(user); + })();" + + echo "$cmd" } + + test_dir=$(realpath $(dirname $0)) . ${test_dir}/../functions set_debug @@ -43,17 +69,17 @@ desc 'check user created on cluster creation' userOne="user-one" userOnePass=$(getSecretData "user-one" "userOnePassKey") -compare 'admin' 'db.getUser("user-one")' "$mongoUri" "user-one" +compare 'admin' "$(get_user_cmd \"user-one\")" "$mongoUri" "user-one" check_mongo_auth "$userOne:$userOnePass@$cluster-0.$cluster.$namespace" generatedUserSecret="$psmdb-custom-user-secret" generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data.user-gen}" | base64 -d) -compare 'admin' 'db.getUser("user-gen")' "$mongoUri" "user-gen" +compare 'admin' "$(get_user_cmd \"user-gen\")" "$mongoUri" "user-gen" check_mongo_auth "user-gen:$generatedPass@$cluster-0.$cluster.$namespace" # Only check if $external.user-external user exists, as the password is not known # since we don't have a external provider set in this test -compare '$external' 'db.getUser("user-external")' "$mongoUri" "user-external" +compare '$external' "$(get_user_cmd \"user-external\")" "$mongoUri" "user-external" desc 'delete initial users from CR and create a new one' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -74,7 +100,7 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ }' wait_for_running $cluster 3 -compare 'admin' 'db.getUser("user-two")' "$mongoUri" "user-two" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongoUri" "user-two" userTwo="user-two" userTwoPass=$(getSecretData "user-two" "userTwoPassKey") @@ -107,7 +133,7 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ]} }' wait_for_running $cluster 3 -compare 'admin' 'db.getUser("user-two")' "$mongoUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongoUri" "user-two-update-roles" desc 'check user roles update from DB' @@ -115,14 +141,14 @@ run_mongo \ 'use admin\n db.updateUser("user-two", { roles : [{ role : "userAdminAnyDatabase", db: "admin"}]})' \ "$mongoUri" sleep 15 -compare 'admin' 'db.getUser("user-two")' "$mongoUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongoUri" "user-two-update-roles" desc 'check user recreated after deleted from DB' run_mongo \ 'use admin\n db.dropUser("user-two")' \ "$mongoUri" sleep 15 -compare 'admin' 'db.getUser("user-two")' "$mongoUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongoUri" "user-two-update-roles" desc 'check new user created after updated user name via CR' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -142,8 +168,8 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ }' wait_for_running $cluster 3 -compare 'admin' 'db.getUser("user-three")' "$mongoUri" "user-three-admin-db" -compare 'admin' 'db.getUser("user-two")' "$mongoUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-three\")" "$mongoUri" "user-three-admin-db" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongoUri" "user-two-update-roles" # user-three and user-two should be in the DB check_mongo_auth "$userTwo:$userTwoNewPass@$cluster-0.$cluster.$namespace" @@ -166,8 +192,8 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ]} }' wait_for_running $cluster 3 -compare 'newDb' 'db.getUser("user-three")' "$mongoUri" "user-three-newDb-db" -compare 'admin' 'db.getUser("user-three")' "$mongoUri" "user-three-admin-db" +compare 'newDb' "$(get_user_cmd \"user-three\")" "$mongoUri" "user-three-newDb-db" +compare 'admin' "$(get_user_cmd \"user-three\")" "$mongoUri" "user-three-admin-db" desc 'check new user created with default db and secret password key' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -184,7 +210,7 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ]} }' wait_for_running $cluster 3 -compare 'admin' 'db.getUser("user-four")' "$mongoUri" "user-four" +compare 'admin' "$(get_user_cmd \"user-four\")" "$mongoUri" "user-four" # ======================== Roles ======================== @@ -407,8 +433,8 @@ compare 'testAdmin1' 'db.getRole("role-four", {showPrivileges: true, showAuthent "$mongoUri" "role-four" compare 'testAdmin2' 'db.getRole("role-five", {showPrivileges: true, showAuthenticationRestrictions: true})' \ "$mongoUri" "role-five" -compare 'testAdmin' 'db.getUser("user-five")' "$mongoUri" "user-five" -compare 'testAdmin' 'db.getUser("user-six")' "$mongoUri" "user-six" +compare 'testAdmin' "$(get_user_cmd \"user-five\")" "$mongoUri" "user-five" +compare 'testAdmin' "$(get_user_cmd \"user-six\")" "$mongoUri" "user-six" destroy $namespace From 9be37ca4dac358ac2d2408a2ef0ee4352fd806ef Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Thu, 21 Nov 2024 16:21:39 +0100 Subject: [PATCH 15/17] Fix getRole order. --- e2e-tests/custom-users-roles/run | 44 +++++++++++++++++++------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index 4fa92456b2..0a576efdce 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -42,6 +42,23 @@ get_user_cmd() { } +get_role_cmd() { + local role="$1" + + cmd="(function() { + var role = db.getRole(${role}, {showPrivileges: true, showAuthenticationRestrictions: true}); + var roles = role.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + role.roles = roles; + printjson(role); + })();" + + echo "$cmd" +} test_dir=$(realpath $(dirname $0)) . ${test_dir}/../functions @@ -215,16 +232,14 @@ compare 'admin' "$(get_user_cmd \"user-four\")" "$mongoUri" "user-four" # ======================== Roles ======================== desc 'check user role on cluster initialization' -compare 'admin' 'db.getRole("role-one", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-one" +compare 'admin' "$(get_role_cmd \"role-one\")" "$mongoUri" "role-one" desc 'check role recreated after deleted from DB' run_mongo \ 'use admin\n db.dropRole("role-one")' \ "$mongoUri" sleep 15 -compare 'admin' 'db.getRole("role-one", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-one" +compare 'admin' "$(get_role_cmd \"role-one\")" "$mongoUri" "role-one" desc 'delete initial role from CR and create a new one' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -253,10 +268,8 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ] }}' wait_for_running $cluster 3 -compare 'admin' 'db.getRole("role-one", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-one" -compare 'admin' 'db.getRole("role-two", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-two" +compare 'admin' "$(get_role_cmd \"role-one\")" "$mongoUri" "role-one" +compare 'admin' "$(get_role_cmd \"role-two\")" "$mongoUri" "role-two" desc 'check role update from CR' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -279,16 +292,14 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ] }}' wait_for_running $cluster 3 -compare 'admin' 'db.getRole("role-two", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-two-updated" +compare 'admin' "$(get_role_cmd \"role-two\")" "$mongoUri" "role-two-updated" desc 'check role update from DB' run_mongo \ 'use admin\n db.updateRole( "role-two",{privileges:[{resource: {db:"config", collection:"" }, actions: ["find", "update"]}]})' \ "$mongoUri" sleep 15 -compare 'admin' 'db.getRole("role-two", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-two-updated" +compare 'admin' "$(get_role_cmd \"role-two\")" "$mongoUri" "role-two-updated" desc 'check new role created after updated role name via CR' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -311,8 +322,7 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ] }}' wait_for_running $cluster 3 -compare 'admin' 'db.getRole("role-three", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-three" +compare 'admin' "$(get_role_cmd \"role-three\")" "$mongoUri" "role-three" desc 'check creating multiple roles and the users in a single CR apply' kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ @@ -429,10 +439,8 @@ kubectl_bin patch psmdb ${psmdb} --type=merge --patch '{ ] }}' wait_for_running $cluster 3 -compare 'testAdmin1' 'db.getRole("role-four", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-four" -compare 'testAdmin2' 'db.getRole("role-five", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongoUri" "role-five" +compare 'testAdmin1' "$(get_role_cmd \"role-four\")" "$mongoUri" "role-four" +compare 'testAdmin2' "$(get_role_cmd \"role-five\")" "$mongoUri" "role-five" compare 'testAdmin' "$(get_user_cmd \"user-five\")" "$mongoUri" "user-five" compare 'testAdmin' "$(get_user_cmd \"user-six\")" "$mongoUri" "user-six" From 9a99799a0809f2e6eab411abba3d64fa131a0cd7 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Thu, 21 Nov 2024 16:37:06 +0100 Subject: [PATCH 16/17] Fix getRole roles order. --- .../compare/user-five.json | 8 +- .../compare/user-two.json | 4 +- e2e-tests/custom-users-roles-sharded/run | 92 ++++++++++++------- e2e-tests/custom-users-roles/run | 8 +- 4 files changed, 67 insertions(+), 45 deletions(-) diff --git a/e2e-tests/custom-users-roles-sharded/compare/user-five.json b/e2e-tests/custom-users-roles-sharded/compare/user-five.json index a25a7b96c9..f0dd32df9a 100644 --- a/e2e-tests/custom-users-roles-sharded/compare/user-five.json +++ b/e2e-tests/custom-users-roles-sharded/compare/user-five.json @@ -4,13 +4,13 @@ switched to db testAdmin "user" : "user-five", "db" : "testAdmin", "roles" : [ - { - "role" : "role-four", - "db" : "testAdmin1" - }, { "role" : "role-five", "db" : "testAdmin2" + }, + { + "role" : "role-four", + "db" : "testAdmin1" } ], "mechanisms" : [ diff --git a/e2e-tests/custom-users-roles-sharded/compare/user-two.json b/e2e-tests/custom-users-roles-sharded/compare/user-two.json index 768466e384..c5c9521063 100644 --- a/e2e-tests/custom-users-roles-sharded/compare/user-two.json +++ b/e2e-tests/custom-users-roles-sharded/compare/user-two.json @@ -5,11 +5,11 @@ switched to db admin "db" : "admin", "roles" : [ { - "role" : "userAdminAnyDatabase", + "role" : "clusterAdmin", "db" : "admin" }, { - "role" : "clusterAdmin", + "role" : "userAdminAnyDatabase", "db" : "admin" } ], diff --git a/e2e-tests/custom-users-roles-sharded/run b/e2e-tests/custom-users-roles-sharded/run index 3ed102fb1a..d8f9bde9e4 100755 --- a/e2e-tests/custom-users-roles-sharded/run +++ b/e2e-tests/custom-users-roles-sharded/run @@ -27,6 +27,43 @@ check_auth() { fi } +get_user_cmd() { + local user="$1" + + cmd="(function() { + var user = db.getUser(${user}); + var roles = user.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + user.roles = roles; + printjson(user); + })();" + + echo "$cmd" +} + + +get_role_cmd() { + local role="$1" + + cmd="(function() { + var role = db.getRole(${role}, {showPrivileges: true, showAuthenticationRestrictions: true}); + var roles = role.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + role.roles = roles; + printjson(role); + })();" + + echo "$cmd" +} + test_dir=$(realpath $(dirname $0)) . ${test_dir}/../functions set_debug @@ -71,17 +108,17 @@ desc 'check user created on cluster creation' userOne="user-one" userOnePass=$(getSecretData "user-one" "userOnePassKey") -compare 'admin' 'db.getUser("user-one")' "$mongosUri" "user-one" +compare 'admin' "$(get_user_cmd \"user-one\")" "$mongosUri" "user-one" check_auth "$userOne:$userOnePass@$cluster-mongos.$namespace" generatedUserSecret="$cluster-custom-user-secret" generatedPass=$(kubectl_bin get secret $generatedUserSecret -o jsonpath="{.data.user-gen}" | base64 -d) -compare 'admin' 'db.getUser("user-gen")' "$mongosUri" "user-gen" +compare 'admin' "$(get_user_cmd \"user-gen\")" "$mongosUri" "user-gen" check_auth "user-gen:$generatedPass@$cluster-mongos.$namespace" # Only check if $external.user-external user exists, as the password is not known # since we don't have a external provider set in this test -compare '$external' 'db.getUser("user-external")' "$mongosUri" "user-external" +compare '$external' "$(get_user_cmd \"user-external\")" "$mongosUri" "user-external" desc 'delete initial user from CR and create a new one' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -102,7 +139,7 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }' wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getUser("user-two")' "$mongosUri" "user-two" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongosUri" "user-two" userTwo="user-two" userTwoPass=$(getSecretData "user-two" "userTwoPassKey") @@ -136,7 +173,7 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }' wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getUser("user-two")' "$mongosUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongosUri" "user-two-update-roles" desc 'check user roles update from DB' @@ -144,14 +181,14 @@ run_mongos \ 'use admin\n db.updateUser("user-two", { roles : [{ role : "userAdminAnyDatabase", db: "admin"}]})' \ "$mongosUri" sleep 15 -compare 'admin' 'db.getUser("user-two")' "$mongosUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongosUri" "user-two-update-roles" desc 'check user recreated after deleted from DB' run_mongos \ 'use admin\n db.dropUser("user-two")' \ "$mongosUri" sleep 15 -compare 'admin' 'db.getUser("user-two")' "$mongosUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongosUri" "user-two-update-roles" desc 'check new user created after updated user name via CR' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -171,8 +208,8 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }' wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getUser("user-three")' "$mongosUri" "user-three-admin-db" -compare 'admin' 'db.getUser("user-two")' "$mongosUri" "user-two-update-roles" +compare 'admin' "$(get_user_cmd \"user-three\")" "$mongosUri" "user-three-admin-db" +compare 'admin' "$(get_user_cmd \"user-two\")" "$mongosUri" "user-two-update-roles" # user-three and user-two should be in the DB check_auth "$userTwo:$userTwoNewPass@$cluster-mongos.$namespace" @@ -196,8 +233,8 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }' wait_for_running $cluster-rs0 3 -compare 'newDb' 'db.getUser("user-three")' "$mongosUri" "user-three-newDb-db" -compare 'admin' 'db.getUser("user-three")' "$mongosUri" "user-three-admin-db" +compare 'newDb' "$(get_user_cmd \"user-three\")" "$mongosUri" "user-three-newDb-db" +compare 'admin' "$(get_user_cmd \"user-three\")" "$mongosUri" "user-three-admin-db" desc 'check new user created with default db and secret password key' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -215,21 +252,19 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }' wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getUser("user-four")' "$mongosUri" "user-four" +compare 'admin' "$(get_user_cmd \"user-four\")" "$mongosUri" "user-four" # ======================== Roles ======================== desc 'check user role on cluster initialization' -compare 'admin' 'db.getRole("role-one", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-one" +compare 'admin' "$(get_role_cmd \"role-one\")" "$mongosUri" "role-one" desc 'check role recreated after deleted from DB' run_mongos \ 'use admin\n db.dropRole("role-one")' \ "$mongosUri" sleep 15 -compare 'admin' 'db.getRole("role-one", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-one" +compare 'admin' "$(get_role_cmd \"role-one\" )" "$mongosUri" "role-one" desc 'delete initial role from CR and create a new one' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -260,10 +295,8 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getRole("role-one", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-one" -compare 'admin' 'db.getRole("role-two", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-two" +compare 'admin' "$(get_role_cmd \"role-one\" )" "$mongosUri" "role-one" +compare 'admin' "$(get_role_cmd \"role-two\" )" "$mongosUri" "role-two" desc 'check role update from CR' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -287,16 +320,14 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }}' wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getRole("role-two", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-two-updated" +compare 'admin' "$(get_role_cmd \"role-two\" )" "$mongosUri" "role-two-updated" desc 'check role update from DB' run_mongos \ 'use admin\n db.updateRole( "role-two",{privileges:[{resource: {db:"config", collection:"" }, actions: ["find", "update"]}]})' \ "$mongosUri" sleep 15 -compare 'admin' 'db.getRole("role-two", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-two-updated" +compare 'admin' "$(get_role_cmd \"role-two\" )" "$mongosUri" "role-two-updated" desc 'check new role created after updated role name via CR' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -320,8 +351,7 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ }}' wait_for_running $cluster-rs0 3 -compare 'admin' 'db.getRole("role-three", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-three" +compare 'admin' "$(get_role_cmd \"role-three\" )" "$mongosUri" "role-three" desc 'check creating multiple roles and the users in a single CR apply' kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ @@ -438,12 +468,10 @@ kubectl_bin patch psmdb ${cluster} --type=merge --patch '{ ] }}' wait_for_running $cluster-rs0 3 -compare 'testAdmin1' 'db.getRole("role-four", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-four" -compare 'testAdmin2' 'db.getRole("role-five", {showPrivileges: true, showAuthenticationRestrictions: true})' \ - "$mongosUri" "role-five" -compare 'testAdmin' 'db.getUser("user-five")' "$mongosUri" "user-five" -compare 'testAdmin' 'db.getUser("user-six")' "$mongosUri" "user-six" +compare 'testAdmin1' "$(get_role_cmd \"role-four\" )" "$mongosUri" "role-four" +compare 'testAdmin2' "$(get_role_cmd \"role-five\" )" "$mongosUri" "role-five" +compare 'testAdmin' "$(get_user_cmd \"user-five\")" "$mongosUri" "user-five" +compare 'testAdmin' "$(get_user_cmd \"user-six\")" "$mongosUri" "user-six" destroy $namespace diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index 0a576efdce..976fceb300 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -8,19 +8,13 @@ compare() { local uri="$3" local target="$4" - echo "===================" - echo "${command}" - echo "===================" - run_mongo "use ${database}\n ${command}" "$uri" "mongodb" \ | egrep -v 'I NETWORK|W NETWORK|F NETWORK|Error saving history file|Percona Server for MongoDB|connecting to:|Unable to reach primary for set|Implicit session:|versions do not match|Error saving history file:' \ | $sed -re 's/ObjectId\("[0-9a-f]+"\)//; s/-[0-9]+.svc/-xxxesvc/' \ | sed '/"userId"/d' \ >$tmp_dir/${target} - # diff ${test_dir}/compare/${target}.json $tmp_dir/${target} - cp $tmp_dir/${target} ${test_dir}/compare/${target}.json - + diff ${test_dir}/compare/${target}.json $tmp_dir/${target} } get_user_cmd() { From 6ea2ddaa87aeccd7c381103a8bcb05b279329553 Mon Sep 17 00:00:00 2001 From: Inel Pandzic Date: Thu, 21 Nov 2024 17:05:31 +0100 Subject: [PATCH 17/17] Refactor --- e2e-tests/custom-users-roles-sharded/run | 60 ++++++++++++------------ e2e-tests/custom-users-roles/run | 60 ++++++++++++------------ 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/e2e-tests/custom-users-roles-sharded/run b/e2e-tests/custom-users-roles-sharded/run index d8f9bde9e4..7ba23741b5 100755 --- a/e2e-tests/custom-users-roles-sharded/run +++ b/e2e-tests/custom-users-roles-sharded/run @@ -28,40 +28,40 @@ check_auth() { } get_user_cmd() { - local user="$1" - - cmd="(function() { - var user = db.getUser(${user}); - var roles = user.roles; - roles.sort((a, b) => { - if (a.role < b.role) return -1; - if (a.role > b.role) return 1; - return 0; - }); - user.roles = roles; - printjson(user); - })();" - - echo "$cmd" + local user="$1" + + cmd="(function() { + var user = db.getUser(${user}); + var roles = user.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + user.roles = roles; + printjson(user); + })();" + + echo "$cmd" } get_role_cmd() { - local role="$1" - - cmd="(function() { - var role = db.getRole(${role}, {showPrivileges: true, showAuthenticationRestrictions: true}); - var roles = role.roles; - roles.sort((a, b) => { - if (a.role < b.role) return -1; - if (a.role > b.role) return 1; - return 0; - }); - role.roles = roles; - printjson(role); - })();" - - echo "$cmd" + local role="$1" + + cmd="(function() { + var role = db.getRole(${role}, {showPrivileges: true, showAuthenticationRestrictions: true}); + var roles = role.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + role.roles = roles; + printjson(role); + })();" + + echo "$cmd" } test_dir=$(realpath $(dirname $0)) diff --git a/e2e-tests/custom-users-roles/run b/e2e-tests/custom-users-roles/run index 976fceb300..70437f6418 100755 --- a/e2e-tests/custom-users-roles/run +++ b/e2e-tests/custom-users-roles/run @@ -18,40 +18,40 @@ compare() { } get_user_cmd() { - local user="$1" - - cmd="(function() { - var user = db.getUser(${user}); - var roles = user.roles; - roles.sort((a, b) => { - if (a.role < b.role) return -1; - if (a.role > b.role) return 1; - return 0; - }); - user.roles = roles; - printjson(user); - })();" - - echo "$cmd" + local user="$1" + + cmd="(function() { + var user = db.getUser(${user}); + var roles = user.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + user.roles = roles; + printjson(user); + })();" + + echo "$cmd" } get_role_cmd() { - local role="$1" - - cmd="(function() { - var role = db.getRole(${role}, {showPrivileges: true, showAuthenticationRestrictions: true}); - var roles = role.roles; - roles.sort((a, b) => { - if (a.role < b.role) return -1; - if (a.role > b.role) return 1; - return 0; - }); - role.roles = roles; - printjson(role); - })();" - - echo "$cmd" + local role="$1" + + cmd="(function() { + var role = db.getRole(${role}, {showPrivileges: true, showAuthenticationRestrictions: true}); + var roles = role.roles; + roles.sort((a, b) => { + if (a.role < b.role) return -1; + if (a.role > b.role) return 1; + return 0; + }); + role.roles = roles; + printjson(role); + })();" + + echo "$cmd" } test_dir=$(realpath $(dirname $0))