diff --git a/internal/controller/postgres_controller.go b/internal/controller/postgres_controller.go index da19b93e..062af076 100644 --- a/internal/controller/postgres_controller.go +++ b/internal/controller/postgres_controller.go @@ -232,49 +232,56 @@ func (r *PostgresReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c instance.Status.Schemas = append(instance.Status.Schemas, schema) } - // Set privileges on schemas during every reconcile to ensure privileges are correct + creatorRoles := []string{owner, writer} + for _, schema := range instance.Spec.Schemas { + for _, creatorRole := range creatorRoles { - // Set privileges on schema - schemaPrivilegesReader := postgres.PostgresSchemaPrivileges{ - DB: database, - Role: reader, - Schema: schema, - Privs: readerPrivs, - CreateSchema: false, - } - err = r.pg.SetSchemaPrivileges(schemaPrivilegesReader) - if err != nil { - reqLogger.Error(err, fmt.Sprintf("Could not give %s permissions \"%s\"", reader, readerPrivs)) - continue - } - schemaPrivilegesWriter := postgres.PostgresSchemaPrivileges{ - DB: database, - Role: writer, - Schema: schema, - Privs: writerPrivs, - SequencePrivs: writerSequencePrivs, - FunctionPrivs: writerFunctionPrivs, - CreateSchema: true, - } - err = r.pg.SetSchemaPrivileges(schemaPrivilegesWriter) - if err != nil { - reqLogger.Error(err, fmt.Sprintf("Could not give %s permissions \"%s\", sequence privileges \"%s\", and function privileges \"%s\"", writer, writerPrivs, writerSequencePrivs, writerFunctionPrivs)) - continue - } - schemaPrivilegesOwner := postgres.PostgresSchemaPrivileges{ - DB: database, - Role: owner, - Schema: schema, - Privs: ownerPrivs, - SequencePrivs: ownerSequencePrivs, - FunctionPrivs: ownerFunctionPrivs, - CreateSchema: true, - } - err = r.pg.SetSchemaPrivileges(schemaPrivilegesOwner) - if err != nil { - reqLogger.Error(err, fmt.Sprintf("Could not give %s permissions \"%s\", sequence privileges \"%s\", and function privileges \"%s\"", owner, ownerPrivs, ownerSequencePrivs, ownerFunctionPrivs)) - continue + schemaPrivilegesReader := postgres.PostgresSchemaPrivileges{ + DB: database, + Role: reader, + CreatorRole: creatorRole, + Schema: schema, + Privs: readerPrivs, + CreateSchema: false, + } + err = r.pg.SetSchemaPrivileges(schemaPrivilegesReader) + if err != nil { + reqLogger.Error(err, fmt.Sprintf("Could not set default privileges for %s on objects created by %s", reader, creatorRole)) + continue + } + + schemaPrivilegesWriter := postgres.PostgresSchemaPrivileges{ + DB: database, + Role: writer, + CreatorRole: creatorRole, + Schema: schema, + Privs: writerPrivs, + SequencePrivs: writerSequencePrivs, + FunctionPrivs: writerFunctionPrivs, + CreateSchema: true, + } + err = r.pg.SetSchemaPrivileges(schemaPrivilegesWriter) + if err != nil { + reqLogger.Error(err, fmt.Sprintf("Could not set default privileges for %s on objects created by %s", writer, creatorRole)) + continue + } + + schemaPrivilegesOwner := postgres.PostgresSchemaPrivileges{ + DB: database, + Role: owner, + CreatorRole: creatorRole, + Schema: schema, + Privs: ownerPrivs, + SequencePrivs: ownerSequencePrivs, + FunctionPrivs: ownerFunctionPrivs, + CreateSchema: true, + } + err = r.pg.SetSchemaPrivileges(schemaPrivilegesOwner) + if err != nil { + reqLogger.Error(err, fmt.Sprintf("Could not set default privileges for %s on objects created by %s", owner, creatorRole)) + continue + } } } diff --git a/pkg/postgres/database.go b/pkg/postgres/database.go index 11fe8c43..2bff58b8 100644 --- a/pkg/postgres/database.go +++ b/pkg/postgres/database.go @@ -16,11 +16,11 @@ const ( GRANT_USAGE_SCHEMA = `GRANT USAGE ON SCHEMA "%s" TO "%s"` GRANT_CREATE_TABLE = `GRANT CREATE ON SCHEMA "%s" TO "%s"` GRANT_ALL_TABLES = `GRANT %s ON ALL TABLES IN SCHEMA "%s" TO "%s"` - DEFAULT_PRIVS_SCHEMA = `ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT %s ON TABLES TO "%s"` + DEFAULT_PRIVS_SCHEMA = `ALTER DEFAULT PRIVILEGES FOR ROLE "%s" IN SCHEMA "%s" GRANT %s ON TABLES TO "%s"` GRANT_ALL_FUNCTIONS = `GRANT %s ON ALL FUNCTIONS IN SCHEMA "%s" TO "%s"` - DEFAULT_PRIVS_FUNCTIONS = `ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT %s ON FUNCTIONS TO "%s"` + DEFAULT_PRIVS_FUNCTIONS = `ALTER DEFAULT PRIVILEGES FOR ROLE "%s" IN SCHEMA "%s" GRANT %s ON FUNCTIONS TO "%s"` GRANT_ALL_SEQUENCES = `GRANT %s ON ALL SEQUENCES IN SCHEMA "%s" TO "%s"` - DEFAULT_PRIVS_SEQUENCES = `ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT %s ON SEQUENCES TO "%s"` + DEFAULT_PRIVS_SEQUENCES = `ALTER DEFAULT PRIVILEGES FOR ROLE "%s" IN SCHEMA "%s" GRANT %s ON SEQUENCES TO "%s"` REVOKE_CONNECT = `REVOKE CONNECT ON DATABASE "%s" FROM public` TERMINATE_BACKEND = `SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '%s' AND pid <> pg_backend_pid()` GET_DB_OWNER = `SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = '%s'` @@ -149,7 +149,7 @@ func (c *pg) SetSchemaPrivileges(schemaPrivileges PostgresSchemaPrivileges) erro } // Grant role privs on future tables in schema - _, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_SCHEMA, schemaPrivileges.Schema, schemaPrivileges.Privs, schemaPrivileges.Role)) + _, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_SCHEMA, schemaPrivileges.CreatorRole, schemaPrivileges.Schema, schemaPrivileges.Privs, schemaPrivileges.Role)) if err != nil { return err } @@ -162,7 +162,7 @@ func (c *pg) SetSchemaPrivileges(schemaPrivileges PostgresSchemaPrivileges) erro } // Grant role privs on future sequences in schema - _, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_SEQUENCES, schemaPrivileges.Schema, schemaPrivileges.SequencePrivs, schemaPrivileges.Role)) + _, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_SEQUENCES, schemaPrivileges.CreatorRole, schemaPrivileges.Schema, schemaPrivileges.SequencePrivs, schemaPrivileges.Role)) if err != nil { return err } @@ -176,7 +176,7 @@ func (c *pg) SetSchemaPrivileges(schemaPrivileges PostgresSchemaPrivileges) erro } // Grant role privs on future functions in schema - _, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_FUNCTIONS, schemaPrivileges.Schema, schemaPrivileges.FunctionPrivs, schemaPrivileges.Role)) + _, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_FUNCTIONS, schemaPrivileges.CreatorRole, schemaPrivileges.Schema, schemaPrivileges.FunctionPrivs, schemaPrivileges.Role)) if err != nil { return err } diff --git a/pkg/postgres/postgres.go b/pkg/postgres/postgres.go index dd5886a5..1dceda27 100644 --- a/pkg/postgres/postgres.go +++ b/pkg/postgres/postgres.go @@ -41,6 +41,7 @@ type pg struct { type PostgresSchemaPrivileges struct { DB string Role string + CreatorRole string Schema string Privs string SequencePrivs string