From c2879e9746fada8751b5fbb4496057fc6bfe1ce6 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Fri, 21 Mar 2025 11:24:07 +0100 Subject: [PATCH 01/15] K8SPG-571 grant user access to public schema --- ...ator.crunchydata.com_postgresclusters.yaml | 4 ++ .../pgv2.percona.com_perconapgclusters.yaml | 8 ++- .../pgv2.percona.com_perconapgclusters.yaml | 8 ++- ...ator.crunchydata.com_postgresclusters.yaml | 4 ++ deploy/bundle.yaml | 12 +++- deploy/cr.yaml | 1 + deploy/crd.yaml | 12 +++- deploy/cw-bundle.yaml | 12 +++- internal/postgres/users.go | 63 +++++++++++++++++++ .../v2/perconapgcluster_types.go | 8 ++- .../v1beta1/postgres_types.go | 4 ++ .../v1beta1/zz_generated.deepcopy.go | 5 ++ 12 files changed, 129 insertions(+), 12 deletions(-) diff --git a/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml b/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml index 5be36f1ce1..967547fde1 100644 --- a/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml +++ b/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml @@ -19655,6 +19655,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml b/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml index 6f9af22c79..22e5994f55 100644 --- a/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml +++ b/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml @@ -58,8 +58,8 @@ spec: properties: autoCreateUserSchema: description: |- - Whether or not the cluster has schemas automatically created for the user - defined in `spec.users` for all of the databases listed for that user. + Indicates whether schemas are automatically created for the user + specified in `spec.users` across all databases associated with that user. type: boolean backups: description: PostgreSQL backup configuration @@ -17450,6 +17450,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml b/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml index 407b04476c..773dbd5482 100644 --- a/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml +++ b/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml @@ -463,8 +463,8 @@ spec: properties: autoCreateUserSchema: description: |- - Whether or not the cluster has schemas automatically created for the user - defined in `spec.users` for all of the databases listed for that user. + Indicates whether schemas are automatically created for the user + specified in `spec.users` across all databases associated with that user. type: boolean backups: description: PostgreSQL backup configuration @@ -17855,6 +17855,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml b/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml index 1fcedcebb7..6fbd12b21d 100644 --- a/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml +++ b/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml @@ -19553,6 +19553,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 9fd29d74c8..c33410b3db 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -756,8 +756,8 @@ spec: properties: autoCreateUserSchema: description: |- - Whether or not the cluster has schemas automatically created for the user - defined in `spec.users` for all of the databases listed for that user. + Indicates whether schemas are automatically created for the user + specified in `spec.users` across all databases associated with that user. type: boolean backups: description: PostgreSQL backup configuration @@ -18148,6 +18148,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -45233,6 +45237,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 7097126128..5fdbd5e0d1 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -47,6 +47,7 @@ spec: # password: # type: ASCII # secretName: "rhino-credentials" +# grantPublicSchemaAccess: false # databaseInitSQL: # key: init.sql diff --git a/deploy/crd.yaml b/deploy/crd.yaml index 3f89da9dff..d0d7185cf6 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -756,8 +756,8 @@ spec: properties: autoCreateUserSchema: description: |- - Whether or not the cluster has schemas automatically created for the user - defined in `spec.users` for all of the databases listed for that user. + Indicates whether schemas are automatically created for the user + specified in `spec.users` across all databases associated with that user. type: boolean backups: description: PostgreSQL backup configuration @@ -18148,6 +18148,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -45233,6 +45237,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index a881c03667..c26c1cc0c2 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -756,8 +756,8 @@ spec: properties: autoCreateUserSchema: description: |- - Whether or not the cluster has schemas automatically created for the user - defined in `spec.users` for all of the databases listed for that user. + Indicates whether schemas are automatically created for the user + specified in `spec.users` across all databases associated with that user. type: boolean backups: description: PostgreSQL backup configuration @@ -18148,6 +18148,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -45233,6 +45237,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant a specific user access to the public schema + in every database where they already have permissions. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase diff --git a/internal/postgres/users.go b/internal/postgres/users.go index 2ea0188c9f..8c9bd25506 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -170,6 +170,14 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', } } + for i := range users { + user := users[i] + if *user.GrantPublicSchemaAccess { + log.V(1).Info("Granting access to public schema for user.", "user", user.Name) + err = grantUsersSchemasInPostgreSQL(ctx, exec, user) + } + } + return err } @@ -239,3 +247,58 @@ func WriteUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, } return err } + +// GrantUsersSchemasInPostgreSQL will create a schema for each user in each database that user has access to +func grantUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, + user v1beta1.PostgresUserSpec) error { + + log := logging.FromContext(ctx) + + var err error + var stdout string + var stderr string + // We skip if the user has no databases + if len(user.Databases) == 0 { + return nil + } + + var sql bytes.Buffer + + // Prevent unexpected dereferences by emptying "search_path". The "pg_catalog" + // schema is still searched, and only temporary objects can be created. + // - https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-SEARCH-PATH + _, _ = sql.WriteString(`SET search_path TO '';`) + + _, _ = sql.WriteString(`SELECT * FROM json_array_elements_text(:'databases');`) + + databases, _ := json.Marshal(user.Databases) + + stdout, stderr, err = exec.ExecInDatabasesFromQuery(ctx, + sql.String(), + strings.Join([]string{ + // Quiet NOTICE messages from IF EXISTS statements. + `SET client_min_messages = WARNING;`, + + // Grant all privileges on the public schema to the user + `GRANT ALL PRIVILEGES ON SCHEMA public TO :"username";`, + + // Grant all privileges on existing tables and sequences in the public schema + `GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO :"username";`, + `GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO :"username";`, + + // Set default privileges for future objects created in the public schema + `ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO :"username";`, + `ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO :"username";`, + }, "\n"), + map[string]string{ + "databases": string(databases), + "username": string(user.Name), + "ON_ERROR_STOP": "on", // Abort when any one statement fails. + "QUIET": "on", // Do not print successful commands to stdout. + }, + ) + + log.V(1).Info("grant access to public PostgreSQL schemas", "stdout", stdout, "stderr", stderr) + + return err +} diff --git a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go index d43e680a13..4fe8aafb44 100644 --- a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go +++ b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go @@ -170,8 +170,8 @@ type PerconaPGClusterSpec struct { // +optional Extensions ExtensionsSpec `json:"extensions,omitempty"` - // Whether or not the cluster has schemas automatically created for the user - // defined in `spec.users` for all of the databases listed for that user. + // Indicates whether schemas are automatically created for the user + // specified in `spec.users` across all databases associated with that user. // +optional AutoCreateUserSchema *bool `json:"autoCreateUserSchema,omitempty"` } @@ -321,6 +321,10 @@ func (cr *PerconaPGCluster) ToCrunchy(ctx context.Context, postgresCluster *crun log.Info(UserMonitoring + " user is reserved, it'll be ignored.") continue } + if cr.CompareVersion("2.7.0") >= 0 && user.GrantPublicSchemaAccess == nil { + f := false + user.GrantPublicSchemaAccess = &f + } users = append(users, user) } diff --git a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go index 562cb1f0f3..56df3437d2 100644 --- a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go +++ b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go @@ -61,4 +61,8 @@ type PostgresUserSpec struct { // The secret name to generate user, password, connection info this PostgreSQL user. // +optional SecretName PostgresIdentifier `json:"secretName,omitempty"` + + // Grant a specific user access to the public schema in every database where they already have permissions. + // +optional + GrantPublicSchemaAccess *bool `json:"grantPublicSchemaAccess,omitempty"` } diff --git a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/zz_generated.deepcopy.go b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/zz_generated.deepcopy.go index a30a97e478..f5e6b5ab78 100644 --- a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/zz_generated.deepcopy.go @@ -2122,6 +2122,11 @@ func (in *PostgresUserSpec) DeepCopyInto(out *PostgresUserSpec) { *out = new(PostgresPasswordSpec) **out = **in } + if in.GrantPublicSchemaAccess != nil { + in, out := &in.GrantPublicSchemaAccess, &out.GrantPublicSchemaAccess + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresUserSpec. From f38c4f9b8b727b738f9b64e804ea051b33d7e3d0 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Fri, 21 Mar 2025 12:21:18 +0100 Subject: [PATCH 02/15] add test case --- ...custom-user-with-public-schema-access.yaml | 12 +++++ e2e-tests/tests/users/13-assert.yaml | 49 +++++++++++++++++++ .../users/14-write-data-to-custom-db.yaml | 23 +++++++++ e2e-tests/tests/users/15-assert.yaml | 10 ++++ .../users/15-read-from-primary-custom-db.yaml | 19 +++++++ internal/postgres/users.go | 2 +- 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 e2e-tests/tests/users/13-add-custom-user-with-public-schema-access.yaml create mode 100644 e2e-tests/tests/users/13-assert.yaml create mode 100644 e2e-tests/tests/users/14-write-data-to-custom-db.yaml create mode 100644 e2e-tests/tests/users/15-assert.yaml create mode 100644 e2e-tests/tests/users/15-read-from-primary-custom-db.yaml diff --git a/e2e-tests/tests/users/13-add-custom-user-with-public-schema-access.yaml b/e2e-tests/tests/users/13-add-custom-user-with-public-schema-access.yaml new file mode 100644 index 0000000000..99c81c5d0d --- /dev/null +++ b/e2e-tests/tests/users/13-add-custom-user-with-public-schema-access.yaml @@ -0,0 +1,12 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 10 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + kubectl -n ${NAMESPACE} patch perconapgcluster/${test_name} --type=json -p '[{"op":"add", "path":"/spec/autoCreateUserSchema","value":true},{"op":"add", "path":"/spec/users","value":[{"name":"chico","databases":["spain"],"password":{"type":"ASCII"},"secretName":"chico-credentials", "grantPublicSchemaAccess": true}]}]' + sleep 10 diff --git a/e2e-tests/tests/users/13-assert.yaml b/e2e-tests/tests/users/13-assert.yaml new file mode 100644 index 0000000000..934432d24b --- /dev/null +++ b/e2e-tests/tests/users/13-assert.yaml @@ -0,0 +1,49 @@ +apiVersion: postgres-operator.crunchydata.com/v1beta1 +kind: PostgresCluster +metadata: + name: users + ownerReferences: + - apiVersion: pgv2.percona.com/v2 + kind: PerconaPGCluster + name: users + controller: true + blockOwnerDeletion: true + finalizers: + - postgres-operator.crunchydata.com/finalizer +status: + instances: + - name: instance1 + readyReplicas: 3 + replicas: 3 + updatedReplicas: 3 + pgbackrest: + repoHost: + apiVersion: apps/v1 + kind: StatefulSet + ready: true + repos: + - bound: true + name: repo1 + replicaCreateBackupComplete: true + stanzaCreated: true + proxy: + pgBouncer: + readyReplicas: 3 + replicas: 3 +--- +apiVersion: pgv2.percona.com/v2 +kind: PerconaPGCluster +metadata: + name: users +status: + pgbouncer: + ready: 3 + size: 3 + postgres: + instances: + - name: instance1 + ready: 3 + size: 3 + ready: 3 + size: 3 + state: ready diff --git a/e2e-tests/tests/users/14-write-data-to-custom-db.yaml b/e2e-tests/tests/users/14-write-data-to-custom-db.yaml new file mode 100644 index 0000000000..7c37c66517 --- /dev/null +++ b/e2e-tests/tests/users/14-write-data-to-custom-db.yaml @@ -0,0 +1,23 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + password=$(get_psql_user_pass chico-credentials) + user='chico' + db_name='spain' + schema='public' + hostname=$(get_pgbouncer_host chico-credentials) + + + run_psql \ + 'SET search_path TO public;CREATE TABLE IF NOT EXISTS customApp (id int PRIMARY KEY);' \ + "-h $hostname -U $user -d $db_name" "$password" + run_psql \ + "INSERT INTO $schema.customApp (id) VALUES (100500)" \ + "-h $hostname -U $user -d $db_name" "$password" + diff --git a/e2e-tests/tests/users/15-assert.yaml b/e2e-tests/tests/users/15-assert.yaml new file mode 100644 index 0000000000..a4d1406345 --- /dev/null +++ b/e2e-tests/tests/users/15-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 30 +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: 10-read-from-primary-custom-db +data: + data: ' 100500' \ No newline at end of file diff --git a/e2e-tests/tests/users/15-read-from-primary-custom-db.yaml b/e2e-tests/tests/users/15-read-from-primary-custom-db.yaml new file mode 100644 index 0000000000..04d6b2c43b --- /dev/null +++ b/e2e-tests/tests/users/15-read-from-primary-custom-db.yaml @@ -0,0 +1,19 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +timeout: 30 +commands: + - script: |- + set -o errexit + set -o xtrace + + source ../../functions + + password=$(get_psql_user_pass chico-credentials) + user='chico' + db_name='spain' + schema='public' + hostname=$(get_pgbouncer_host chico-credentials) + + data=$(run_psql "SELECT * from $schema.customApp;" "-h $hostname -U $user -d $db_name" "$password") + + kubectl create configmap -n "${NAMESPACE}" 10-read-from-primary-custom-db --from-literal=data="${data}" diff --git a/internal/postgres/users.go b/internal/postgres/users.go index 8c9bd25506..26c9e3cc3e 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -173,7 +173,7 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', for i := range users { user := users[i] if *user.GrantPublicSchemaAccess { - log.V(1).Info("Granting access to public schema for user.", "user", user.Name) + log.V(1).Info("Granting access to public schema for user.", "name", string(user.Name)) err = grantUsersSchemasInPostgreSQL(ctx, exec, user) } } From 7e9791e0c3c9bee97e460387d4d7abf864a60e0e Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Fri, 21 Mar 2025 12:24:29 +0100 Subject: [PATCH 03/15] update database condition --- internal/postgres/users.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/postgres/users.go b/internal/postgres/users.go index 26c9e3cc3e..245f2d8c14 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -172,6 +172,11 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', for i := range users { user := users[i] + + // We skip if the user has no databases + if len(user.Databases) == 0 { + continue + } if *user.GrantPublicSchemaAccess { log.V(1).Info("Granting access to public schema for user.", "name", string(user.Name)) err = grantUsersSchemasInPostgreSQL(ctx, exec, user) From 613842fc8e9df1a6c752c1f8eeea1278fd8fa901 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Fri, 21 Mar 2025 14:53:08 +0100 Subject: [PATCH 04/15] fix unit tests --- internal/postgres/users.go | 2 +- pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/postgres/users.go b/internal/postgres/users.go index 245f2d8c14..b4406a4322 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -177,7 +177,7 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', if len(user.Databases) == 0 { continue } - if *user.GrantPublicSchemaAccess { + if cluster.CompareVersion("2.7.0") >= 0 && user.GrantPublicSchemaAccess != nil && *user.GrantPublicSchemaAccess { log.V(1).Info("Granting access to public schema for user.", "name", string(user.Name)) err = grantUsersSchemasInPostgreSQL(ctx, exec, user) } diff --git a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go index 4fe8aafb44..6c7f613ce8 100644 --- a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go +++ b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go @@ -321,10 +321,6 @@ func (cr *PerconaPGCluster) ToCrunchy(ctx context.Context, postgresCluster *crun log.Info(UserMonitoring + " user is reserved, it'll be ignored.") continue } - if cr.CompareVersion("2.7.0") >= 0 && user.GrantPublicSchemaAccess == nil { - f := false - user.GrantPublicSchemaAccess = &f - } users = append(users, user) } From d2a091474273dcf9481749f0e040cedfb87ca0e7 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Fri, 21 Mar 2025 15:11:44 +0100 Subject: [PATCH 05/15] fix names --- internal/postgres/users.go | 12 ++++++------ internal/postgres/users_test.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/postgres/users.go b/internal/postgres/users.go index b4406a4322..f04d5c6a2e 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -166,7 +166,7 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', autoCreateUserSchemaAnnotationValue, annotationExists := cluster.Annotations[naming.AutoCreateUserSchemaAnnotation] if annotationExists && strings.EqualFold(autoCreateUserSchemaAnnotationValue, "true") { log.V(1).Info("Writing schemas for users.") - err = WriteUsersSchemasInPostgreSQL(ctx, exec, users) + err = writeUsersSchemasInPostgreSQL(ctx, exec, users) } } @@ -179,15 +179,15 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', } if cluster.CompareVersion("2.7.0") >= 0 && user.GrantPublicSchemaAccess != nil && *user.GrantPublicSchemaAccess { log.V(1).Info("Granting access to public schema for user.", "name", string(user.Name)) - err = grantUsersSchemasInPostgreSQL(ctx, exec, user) + err = grantUserAccessToPublicSchemaInPostgreSQL(ctx, exec, user) } } return err } -// WriteUsersSchemasInPostgreSQL will create a schema for each user in each database that user has access to -func WriteUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, +// writeUsersSchemasInPostgreSQL will create a schema for each user in each database that user has access to +func writeUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, users []v1beta1.PostgresUserSpec) error { log := logging.FromContext(ctx) @@ -253,8 +253,8 @@ func WriteUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, return err } -// GrantUsersSchemasInPostgreSQL will create a schema for each user in each database that user has access to -func grantUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, +// grantUserAccessToPublicSchemaInPostgreSQL grant the specified user access to the public schema within the specified database. +func grantUserAccessToPublicSchemaInPostgreSQL(ctx context.Context, exec Executor, user v1beta1.PostgresUserSpec) error { log := logging.FromContext(ctx) diff --git a/internal/postgres/users_test.go b/internal/postgres/users_test.go index 9b9530835e..f132c6f8c1 100644 --- a/internal/postgres/users_test.go +++ b/internal/postgres/users_test.go @@ -209,7 +209,7 @@ func TestWriteUsersSchemasInPostgreSQL(t *testing.T) { return nil } - assert.NilError(t, WriteUsersSchemasInPostgreSQL(ctx, exec, + assert.NilError(t, writeUsersSchemasInPostgreSQL(ctx, exec, []v1beta1.PostgresUserSpec{ { Name: "user-single-db", From 0819c1b4609858dd7a6bbf56bc5e0fc747ceb8ab Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Fri, 21 Mar 2025 19:54:13 +0100 Subject: [PATCH 06/15] fix PR comments --- ...ostgres-operator.crunchydata.com_postgresclusters.yaml | 4 ++-- .../generated/pgv2.percona.com_perconapgclusters.yaml | 4 ++-- config/crd/bases/pgv2.percona.com_perconapgclusters.yaml | 4 ++-- ...ostgres-operator.crunchydata.com_postgresclusters.yaml | 4 ++-- deploy/bundle.yaml | 8 ++++---- deploy/crd.yaml | 8 ++++---- deploy/cw-bundle.yaml | 8 ++++---- internal/postgres/users.go | 8 ++------ .../v1beta1/postgres_types.go | 2 +- 9 files changed, 23 insertions(+), 27 deletions(-) diff --git a/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml b/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml index 967547fde1..038824ea2d 100644 --- a/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml +++ b/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml @@ -19656,8 +19656,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml b/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml index 22e5994f55..0be0c46e06 100644 --- a/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml +++ b/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml @@ -17451,8 +17451,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml b/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml index 773dbd5482..0f5f922e2d 100644 --- a/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml +++ b/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml @@ -17856,8 +17856,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml b/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml index 6fbd12b21d..9d8967340f 100644 --- a/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml +++ b/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml @@ -19554,8 +19554,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index c33410b3db..1533f3ae02 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -18149,8 +18149,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- @@ -45238,8 +45238,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/deploy/crd.yaml b/deploy/crd.yaml index d0d7185cf6..7ffc6483d4 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -18149,8 +18149,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- @@ -45238,8 +45238,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index c26c1cc0c2..4a87bdab13 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -18149,8 +18149,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- @@ -45238,8 +45238,8 @@ spec: type: array x-kubernetes-list-type: set grantPublicSchemaAccess: - description: Grant a specific user access to the public schema - in every database where they already have permissions. + description: Grant the user access to the public schema in each + database listed under `databases`. type: boolean name: description: |- diff --git a/internal/postgres/users.go b/internal/postgres/users.go index f04d5c6a2e..272f42de70 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -170,8 +170,7 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', } } - for i := range users { - user := users[i] + for _, user := range users { // We skip if the user has no databases if len(user.Databases) == 0 { @@ -259,9 +258,6 @@ func grantUserAccessToPublicSchemaInPostgreSQL(ctx context.Context, exec Executo log := logging.FromContext(ctx) - var err error - var stdout string - var stderr string // We skip if the user has no databases if len(user.Databases) == 0 { return nil @@ -278,7 +274,7 @@ func grantUserAccessToPublicSchemaInPostgreSQL(ctx context.Context, exec Executo databases, _ := json.Marshal(user.Databases) - stdout, stderr, err = exec.ExecInDatabasesFromQuery(ctx, + stdout, stderr, err := exec.ExecInDatabasesFromQuery(ctx, sql.String(), strings.Join([]string{ // Quiet NOTICE messages from IF EXISTS statements. diff --git a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go index 56df3437d2..30cf44fd17 100644 --- a/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go +++ b/pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgres_types.go @@ -62,7 +62,7 @@ type PostgresUserSpec struct { // +optional SecretName PostgresIdentifier `json:"secretName,omitempty"` - // Grant a specific user access to the public schema in every database where they already have permissions. + // Grant the user access to the public schema in each database listed under `databases`. // +optional GrantPublicSchemaAccess *bool `json:"grantPublicSchemaAccess,omitempty"` } From 90abede40c4f597733d66f981ede3a1543955822 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 3 Apr 2025 13:48:34 +0200 Subject: [PATCH 07/15] add validation and update new schema access --- .../generated/pgv2.percona.com_perconapgclusters.yaml | 5 +++++ config/crd/bases/pgv2.percona.com_perconapgclusters.yaml | 5 +++++ deploy/bundle.yaml | 5 +++++ deploy/crd.yaml | 5 +++++ deploy/cw-bundle.yaml | 5 +++++ internal/postgres/users.go | 4 ++-- pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go | 1 + 7 files changed, 28 insertions(+), 2 deletions(-) diff --git a/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml b/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml index 0be0c46e06..e7adc74cb3 100644 --- a/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml +++ b/build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml @@ -17505,6 +17505,11 @@ spec: - instances - postgresVersion type: object + x-kubernetes-validations: + - message: PostgresVersion must be >= 15 if grantPublicSchemaAccess exists + and is true + rule: '!has(self.users) || self.postgresVersion >= 15 || self.users.all(u, + !has(u.grantPublicSchemaAccess) || !u.grantPublicSchemaAccess)' status: properties: host: diff --git a/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml b/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml index 0f5f922e2d..970c9deae6 100644 --- a/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml +++ b/config/crd/bases/pgv2.percona.com_perconapgclusters.yaml @@ -17910,6 +17910,11 @@ spec: - instances - postgresVersion type: object + x-kubernetes-validations: + - message: PostgresVersion must be >= 15 if grantPublicSchemaAccess exists + and is true + rule: '!has(self.users) || self.postgresVersion >= 15 || self.users.all(u, + !has(u.grantPublicSchemaAccess) || !u.grantPublicSchemaAccess)' status: properties: host: diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 1533f3ae02..ad355b6e67 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -18203,6 +18203,11 @@ spec: - instances - postgresVersion type: object + x-kubernetes-validations: + - message: PostgresVersion must be >= 15 if grantPublicSchemaAccess exists + and is true + rule: '!has(self.users) || self.postgresVersion >= 15 || self.users.all(u, + !has(u.grantPublicSchemaAccess) || !u.grantPublicSchemaAccess)' status: properties: host: diff --git a/deploy/crd.yaml b/deploy/crd.yaml index 7ffc6483d4..208b9cb1fa 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -18203,6 +18203,11 @@ spec: - instances - postgresVersion type: object + x-kubernetes-validations: + - message: PostgresVersion must be >= 15 if grantPublicSchemaAccess exists + and is true + rule: '!has(self.users) || self.postgresVersion >= 15 || self.users.all(u, + !has(u.grantPublicSchemaAccess) || !u.grantPublicSchemaAccess)' status: properties: host: diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index 4a87bdab13..fe3799aa08 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -18203,6 +18203,11 @@ spec: - instances - postgresVersion type: object + x-kubernetes-validations: + - message: PostgresVersion must be >= 15 if grantPublicSchemaAccess exists + and is true + rule: '!has(self.users) || self.postgresVersion >= 15 || self.users.all(u, + !has(u.grantPublicSchemaAccess) || !u.grantPublicSchemaAccess)' status: properties: host: diff --git a/internal/postgres/users.go b/internal/postgres/users.go index 272f42de70..75aae55e50 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -288,8 +288,8 @@ func grantUserAccessToPublicSchemaInPostgreSQL(ctx context.Context, exec Executo `GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO :"username";`, // Set default privileges for future objects created in the public schema - `ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO :"username";`, - `ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO :"username";`, + `ALTER DEFAULT PRIVILEGES FOR ROLE "username" IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO "username";`, + `ALTER DEFAULT PRIVILEGES FOR ROLE "username" IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO "username";`, }, "\n"), map[string]string{ "databases": string(databases), diff --git a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go index 6c7f613ce8..2c06467a75 100644 --- a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go +++ b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go @@ -47,6 +47,7 @@ type PerconaPGCluster struct { Status PerconaPGClusterStatus `json:"status,omitempty"` } +// +kubebuilder:validation:XValidation:rule="!has(self.users) || self.postgresVersion >= 15 || self.users.all(u, !has(u.grantPublicSchemaAccess) || !u.grantPublicSchemaAccess)",message="PostgresVersion must be >= 15 if grantPublicSchemaAccess exists and is true" type PerconaPGClusterSpec struct { // +optional Metadata *crunchyv1beta1.Metadata `json:"metadata,omitempty"` From 210c8fd21b049d66fdbd1e1b8d12e28877dca7b8 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 14:57:22 +0200 Subject: [PATCH 08/15] fix PR comments --- internal/postgres/users.go | 9 +- .../controller/pgcluster/controller_test.go | 109 +++++++++++++++++- 2 files changed, 109 insertions(+), 9 deletions(-) diff --git a/internal/postgres/users.go b/internal/postgres/users.go index 75aae55e50..dfac9a0d2d 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -178,7 +178,9 @@ SELECT pg_catalog.format('GRANT ALL PRIVILEGES ON DATABASE %I TO %I', } if cluster.CompareVersion("2.7.0") >= 0 && user.GrantPublicSchemaAccess != nil && *user.GrantPublicSchemaAccess { log.V(1).Info("Granting access to public schema for user.", "name", string(user.Name)) - err = grantUserAccessToPublicSchemaInPostgreSQL(ctx, exec, user) + if err = grantUserAccessToPublicSchemaInPostgreSQL(ctx, exec, user); err != nil { + return err + } } } @@ -258,11 +260,6 @@ func grantUserAccessToPublicSchemaInPostgreSQL(ctx context.Context, exec Executo log := logging.FromContext(ctx) - // We skip if the user has no databases - if len(user.Databases) == 0 { - return nil - } - var sql bytes.Buffer // Prevent unexpected dereferences by emptying "search_path". The "pg_catalog" diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index 15f507822f..61335418e5 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -11,8 +11,6 @@ import ( "sync" "time" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" gs "github.com/onsi/gomega/gstruct" "github.com/pkg/errors" "go.opentelemetry.io/otel/trace" @@ -843,7 +841,7 @@ var _ = Describe("Users", Ordered, func() { Expect(k8sClient.Status().Update(ctx, cr)).Should(Succeed()) }) - It("should create defaul and monitor user", func() { + It("should create default and monitor user", func() { _, err := reconciler(cr).Reconcile(ctx, ctrl.Request{NamespacedName: crNamespacedName}) Expect(err).NotTo(HaveOccurred()) _, err = crunchyReconciler().Reconcile(ctx, ctrl.Request{NamespacedName: crNamespacedName}) @@ -1622,3 +1620,108 @@ var _ = Describe("Validate TLS", Ordered, func() { checkSecretProjectionWithCA(cr, cr.Spec.Secrets.CustomReplicationClientTLSSecret, secretName) }) }) + +var _ = FDescribe("CR Validations", Ordered, func() { + ctx := context.Background() + ns := "cr-validation" + + namespace := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns, + }, + } + + BeforeAll(func() { + By("Creating the Namespace to perform the tests") + err := k8sClient.Create(ctx, namespace) + Expect(err).To(Not(HaveOccurred())) + }) + + AfterAll(func() { + By("Deleting the Namespace to perform the tests") + _ = k8sClient.Delete(ctx, namespace) + }) + + Context("PostgresVersion and grantPublicSchemaAccess validations", Ordered, func() { + When("creating a CR with valid configurations", func() { + It("should accept version >=15 with public schema access", func() { + cr, err := readDefaultCR("cr-validation-1", ns) + Expect(err).NotTo(HaveOccurred()) + + cr.Spec.PostgresVersion = 15 + cr.Spec.Users = []v2.User{{ + GrantPublicSchemaAccess: ptr.To(true), + }} + + Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) + }) + + It("should accept version <15 without public schema access", func() { + cr, err := readDefaultCR("cr-validation-2", ns) + Expect(err).NotTo(HaveOccurred()) + + cr.Spec.PostgresVersion = 14 + cr.Spec.Users = []v2.User{{ + GrantPublicSchemaAccess: ptr.To(false), + }} + + Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) + }) + + It("should accept version <15 with omitted public schema access", func() { + cr, err := readDefaultCR("cr-validation-3", ns) + Expect(err).NotTo(HaveOccurred()) + + cr.Spec.PostgresVersion = 14 + cr.Spec.Users = []v2.User{{}} + + Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) + }) + + It("should accept when no users are specified", func() { + cr, err := readDefaultCR("cr-validation-4", ns) + Expect(err).NotTo(HaveOccurred()) + + cr.Spec.PostgresVersion = 14 + cr.Spec.Users = nil // No users provided + + Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) + }) + }) + + When("creating a CR with invalid configurations", func() { + It("should reject version <15 with public schema access", func() { + cr, err := readDefaultCR("cr-validation-5", ns) + Expect(err).NotTo(HaveOccurred()) + + cr.Spec.PostgresVersion = 14 + cr.Spec.Users = []v2.User{{ + GrantPublicSchemaAccess: ptr.To(true), + }} + + err = k8sClient.Create(ctx, cr) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring( + "PostgresVersion must be >= 15 if grantPublicSchemaAccess exists and is true", + )) + }) + + It("should reject mixed access in multiple users", func() { + cr, err := readDefaultCR("cr-validation-6", ns) + Expect(err).NotTo(HaveOccurred()) + + cr.Spec.PostgresVersion = 14 + cr.Spec.Users = []v2.User{ + {GrantPublicSchemaAccess: ptr.To(false)}, + {GrantPublicSchemaAccess: ptr.To(true)}, + } + + err = k8sClient.Create(ctx, cr) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring( + "PostgresVersion must be >= 15 if grantPublicSchemaAccess exists and is true", + )) + }) + }) + }) +}) From 1a91e1865486d97b6dad25b922061e17d3186e4e Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 15:03:20 +0200 Subject: [PATCH 09/15] delete force --- percona/controller/pgcluster/controller_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index 61335418e5..ac14c4864c 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -1621,7 +1621,7 @@ var _ = Describe("Validate TLS", Ordered, func() { }) }) -var _ = FDescribe("CR Validations", Ordered, func() { +var _ = Describe("CR Validations", Ordered, func() { ctx := context.Background() ns := "cr-validation" From 8143727c317aea6f8421f5b07e68e628e38779dd Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 15:28:14 +0200 Subject: [PATCH 10/15] add import --- percona/controller/pgcluster/controller_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index ac14c4864c..09832368f9 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -11,6 +11,8 @@ import ( "sync" "time" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" gs "github.com/onsi/gomega/gstruct" "github.com/pkg/errors" "go.opentelemetry.io/otel/trace" From 13314bf15f402bced1de8417144bb56d1a6afe46 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 15:54:03 +0200 Subject: [PATCH 11/15] fix tests --- .../controller/pgcluster/controller_test.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index 09832368f9..b260db8d2c 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -1640,7 +1640,7 @@ var _ = Describe("CR Validations", Ordered, func() { }) AfterAll(func() { - By("Deleting the Namespace to perform the tests") + By("Deleting the Namespace to clean up after the tests") _ = k8sClient.Delete(ctx, namespace) }) @@ -1651,8 +1651,8 @@ var _ = Describe("CR Validations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) cr.Spec.PostgresVersion = 15 - cr.Spec.Users = []v2.User{{ - GrantPublicSchemaAccess: ptr.To(true), + cr.Spec.Users = []v1beta1.PostgresUserSpec{{ + GrantPublicSchemaAccess: true, }} Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) @@ -1663,8 +1663,8 @@ var _ = Describe("CR Validations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) cr.Spec.PostgresVersion = 14 - cr.Spec.Users = []v2.User{{ - GrantPublicSchemaAccess: ptr.To(false), + cr.Spec.Users = []v1beta1.PostgresUserSpec{{ + GrantPublicSchemaAccess: false, }} Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) @@ -1675,7 +1675,7 @@ var _ = Describe("CR Validations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) cr.Spec.PostgresVersion = 14 - cr.Spec.Users = []v2.User{{}} + cr.Spec.Users = []v1beta1.PostgresUserSpec{{}} Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) }) @@ -1697,8 +1697,8 @@ var _ = Describe("CR Validations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) cr.Spec.PostgresVersion = 14 - cr.Spec.Users = []v2.User{{ - GrantPublicSchemaAccess: ptr.To(true), + cr.Spec.Users = []v1beta1.PostgresUserSpec{{ + GrantPublicSchemaAccess: true, }} err = k8sClient.Create(ctx, cr) @@ -1713,9 +1713,9 @@ var _ = Describe("CR Validations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) cr.Spec.PostgresVersion = 14 - cr.Spec.Users = []v2.User{ - {GrantPublicSchemaAccess: ptr.To(false)}, - {GrantPublicSchemaAccess: ptr.To(true)}, + cr.Spec.Users = []v1beta1.PostgresUserSpec{ + {GrantPublicSchemaAccess: false}, + {GrantPublicSchemaAccess: true}, } err = k8sClient.Create(ctx, cr) From 9b6876459ccc5c50e2007e3f11f40686e03bb4a7 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 16:03:43 +0200 Subject: [PATCH 12/15] fix tests --- percona/controller/pgcluster/controller_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index b260db8d2c..d4f3331a60 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -1626,7 +1626,8 @@ var _ = Describe("Validate TLS", Ordered, func() { var _ = Describe("CR Validations", Ordered, func() { ctx := context.Background() ns := "cr-validation" - + t := true + f := false namespace := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: ns, @@ -1652,7 +1653,7 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 15 cr.Spec.Users = []v1beta1.PostgresUserSpec{{ - GrantPublicSchemaAccess: true, + GrantPublicSchemaAccess: &t, }} Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) @@ -1664,7 +1665,7 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 14 cr.Spec.Users = []v1beta1.PostgresUserSpec{{ - GrantPublicSchemaAccess: false, + GrantPublicSchemaAccess: &f, }} Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) @@ -1698,7 +1699,7 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 14 cr.Spec.Users = []v1beta1.PostgresUserSpec{{ - GrantPublicSchemaAccess: true, + GrantPublicSchemaAccess: &t, }} err = k8sClient.Create(ctx, cr) @@ -1714,8 +1715,8 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 14 cr.Spec.Users = []v1beta1.PostgresUserSpec{ - {GrantPublicSchemaAccess: false}, - {GrantPublicSchemaAccess: true}, + {GrantPublicSchemaAccess: &f}, + {GrantPublicSchemaAccess: &t}, } err = k8sClient.Create(ctx, cr) From 5a76c7286559766f44adcf5cb1aee8475afaceed Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 16:14:26 +0200 Subject: [PATCH 13/15] fix vars --- percona/controller/pgcluster/controller_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index d4f3331a60..629f9d79eb 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -1653,6 +1653,7 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 15 cr.Spec.Users = []v1beta1.PostgresUserSpec{{ + Name: "test", GrantPublicSchemaAccess: &t, }} @@ -1665,6 +1666,7 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 14 cr.Spec.Users = []v1beta1.PostgresUserSpec{{ + Name: "test", GrantPublicSchemaAccess: &f, }} @@ -1699,6 +1701,7 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 14 cr.Spec.Users = []v1beta1.PostgresUserSpec{{ + Name: "test", GrantPublicSchemaAccess: &t, }} @@ -1715,8 +1718,8 @@ var _ = Describe("CR Validations", Ordered, func() { cr.Spec.PostgresVersion = 14 cr.Spec.Users = []v1beta1.PostgresUserSpec{ - {GrantPublicSchemaAccess: &f}, - {GrantPublicSchemaAccess: &t}, + {Name: "test1", GrantPublicSchemaAccess: &f}, + {Name: "test2", GrantPublicSchemaAccess: &t}, } err = k8sClient.Create(ctx, cr) From 304317f10af4ff75cfda33f81b1a35270f64bfef Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 16:21:45 +0200 Subject: [PATCH 14/15] update vars --- percona/controller/pgcluster/controller_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index 629f9d79eb..a4f242295e 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -1678,7 +1678,7 @@ var _ = Describe("CR Validations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) cr.Spec.PostgresVersion = 14 - cr.Spec.Users = []v1beta1.PostgresUserSpec{{}} + cr.Spec.Users = []v1beta1.PostgresUserSpec{{Name: "test"}} Expect(k8sClient.Create(ctx, cr)).Should(Succeed()) }) From 93895d1035d6202c0453978aa3859915ec2a79b1 Mon Sep 17 00:00:00 2001 From: Natalia Marukovich Date: Thu, 10 Apr 2025 16:42:09 +0200 Subject: [PATCH 15/15] fix test --- percona/controller/pgcluster/controller_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index a4f242295e..8909485abe 100644 --- a/percona/controller/pgcluster/controller_test.go +++ b/percona/controller/pgcluster/controller_test.go @@ -1625,12 +1625,14 @@ var _ = Describe("Validate TLS", Ordered, func() { var _ = Describe("CR Validations", Ordered, func() { ctx := context.Background() - ns := "cr-validation" + const crName = "cr-validation" + const ns = crName t := true f := false namespace := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - Name: ns, + Name: crName, + Namespace: ns, }, }