From cd3bd0605671491754cdb6489020e1a917436de3 Mon Sep 17 00:00:00 2001 From: Alex Szakaly Date: Thu, 5 Jun 2025 22:47:27 +0200 Subject: [PATCH 1/3] feat: spec.secrets must be existing secrets Signed-off-by: Alex Szakaly --- .../perconaservermongodb/psmdb_controller.go | 6 ++ .../perconaservermongodb/secrets.go | 67 ++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/pkg/controller/perconaservermongodb/psmdb_controller.go b/pkg/controller/perconaservermongodb/psmdb_controller.go index 47d8632a2..b2dbfb0fc 100644 --- a/pkg/controller/perconaservermongodb/psmdb_controller.go +++ b/pkg/controller/perconaservermongodb/psmdb_controller.go @@ -276,6 +276,12 @@ func (r *ReconcilePerconaServerMongoDB) Reconcile(ctx context.Context, request r return reconcile.Result{}, errors.Wrap(err, "set CR version") } + // Make sure that secrets specified in the manifest are preserved and not overwritten by the operator. + err = r.ensureSecretExistence(ctx, cr) + if err != nil { + return reconcile.Result{}, err + } + err = cr.CheckNSetDefaults(ctx, r.serverVersion.Platform) if err != nil { // If the user created a cluster with finalizers and wrong options, it would be impossible to delete a cluster. diff --git a/pkg/controller/perconaservermongodb/secrets.go b/pkg/controller/perconaservermongodb/secrets.go index c618b6508..672de74a6 100644 --- a/pkg/controller/perconaservermongodb/secrets.go +++ b/pkg/controller/perconaservermongodb/secrets.go @@ -11,6 +11,7 @@ import ( 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/naming" @@ -18,10 +19,10 @@ import ( "github.com/percona/percona-server-mongodb-operator/pkg/psmdb/secret" ) -func getUserSecret(ctx context.Context, cl client.Reader, cr *api.PerconaServerMongoDB, name string) (corev1.Secret, error) { +func getSecret(ctx context.Context, cl client.Reader, cr *api.PerconaServerMongoDB, name string) (corev1.Secret, error) { secrets := corev1.Secret{} err := cl.Get(ctx, types.NamespacedName{Name: name, Namespace: cr.Namespace}, &secrets) - return secrets, errors.Wrap(err, "get user secrets") + return secrets, err } func getInternalCredentials(ctx context.Context, cl client.Reader, cr *api.PerconaServerMongoDB, role api.SystemUserRole) (psmdb.Credentials, error) { @@ -30,7 +31,7 @@ func getInternalCredentials(ctx context.Context, cl client.Reader, cr *api.Perco func getCredentials(ctx context.Context, cl client.Reader, cr *api.PerconaServerMongoDB, name string, role api.SystemUserRole) (psmdb.Credentials, error) { creds := psmdb.Credentials{} - usersSecret, err := getUserSecret(ctx, cl, cr, name) + usersSecret, err := getSecret(ctx, cl, cr, name) if err != nil { return creds, errors.Wrap(err, "failed to get user secret") } @@ -62,7 +63,65 @@ func getCredentials(ctx context.Context, cl client.Reader, cr *api.PerconaServer return creds, nil } +func (r *ReconcilePerconaServerMongoDB) ensureSecretExistence(ctx context.Context, cr *api.PerconaServerMongoDB) error { + if cr.Spec.Secrets == nil { + return nil + } + + if cr.Spec.Secrets.Users != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.Users); err != nil { + return fmt.Errorf("users '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.Users, err) + } + } + + if cr.Spec.Secrets.SSL != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.SSL); err != nil { + return fmt.Errorf("ssl '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.SSL, err) + } + } + + if cr.Spec.Secrets.SSLInternal != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.SSLInternal); err != nil { + return fmt.Errorf("ssl internal '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.SSLInternal, err) + } + } + + if cr.Spec.Secrets.InternalKey != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.InternalKey); err != nil { + return fmt.Errorf("internal key '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.InternalKey, err) + } + } + + if cr.Spec.Secrets.EncryptionKey != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.EncryptionKey); err != nil { + return fmt.Errorf("encryption key '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.EncryptionKey, err) + } + } + + if cr.Spec.Secrets.Vault != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.Vault); err != nil { + return fmt.Errorf("vault '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.Vault, err) + } + } + + if cr.Spec.Secrets.SSE != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.SSE); err != nil { + return fmt.Errorf("sse '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.SSE, err) + } + } + + if cr.Spec.Secrets.LDAPSecret != "" { + if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.LDAPSecret); err != nil { + return fmt.Errorf("ldap '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.LDAPSecret, err) + } + } + + return nil +} + func (r *ReconcilePerconaServerMongoDB) reconcileUsersSecret(ctx context.Context, cr *api.PerconaServerMongoDB) error { + log := logf.FromContext(ctx).WithName("reconcileUsersSecret") + secretObj := corev1.Secret{} err := r.client.Get(ctx, types.NamespacedName{ @@ -117,6 +176,8 @@ func (r *ReconcilePerconaServerMongoDB) reconcileUsersSecret(ctx context.Context return fmt.Errorf("create Users secret: %v", err) } + log.Info("Created user secrets", "secret", cr.Spec.Secrets.Users) + return nil } From f10e45eca967c847ca57bce98addbfd292c1d94a Mon Sep 17 00:00:00 2001 From: Alex Szakaly Date: Thu, 5 Jun 2025 23:57:38 +0200 Subject: [PATCH 2/3] fix: typo in the error message Signed-off-by: Alex Szakaly --- pkg/controller/perconaservermongodb/secrets.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/controller/perconaservermongodb/secrets.go b/pkg/controller/perconaservermongodb/secrets.go index 672de74a6..0ff630ed1 100644 --- a/pkg/controller/perconaservermongodb/secrets.go +++ b/pkg/controller/perconaservermongodb/secrets.go @@ -70,49 +70,49 @@ func (r *ReconcilePerconaServerMongoDB) ensureSecretExistence(ctx context.Contex if cr.Spec.Secrets.Users != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.Users); err != nil { - return fmt.Errorf("users '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.Users, err) + return fmt.Errorf("users '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.Users, err) } } if cr.Spec.Secrets.SSL != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.SSL); err != nil { - return fmt.Errorf("ssl '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.SSL, err) + return fmt.Errorf("ssl '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.SSL, err) } } if cr.Spec.Secrets.SSLInternal != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.SSLInternal); err != nil { - return fmt.Errorf("ssl internal '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.SSLInternal, err) + return fmt.Errorf("ssl internal '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.SSLInternal, err) } } if cr.Spec.Secrets.InternalKey != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.InternalKey); err != nil { - return fmt.Errorf("internal key '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.InternalKey, err) + return fmt.Errorf("internal key '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.InternalKey, err) } } if cr.Spec.Secrets.EncryptionKey != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.EncryptionKey); err != nil { - return fmt.Errorf("encryption key '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.EncryptionKey, err) + return fmt.Errorf("encryption key '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.EncryptionKey, err) } } if cr.Spec.Secrets.Vault != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.Vault); err != nil { - return fmt.Errorf("vault '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.Vault, err) + return fmt.Errorf("vault '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.Vault, err) } } if cr.Spec.Secrets.SSE != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.SSE); err != nil { - return fmt.Errorf("sse '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.SSE, err) + return fmt.Errorf("sse '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.SSE, err) } } if cr.Spec.Secrets.LDAPSecret != "" { if _, err := getSecret(ctx, r.client, cr, cr.Spec.Secrets.LDAPSecret); err != nil { - return fmt.Errorf("ldap '%s' secret must exist if specified in the in the manifest: %w", cr.Spec.Secrets.LDAPSecret, err) + return fmt.Errorf("ldap '%s' secret must exist if specified in the manifest: %w", cr.Spec.Secrets.LDAPSecret, err) } } From db56ee7c993f5ad2d1ada9b0fbbd4e3142f61963 Mon Sep 17 00:00:00 2001 From: Alex Szakaly Date: Fri, 6 Jun 2025 07:38:53 +0200 Subject: [PATCH 3/3] fix: controller tests Signed-off-by: Alex Szakaly --- deploy/cr.yaml | 6 +++--- .../testdata/reconcile-statefulset/cfg-arbiter.yaml | 6 +++--- .../testdata/reconcile-statefulset/cfg-hidden.yaml | 6 +++--- .../testdata/reconcile-statefulset/cfg-mongod.yaml | 6 +++--- .../testdata/reconcile-statefulset/cfg-nv.yaml | 6 +++--- .../testdata/reconcile-statefulset/rs0-arbiter.yaml | 6 +++--- .../testdata/reconcile-statefulset/rs0-hidden.yaml | 6 +++--- .../testdata/reconcile-statefulset/rs0-mongod.yaml | 6 +++--- .../testdata/reconcile-statefulset/rs0-nv.yaml | 6 +++--- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 029b4099b..79db287dd 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -49,9 +49,9 @@ spec: apply: disabled schedule: "0 2 * * *" setFCV: false - secrets: - users: my-cluster-name-secrets - encryptionKey: my-cluster-name-mongodb-encryption-key +# secrets: +# users: my-cluster-name-secrets +# encryptionKey: my-cluster-name-mongodb-encryption-key # ssl: my-cluster-name-ssl # sslInternal: my-cluster-name-ssl-internal # keyFile: my-cluster-name-mongodb-keyfile diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml index b6112d456..8926c955a 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-arbiter.yaml @@ -147,7 +147,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -288,11 +288,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-hidden.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-hidden.yaml index b6112d456..8926c955a 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-hidden.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-hidden.yaml @@ -147,7 +147,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -288,11 +288,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml index b6112d456..8926c955a 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-mongod.yaml @@ -147,7 +147,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -288,11 +288,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml index b6112d456..8926c955a 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/cfg-nv.yaml @@ -147,7 +147,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -288,11 +288,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml index c3b2447cf..776acd1fd 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-arbiter.yaml @@ -148,7 +148,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -182,11 +182,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-hidden.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-hidden.yaml index b2f6e06c5..b386a7ce5 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-hidden.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-hidden.yaml @@ -146,7 +146,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -287,11 +287,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml index dcfbd8ba2..34bb0ef8b 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-mongod.yaml @@ -147,7 +147,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -288,11 +288,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288 diff --git a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml index c98624174..3bcdcecf9 100644 --- a/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml +++ b/pkg/controller/perconaservermongodb/testdata/reconcile-statefulset/rs0-nv.yaml @@ -146,7 +146,7 @@ spec: - mountPath: /opt/percona name: bin - mountPath: /etc/mongodb-encryption - name: my-cluster-name-mongodb-encryption-key + name: reconcile-statefulset-cr-mongodb-encryption-key readOnly: true - mountPath: /etc/users-secret name: users-secret-file @@ -287,11 +287,11 @@ spec: secretName: reconcile-statefulset-cr-mongodb-keyfile - emptyDir: {} name: bin - - name: my-cluster-name-mongodb-encryption-key + - name: reconcile-statefulset-cr-mongodb-encryption-key secret: defaultMode: 288 optional: false - secretName: my-cluster-name-mongodb-encryption-key + secretName: reconcile-statefulset-cr-mongodb-encryption-key - name: ssl secret: defaultMode: 288