Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions pkg/cluster/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const (
createDatabaseSQL = `CREATE DATABASE "%s" OWNER "%s";`
createDatabaseSchemaSQL = `SET ROLE TO "%s"; CREATE SCHEMA IF NOT EXISTS "%s" AUTHORIZATION "%s"`
alterDatabaseOwnerSQL = `ALTER DATABASE "%s" OWNER TO "%s";`
createExtensionSQL = `CREATE EXTENSION IF NOT EXISTS "%s" SCHEMA "%s"`
alterExtensionSQL = `ALTER EXTENSION "%s" SET SCHEMA "%s"`
createExtensionSQL = `SET ROLE TO "%s"; CREATE EXTENSION IF NOT EXISTS "%s" SCHEMA "%s"`
alterExtensionSQL = `SET ROLE TO "%s"; ALTER EXTENSION "%s" SET SCHEMA "%s"`

globalDefaultPrivilegesSQL = `SET ROLE TO "%s";
ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO "%s","%s";
Expand All @@ -56,6 +56,13 @@ const (
ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT EXECUTE ON FUNCTIONS TO "%s","%s";
ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT USAGE ON TYPES TO "%s","%s";`

extensionPostCreateSQL = `
GRANT SELECT ON ALL TABLES IN SCHEMA "%s" TO "%s","%s";
GRANT SELECT ON ALL SEQUENCES IN SCHEMA "%s" TO "%s","%s";
GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA "%s" TO "%s","%s";
GRANT USAGE, UPDATE ON ALL SEQUENCES IN SCHEMA "%s" TO "%s","%s";
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "%s" TO "%s","%s","%s";`

connectionPoolerLookup = `
CREATE SCHEMA IF NOT EXISTS {{.pooler_schema}};

Expand Down Expand Up @@ -418,6 +425,19 @@ func (c *Cluster) execAlterGlobalDefaultPrivileges(owner, rolePrefix string) err
return nil
}

func (c *Cluster) execExtensionPostCreatePrivileges(schemaName, rolePrefix string) error {
if _, err := c.pgDb.Exec(fmt.Sprintf(extensionPostCreateSQL,
schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.ReaderRoleNameSuffix, // tables
schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.ReaderRoleNameSuffix, // sequences
schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.WriterRoleNameSuffix, // tables
schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.WriterRoleNameSuffix, // sequences
schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.ReaderRoleNameSuffix, rolePrefix+constants.WriterRoleNameSuffix)); err != nil { // functions
return fmt.Errorf("could not set privileges in schema %s: %v", schemaName, err)
}

return nil
}

func makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool) (result []string) {
if rolsuper {
result = append(result, constants.RoleFlagSuperuser)
Expand Down Expand Up @@ -484,22 +504,22 @@ func (c *Cluster) getExtensions() (dbExtensions map[string]string, err error) {

// executeCreateExtension creates new extension in the given schema.
// The caller is responsible for opening and closing the database connection.
func (c *Cluster) executeCreateExtension(extName, schemaName string) error {
return c.execCreateOrAlterExtension(extName, schemaName, createExtensionSQL,
func (c *Cluster) executeCreateExtension(extName, schemaName, schemaOwner string) error {
return c.execCreateOrAlterExtension(extName, schemaName, schemaOwner, createExtensionSQL,
"creating extension", "create extension")
}

// executeAlterExtension changes the schema of the given extension.
// The caller is responsible for opening and closing the database connection.
func (c *Cluster) executeAlterExtension(extName, schemaName string) error {
return c.execCreateOrAlterExtension(extName, schemaName, alterExtensionSQL,
func (c *Cluster) executeAlterExtension(extName, schemaName, schemaOwner string) error {
return c.execCreateOrAlterExtension(extName, schemaName, schemaOwner, alterExtensionSQL,
"changing schema for extension", "alter extension schema")
}

func (c *Cluster) execCreateOrAlterExtension(extName, schemaName, statement, doing, operation string) error {
func (c *Cluster) execCreateOrAlterExtension(extName, schemaName, schemaOwner, statement, doing, operation string) error {

c.logger.Infof("%s %q schema %q", doing, extName, schemaName)
if _, err := c.pgDb.Exec(fmt.Sprintf(statement, extName, schemaName)); err != nil {
if _, err := c.pgDb.Exec(fmt.Sprintf(statement, schemaOwner, extName, schemaName)); err != nil {
return fmt.Errorf("could not execute %s: %v", operation, err)
}

Expand Down
16 changes: 12 additions & 4 deletions pkg/cluster/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ func (c *Cluster) syncPreparedDatabases() error {
}

// install extensions
if err := c.syncExtensions(preparedDB.Extensions); err != nil {
if err := c.syncExtensions(preparedDbName, preparedDB.Extensions); err != nil {
return err
}

Expand Down Expand Up @@ -836,7 +836,7 @@ func (c *Cluster) syncPreparedSchemas(databaseName string, preparedSchemas map[s
return nil
}

func (c *Cluster) syncExtensions(extensions map[string]string) error {
func (c *Cluster) syncExtensions(databaseName string, extensions map[string]string) error {
c.setProcessName("syncing database extensions")

createExtensions := make(map[string]string)
Expand All @@ -857,12 +857,20 @@ func (c *Cluster) syncExtensions(extensions map[string]string) error {
}

for extName, schema := range createExtensions {
if err = c.executeCreateExtension(extName, schema); err != nil {
if err = c.executeCreateExtension(extName, schema, databaseName+constants.OwnerRoleNameSuffix); err != nil {
return err
}
// grant privileges on objects created by the extension to default database roles
if err = c.execExtensionPostCreatePrivileges(schema, databaseName); err != nil {
return err
}
// try to grant to default schema roles, too, but defaultRoles could be false for schema
if err = c.execExtensionPostCreatePrivileges(schema, databaseName+"_"+schema); err != nil {
c.logger.Debugf("no privileges assigned to schema roles: %v", err)
}
}
for extName, schema := range alterExtensions {
if err = c.executeAlterExtension(extName, schema); err != nil {
if err = c.executeAlterExtension(extName, schema, databaseName+constants.OwnerRoleNameSuffix); err != nil {
return err
}
}
Expand Down