set search_path for default roles (#1065)
* set search_path for default roles * deployment back to 1.5.0 Co-authored-by: Felix Kunde <felix.kunde@zalando.de>
This commit is contained in:
parent
0508266219
commit
dfd0dd90ed
|
|
@ -959,32 +959,42 @@ func (c *Cluster) initPreparedDatabaseRoles() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for preparedDbName, preparedDB := range c.Spec.PreparedDatabases {
|
for preparedDbName, preparedDB := range c.Spec.PreparedDatabases {
|
||||||
|
// get list of prepared schemas to set in search_path
|
||||||
|
preparedSchemas := preparedDB.PreparedSchemas
|
||||||
|
if len(preparedDB.PreparedSchemas) == 0 {
|
||||||
|
preparedSchemas = map[string]acidv1.PreparedSchema{"data": {DefaultRoles: util.True()}}
|
||||||
|
}
|
||||||
|
|
||||||
|
var searchPath strings.Builder
|
||||||
|
searchPath.WriteString(constants.DefaultSearchPath)
|
||||||
|
for preparedSchemaName := range preparedSchemas {
|
||||||
|
searchPath.WriteString(", " + preparedSchemaName)
|
||||||
|
}
|
||||||
|
|
||||||
// default roles per database
|
// default roles per database
|
||||||
if err := c.initDefaultRoles(defaultRoles, "admin", preparedDbName); err != nil {
|
if err := c.initDefaultRoles(defaultRoles, "admin", preparedDbName, searchPath.String()); err != nil {
|
||||||
return fmt.Errorf("could not initialize default roles for database %s: %v", preparedDbName, err)
|
return fmt.Errorf("could not initialize default roles for database %s: %v", preparedDbName, err)
|
||||||
}
|
}
|
||||||
if preparedDB.DefaultUsers {
|
if preparedDB.DefaultUsers {
|
||||||
if err := c.initDefaultRoles(defaultUsers, "admin", preparedDbName); err != nil {
|
if err := c.initDefaultRoles(defaultUsers, "admin", preparedDbName, searchPath.String()); err != nil {
|
||||||
return fmt.Errorf("could not initialize default roles for database %s: %v", preparedDbName, err)
|
return fmt.Errorf("could not initialize default roles for database %s: %v", preparedDbName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// default roles per database schema
|
// default roles per database schema
|
||||||
preparedSchemas := preparedDB.PreparedSchemas
|
|
||||||
if len(preparedDB.PreparedSchemas) == 0 {
|
|
||||||
preparedSchemas = map[string]acidv1.PreparedSchema{"data": {DefaultRoles: util.True()}}
|
|
||||||
}
|
|
||||||
for preparedSchemaName, preparedSchema := range preparedSchemas {
|
for preparedSchemaName, preparedSchema := range preparedSchemas {
|
||||||
if preparedSchema.DefaultRoles == nil || *preparedSchema.DefaultRoles {
|
if preparedSchema.DefaultRoles == nil || *preparedSchema.DefaultRoles {
|
||||||
if err := c.initDefaultRoles(defaultRoles,
|
if err := c.initDefaultRoles(defaultRoles,
|
||||||
preparedDbName+constants.OwnerRoleNameSuffix,
|
preparedDbName+constants.OwnerRoleNameSuffix,
|
||||||
preparedDbName+"_"+preparedSchemaName); err != nil {
|
preparedDbName+"_"+preparedSchemaName,
|
||||||
|
constants.DefaultSearchPath+", "+preparedSchemaName); err != nil {
|
||||||
return fmt.Errorf("could not initialize default roles for database schema %s: %v", preparedSchemaName, err)
|
return fmt.Errorf("could not initialize default roles for database schema %s: %v", preparedSchemaName, err)
|
||||||
}
|
}
|
||||||
if preparedSchema.DefaultUsers {
|
if preparedSchema.DefaultUsers {
|
||||||
if err := c.initDefaultRoles(defaultUsers,
|
if err := c.initDefaultRoles(defaultUsers,
|
||||||
preparedDbName+constants.OwnerRoleNameSuffix,
|
preparedDbName+constants.OwnerRoleNameSuffix,
|
||||||
preparedDbName+"_"+preparedSchemaName); err != nil {
|
preparedDbName+"_"+preparedSchemaName,
|
||||||
|
constants.DefaultSearchPath+", "+preparedSchemaName); err != nil {
|
||||||
return fmt.Errorf("could not initialize default users for database schema %s: %v", preparedSchemaName, err)
|
return fmt.Errorf("could not initialize default users for database schema %s: %v", preparedSchemaName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -994,7 +1004,7 @@ func (c *Cluster) initPreparedDatabaseRoles() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) initDefaultRoles(defaultRoles map[string]string, admin, prefix string) error {
|
func (c *Cluster) initDefaultRoles(defaultRoles map[string]string, admin, prefix string, searchPath string) error {
|
||||||
|
|
||||||
for defaultRole, inherits := range defaultRoles {
|
for defaultRole, inherits := range defaultRoles {
|
||||||
|
|
||||||
|
|
@ -1018,12 +1028,13 @@ func (c *Cluster) initDefaultRoles(defaultRoles map[string]string, admin, prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
newRole := spec.PgUser{
|
newRole := spec.PgUser{
|
||||||
Origin: spec.RoleOriginBootstrap,
|
Origin: spec.RoleOriginBootstrap,
|
||||||
Name: roleName,
|
Name: roleName,
|
||||||
Password: util.RandomPassword(constants.PasswordLength),
|
Password: util.RandomPassword(constants.PasswordLength),
|
||||||
Flags: flags,
|
Flags: flags,
|
||||||
MemberOf: memberOf,
|
MemberOf: memberOf,
|
||||||
AdminRole: adminRole,
|
Parameters: map[string]string{"search_path": searchPath},
|
||||||
|
AdminRole: adminRole,
|
||||||
}
|
}
|
||||||
if currentRole, present := c.pgUsers[roleName]; present {
|
if currentRole, present := c.pgUsers[roleName]; present {
|
||||||
c.pgUsers[roleName] = c.resolveNameConflict(¤tRole, &newRole)
|
c.pgUsers[roleName] = c.resolveNameConflict(¤tRole, &newRole)
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,21 @@ package constants
|
||||||
|
|
||||||
// Roles specific constants
|
// Roles specific constants
|
||||||
const (
|
const (
|
||||||
PasswordLength = 64
|
PasswordLength = 64
|
||||||
SuperuserKeyName = "superuser"
|
SuperuserKeyName = "superuser"
|
||||||
ConnectionPoolerUserKeyName = "pooler"
|
ConnectionPoolerUserKeyName = "pooler"
|
||||||
ReplicationUserKeyName = "replication"
|
ReplicationUserKeyName = "replication"
|
||||||
RoleFlagSuperuser = "SUPERUSER"
|
RoleFlagSuperuser = "SUPERUSER"
|
||||||
RoleFlagInherit = "INHERIT"
|
RoleFlagInherit = "INHERIT"
|
||||||
RoleFlagLogin = "LOGIN"
|
RoleFlagLogin = "LOGIN"
|
||||||
RoleFlagNoLogin = "NOLOGIN"
|
RoleFlagNoLogin = "NOLOGIN"
|
||||||
RoleFlagCreateRole = "CREATEROLE"
|
RoleFlagCreateRole = "CREATEROLE"
|
||||||
RoleFlagCreateDB = "CREATEDB"
|
RoleFlagCreateDB = "CREATEDB"
|
||||||
RoleFlagReplication = "REPLICATION"
|
RoleFlagReplication = "REPLICATION"
|
||||||
RoleFlagByPassRLS = "BYPASSRLS"
|
RoleFlagByPassRLS = "BYPASSRLS"
|
||||||
OwnerRoleNameSuffix = "_owner"
|
OwnerRoleNameSuffix = "_owner"
|
||||||
ReaderRoleNameSuffix = "_reader"
|
ReaderRoleNameSuffix = "_reader"
|
||||||
WriterRoleNameSuffix = "_writer"
|
WriterRoleNameSuffix = "_writer"
|
||||||
UserRoleNameSuffix = "_user"
|
UserRoleNameSuffix = "_user"
|
||||||
|
DefaultSearchPath = "\"$user\""
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -114,14 +114,14 @@ func (strategy DefaultUserSyncStrategy) ExecuteSyncRequests(requests []spec.PgSy
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (strategy DefaultUserSyncStrategy) alterPgUserSet(user spec.PgUser, db *sql.DB) (err error) {
|
|
||||||
|
func (strategy DefaultUserSyncStrategy) alterPgUserSet(user spec.PgUser, db *sql.DB) error {
|
||||||
queries := produceAlterRoleSetStmts(user)
|
queries := produceAlterRoleSetStmts(user)
|
||||||
query := fmt.Sprintf(doBlockStmt, strings.Join(queries, ";"))
|
query := fmt.Sprintf(doBlockStmt, strings.Join(queries, ";"))
|
||||||
if _, err = db.Exec(query); err != nil {
|
if _, err := db.Exec(query); err != nil {
|
||||||
err = fmt.Errorf("dB error: %v, query: %s", err, query)
|
return fmt.Errorf("dB error: %v, query: %s", err, query)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (strategy DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.DB) error {
|
func (strategy DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.DB) error {
|
||||||
|
|
@ -149,6 +149,12 @@ func (strategy DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.D
|
||||||
return fmt.Errorf("dB error: %v, query: %s", err, query)
|
return fmt.Errorf("dB error: %v, query: %s", err, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(user.Parameters) > 0 {
|
||||||
|
if err := strategy.alterPgUserSet(user, db); err != nil {
|
||||||
|
return fmt.Errorf("incomplete setup for user %s: %v", user.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue