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 cd66d8f82..becd24c4c 100644 --- a/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml +++ b/build/crd/crunchy/generated/postgres-operator.crunchydata.com_postgresclusters.yaml @@ -20451,6 +20451,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + 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 211bfedcb..742c488ac 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 @@ -18252,6 +18252,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -18303,6 +18307,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 2d324fbb4..db5017eb6 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 @@ -18657,6 +18657,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -18708,6 +18712,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/postgres-operator.crunchydata.com_postgresclusters.yaml b/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml index 5acc36867..28fd3394f 100644 --- a/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml +++ b/config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml @@ -20349,6 +20349,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + 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 d463f3d34..61a32eb20 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -760,8 +760,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 @@ -18954,6 +18954,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -19005,6 +19009,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: @@ -46837,6 +46846,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + 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 cd2b8e3ae..a9db1ee78 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -72,6 +72,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 0f3446ac9..078396cbb 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -760,8 +760,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 @@ -18954,6 +18954,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -19005,6 +19009,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: @@ -46837,6 +46846,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + 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 45f1915b3..143ffbefb 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -760,8 +760,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 @@ -18954,6 +18954,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase @@ -19005,6 +19009,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: @@ -46837,6 +46846,10 @@ spec: type: string type: array x-kubernetes-list-type: set + grantPublicSchemaAccess: + description: Grant the user access to the public schema in each + database listed under `databases`. + type: boolean name: description: |- The name of this PostgreSQL user. The value may contain only lowercase 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 000000000..99c81c5d0 --- /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 000000000..934432d24 --- /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 000000000..7c37c6651 --- /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 000000000..a4d140634 --- /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 000000000..04d6b2c43 --- /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 2ea0188c9..dfac9a0d2 100644 --- a/internal/postgres/users.go +++ b/internal/postgres/users.go @@ -166,15 +166,29 @@ 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) + } + } + + for _, user := range users { + + // We skip if the user has no databases + if len(user.Databases) == 0 { + continue + } + 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)) + if err = grantUserAccessToPublicSchemaInPostgreSQL(ctx, exec, user); err != nil { + return err + } } } 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) @@ -239,3 +253,50 @@ func WriteUsersSchemasInPostgreSQL(ctx context.Context, exec Executor, } return err } + +// 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) + + 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 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), + "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/internal/postgres/users_test.go b/internal/postgres/users_test.go index 9b9530835..f132c6f8c 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", diff --git a/percona/controller/pgcluster/controller_test.go b/percona/controller/pgcluster/controller_test.go index 15f507822..ac14c4864 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 _ = Describe("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", + )) + }) + }) + }) +}) diff --git a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go index f22f7422e..96ca5b68a 100644 --- a/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go +++ b/pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go @@ -42,6 +42,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"` @@ -167,8 +168,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"` } 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 562cb1f0f..30cf44fd1 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 the user access to the public schema in each database listed under `databases`. + // +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 3d1486fb6..8b2dc688d 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 @@ -2167,6 +2167,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.