rename suffix and pgUser field

This commit is contained in:
Felix Kunde 2021-05-17 12:11:36 +02:00
parent 044e92a609
commit 8d58ceb339
18 changed files with 42 additions and 41 deletions

View File

@ -465,9 +465,9 @@ spec:
type: string type: string
default: default:
- admin - admin
role_deprecation_suffix: role_deletion_suffix:
type: string type: string
default: "_delete_me" default: "_deleted"
team_admin_role: team_admin_role:
type: string type: string
default: "admin" default: "admin"

View File

@ -314,7 +314,7 @@ configTeamsApi:
- admin - admin
# Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD # Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD
# role_deprecation_suffix: "_delete_me" # role_deletion_suffix: "_deleted"
# role name to grant to team members created from the Teams API # role name to grant to team members created from the Teams API
team_admin_role: admin team_admin_role: admin

View File

@ -305,7 +305,7 @@ configTeamsApi:
# protected_role_names: "admin" # protected_role_names: "admin"
# Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD # Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD
# role_deprecation_suffix: "_delete_me" # role_deletion_suffix: "_deleted"
# role name to grant to team members created from the Teams API # role name to grant to team members created from the Teams API
# team_admin_role: "admin" # team_admin_role: "admin"

View File

@ -704,12 +704,12 @@ key.
cluster to administer Postgres and maintain infrastructure built around it. cluster to administer Postgres and maintain infrastructure built around it.
The default is empty. The default is empty.
* **role_deprecation_suffix** * **role_deletion_suffix**
defines a suffix that will be appended to database role names of team members defines a suffix that will be appended to database role names of team members
that were removed from either the team in the Teams API or a `PostgresTeam` that were removed from either the team in the Teams API or a `PostgresTeam`
custom resource (additionalMembers). When re-added, the operator will rename custom resource (additionalMembers). When re-added, the operator will rename
roles with the defined suffix back to the original role name. roles with the defined suffix back to the original role name.
The default is `_delete_me`. The default is `_deleted`.
* **enable_postgres_team_crd** * **enable_postgres_team_crd**
toggle to make the operator watch for created or updated `PostgresTeam` CRDs toggle to make the operator watch for created or updated `PostgresTeam` CRDs

View File

@ -414,13 +414,14 @@ from manifests. But, using the `PostgresTeam` custom resource or Teams API it
is very easy to add roles to many clusters. Manually reverting such a change is very easy to add roles to many clusters. Manually reverting such a change
is cumbersome. Therefore, if members are removed from a `PostgresTeam` or the is cumbersome. Therefore, if members are removed from a `PostgresTeam` or the
Teams API the operator will rename roles appending a configured suffix to the Teams API the operator will rename roles appending a configured suffix to the
name (see `role_deprecation_suffix` option) and revoke the `LOGIN` privilege. name (see `role_deletion_suffix` option) and revoke the `LOGIN` privilege.
The suffix makes it easy then for a cleanup script to remove those deprecated The suffix makes it easy then for a cleanup script to remove those deprecated
roles completely. roles completely.
When a role is re-added to a PostgresTeam manifest (or to the source behind When a role is re-added to a `PostgresTeam` manifest (or to the source behind
the Teams API) the operator will check for roles with the configured suffix the Teams API) the operator will check for roles with the configured suffix
and if found, rename the role back to the original name and grant LOGIN again. and if found, rename the role back to the original name and grant `LOGIN`
again.
## Prepared databases with roles and default privileges ## Prepared databases with roles and default privileges

View File

@ -249,7 +249,7 @@ class EndToEndTestCase(unittest.TestCase):
SELECT rolname SELECT rolname
FROM pg_catalog.pg_roles FROM pg_catalog.pg_roles
WHERE (rolname = 'tester' AND rolcanlogin) WHERE (rolname = 'tester' AND rolcanlogin)
OR (rolname = 'kind_delete_me' AND NOT rolcanlogin); OR (rolname = 'kind_deleted' AND NOT rolcanlogin);
""" """
self.eventuallyEqual(lambda: len(self.query_database(leader.metadata.name, "postgres", user_query)), 2, self.eventuallyEqual(lambda: len(self.query_database(leader.metadata.name, "postgres", user_query)), 2,
"PostgresTeam change not reflected in database", 10, 5) "PostgresTeam change not reflected in database", 10, 5)
@ -272,7 +272,7 @@ class EndToEndTestCase(unittest.TestCase):
SELECT rolname SELECT rolname
FROM pg_catalog.pg_roles FROM pg_catalog.pg_roles
WHERE (rolname = 'kind' AND rolcanlogin) WHERE (rolname = 'kind' AND rolcanlogin)
OR (rolname = 'tester_delete_me' AND NOT rolcanlogin); OR (rolname = 'tester_deleted' AND NOT rolcanlogin);
""" """
self.eventuallyEqual(lambda: len(self.query_database(leader.metadata.name, "postgres", user_query)), 2, self.eventuallyEqual(lambda: len(self.query_database(leader.metadata.name, "postgres", user_query)), 2,
"PostgresTeam change not reflected in database", 10, 5) "PostgresTeam change not reflected in database", 10, 5)

View File

@ -111,7 +111,7 @@ data:
resource_check_timeout: 10m resource_check_timeout: 10m
resync_period: 30m resync_period: 30m
ring_log_lines: "100" ring_log_lines: "100"
# role_deprecation_suffix: "_delete_me" # role_deletion_suffix: "_deleted"
secret_name_template: "{username}.{cluster}.credentials" secret_name_template: "{username}.{cluster}.credentials"
# sidecar_docker_images: "" # sidecar_docker_images: ""
# set_memory_request_to_limit: "false" # set_memory_request_to_limit: "false"

View File

@ -461,9 +461,9 @@ spec:
type: string type: string
default: default:
- admin - admin
role_deprecation_suffix: role_deletion_suffix:
type: string type: string
default: "_delete_me" default: "_deleted"
team_admin_role: team_admin_role:
type: string type: string
default: "admin" default: "admin"

View File

@ -149,7 +149,7 @@ configuration:
# - postgres_superusers # - postgres_superusers
protected_role_names: protected_role_names:
- admin - admin
# role_deprecation_suffix: "_delete_me" # role_deletion_suffix: "_deleted"
team_admin_role: admin team_admin_role: admin
team_api_role_configuration: team_api_role_configuration:
log_statement: all log_statement: all

View File

@ -1405,7 +1405,7 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
}, },
}, },
}, },
"role_deprecation_suffix": { "role_deletion_suffix": {
Type: "string", Type: "string",
}, },
"team_admin_role": { "team_admin_role": {

View File

@ -159,7 +159,7 @@ type TeamsAPIConfiguration struct {
PostgresSuperuserTeams []string `json:"postgres_superuser_teams,omitempty"` PostgresSuperuserTeams []string `json:"postgres_superuser_teams,omitempty"`
EnablePostgresTeamCRD bool `json:"enable_postgres_team_crd,omitempty"` EnablePostgresTeamCRD bool `json:"enable_postgres_team_crd,omitempty"`
EnablePostgresTeamCRDSuperusers bool `json:"enable_postgres_team_crd_superusers,omitempty"` EnablePostgresTeamCRDSuperusers bool `json:"enable_postgres_team_crd_superusers,omitempty"`
RoleDeprecationSuffix string `json:"role_deprecation_suffix,omitempty"` RoleDeletionSuffix string `json:"role_deletion_suffix,omitempty"`
} }
// LoggingRESTAPIConfiguration defines Logging API conf // LoggingRESTAPIConfiguration defines Logging API conf

View File

@ -131,8 +131,8 @@ func New(cfg Config, kubeClient k8sutil.KubernetesClient, pgSpec acidv1.Postgres
Services: make(map[PostgresRole]*v1.Service), Services: make(map[PostgresRole]*v1.Service),
Endpoints: make(map[PostgresRole]*v1.Endpoints)}, Endpoints: make(map[PostgresRole]*v1.Endpoints)},
userSyncStrategy: users.DefaultUserSyncStrategy{ userSyncStrategy: users.DefaultUserSyncStrategy{
PasswordEncryption: passwordEncryption, PasswordEncryption: passwordEncryption,
RoleDeprecationSuffix: cfg.OpConfig.RoleDeprecationSuffix}, RoleDeletionSuffix: cfg.OpConfig.RoleDeletionSuffix},
deleteOptions: metav1.DeleteOptions{PropagationPolicy: &deletePropagationPolicy}, deleteOptions: metav1.DeleteOptions{PropagationPolicy: &deletePropagationPolicy},
podEventsQueue: podEventsQueue, podEventsQueue: podEventsQueue,
KubeClient: kubeClient, KubeClient: kubeClient,

View File

@ -198,7 +198,7 @@ func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUser
rolname, rolpassword string rolname, rolpassword string
rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool
roloptions, memberof []string roloptions, memberof []string
roldeprecated bool roldeleted bool
) )
err := rows.Scan(&rolname, &rolpassword, &rolsuper, &rolinherit, err := rows.Scan(&rolname, &rolpassword, &rolsuper, &rolinherit,
&rolcreaterole, &rolcreatedb, &rolcanlogin, pq.Array(&roloptions), pq.Array(&memberof)) &rolcreaterole, &rolcreatedb, &rolcanlogin, pq.Array(&roloptions), pq.Array(&memberof))
@ -217,11 +217,11 @@ func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUser
parameters[fields[0]] = fields[1] parameters[fields[0]] = fields[1]
} }
if strings.HasSuffix(rolname, c.OpConfig.RoleDeprecationSuffix) { if strings.HasSuffix(rolname, c.OpConfig.RoleDeletionSuffix) {
roldeprecated = true roldeleted = true
} }
users[rolname] = spec.PgUser{Name: rolname, Password: rolpassword, Flags: flags, MemberOf: memberof, Parameters: parameters, Deprecated: roldeprecated} users[rolname] = spec.PgUser{Name: rolname, Password: rolpassword, Flags: flags, MemberOf: memberof, Parameters: parameters, Deleted: roldeleted}
} }
return users, nil return users, nil

View File

@ -551,16 +551,16 @@ func (c *Cluster) syncRoles() (err error) {
} }
}() }()
// mapping between deprecated and original role name // mapping between original role name and with deletion suffix
deprecatedUsers := map[string]string{} deletedUsers := map[string]string{}
// create list of database roles to query // create list of database roles to query
for _, u := range c.pgUsers { for _, u := range c.pgUsers {
userNames = append(userNames, u.Name) userNames = append(userNames, u.Name)
// add team member role name with rename suffix in case we need to rename it back // add team member role name with rename suffix in case we need to rename it back
if u.Origin == spec.RoleOriginTeamsAPI { if u.Origin == spec.RoleOriginTeamsAPI {
deprecatedUsers[u.Name+c.OpConfig.RoleDeprecationSuffix] = u.Name deletedUsers[u.Name+c.OpConfig.RoleDeletionSuffix] = u.Name
userNames = append(userNames, u.Name+c.OpConfig.RoleDeprecationSuffix) userNames = append(userNames, u.Name+c.OpConfig.RoleDeletionSuffix)
} }
} }
@ -588,12 +588,12 @@ func (c *Cluster) syncRoles() (err error) {
return fmt.Errorf("error getting users from the database: %v", err) return fmt.Errorf("error getting users from the database: %v", err)
} }
// update pgUsers where a deprecated role was found // update pgUsers where a deleted role was found
// so that they are skipped in ProduceSyncRequests // so that they are skipped in ProduceSyncRequests
for _, dbUser := range dbUsers { for _, dbUser := range dbUsers {
if originalUser, exists := deprecatedUsers[dbUser.Name]; exists { if originalUser, exists := deletedUsers[dbUser.Name]; exists {
recreatedUser := c.pgUsers[originalUser] recreatedUser := c.pgUsers[originalUser]
recreatedUser.Deprecated = true recreatedUser.Deleted = true
c.pgUsers[originalUser] = recreatedUser c.pgUsers[originalUser] = recreatedUser
} }
} }

View File

@ -180,7 +180,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.PostgresSuperuserTeams = fromCRD.TeamsAPI.PostgresSuperuserTeams result.PostgresSuperuserTeams = fromCRD.TeamsAPI.PostgresSuperuserTeams
result.EnablePostgresTeamCRD = fromCRD.TeamsAPI.EnablePostgresTeamCRD result.EnablePostgresTeamCRD = fromCRD.TeamsAPI.EnablePostgresTeamCRD
result.EnablePostgresTeamCRDSuperusers = fromCRD.TeamsAPI.EnablePostgresTeamCRDSuperusers result.EnablePostgresTeamCRDSuperusers = fromCRD.TeamsAPI.EnablePostgresTeamCRDSuperusers
result.RoleDeprecationSuffix = util.Coalesce(fromCRD.TeamsAPI.RoleDeprecationSuffix, "_delete_me") result.RoleDeletionSuffix = util.Coalesce(fromCRD.TeamsAPI.RoleDeletionSuffix, "_deleted")
// logging REST API config // logging REST API config
result.APIPort = util.CoalesceInt(fromCRD.LoggingRESTAPI.APIPort, 8080) result.APIPort = util.CoalesceInt(fromCRD.LoggingRESTAPI.APIPort, 8080)

View File

@ -54,7 +54,7 @@ type PgUser struct {
MemberOf []string `yaml:"inrole"` MemberOf []string `yaml:"inrole"`
Parameters map[string]string `yaml:"db_parameters"` Parameters map[string]string `yaml:"db_parameters"`
AdminRole string `yaml:"admin_role"` AdminRole string `yaml:"admin_role"`
Deprecated bool `yaml:"deprecated"` Deleted bool `yaml:"deleted"`
} }
func (user *PgUser) Valid() bool { func (user *PgUser) Valid() bool {

View File

@ -176,7 +176,7 @@ type Config struct {
EnableTeamsAPI bool `name:"enable_teams_api" default:"true"` EnableTeamsAPI bool `name:"enable_teams_api" default:"true"`
EnableTeamSuperuser bool `name:"enable_team_superuser" default:"false"` EnableTeamSuperuser bool `name:"enable_team_superuser" default:"false"`
TeamAdminRole string `name:"team_admin_role" default:"admin"` TeamAdminRole string `name:"team_admin_role" default:"admin"`
RoleDeprecationSuffix string `name:"role_deprecation_suffix,omitempty" default:"_delete_me"` RoleDeletionSuffix string `name:"role_deletion_suffix,omitempty" default:"_deleted"`
EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"` EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"`
EnablePostgresTeamCRD bool `name:"enable_postgres_team_crd" default:"false"` EnablePostgresTeamCRD bool `name:"enable_postgres_team_crd" default:"false"`
EnablePostgresTeamCRDSuperusers bool `name:"enable_postgres_team_crd_superusers" default:"false"` EnablePostgresTeamCRDSuperusers bool `name:"enable_postgres_team_crd_superusers" default:"false"`

View File

@ -30,8 +30,8 @@ const (
// an existing roles of another role membership, nor it removes the already assigned flag // an existing roles of another role membership, nor it removes the already assigned flag
// (except for the NOLOGIN). TODO: process other NOflags, i.e. NOSUPERUSER correctly. // (except for the NOLOGIN). TODO: process other NOflags, i.e. NOSUPERUSER correctly.
type DefaultUserSyncStrategy struct { type DefaultUserSyncStrategy struct {
PasswordEncryption string PasswordEncryption string
RoleDeprecationSuffix string RoleDeletionSuffix string
} }
// ProduceSyncRequests figures out the types of changes that need to happen with the given users. // ProduceSyncRequests figures out the types of changes that need to happen with the given users.
@ -40,7 +40,7 @@ func (strategy DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserM
var reqs []spec.PgSyncUserRequest var reqs []spec.PgSyncUserRequest
for name, newUser := range newUsers { for name, newUser := range newUsers {
if newUser.Deprecated { if newUser.Deleted {
continue continue
} }
dbUser, exists := dbUsers[name] dbUser, exists := dbUsers[name]
@ -79,10 +79,10 @@ func (strategy DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserM
// but team roles will be renamed and denied from LOGIN // but team roles will be renamed and denied from LOGIN
for name, dbUser := range dbUsers { for name, dbUser := range dbUsers {
if _, exists := newUsers[name]; !exists { if _, exists := newUsers[name]; !exists {
// toggle LOGIN flag based on role deprecation // toggle LOGIN flag based on role deletion
userFlags := make([]string, len(dbUser.Flags)) userFlags := make([]string, len(dbUser.Flags))
userFlags = append(userFlags, dbUser.Flags...) userFlags = append(userFlags, dbUser.Flags...)
if dbUser.Deprecated { if dbUser.Deleted {
dbUser.Flags = util.StringSliceReplaceElement(dbUser.Flags, constants.RoleFlagNoLogin, constants.RoleFlagLogin) dbUser.Flags = util.StringSliceReplaceElement(dbUser.Flags, constants.RoleFlagNoLogin, constants.RoleFlagLogin)
} else { } else {
dbUser.Flags = util.StringSliceReplaceElement(dbUser.Flags, constants.RoleFlagLogin, constants.RoleFlagNoLogin) dbUser.Flags = util.StringSliceReplaceElement(dbUser.Flags, constants.RoleFlagLogin, constants.RoleFlagNoLogin)
@ -156,11 +156,11 @@ func (strategy DefaultUserSyncStrategy) alterPgUserSet(user spec.PgUser, db *sql
func (strategy DefaultUserSyncStrategy) alterPgUserRename(user spec.PgUser, db *sql.DB) error { func (strategy DefaultUserSyncStrategy) alterPgUserRename(user spec.PgUser, db *sql.DB) error {
var query string var query string
if user.Deprecated { if user.Deleted {
newName := strings.TrimSuffix(user.Name, strategy.RoleDeprecationSuffix) newName := strings.TrimSuffix(user.Name, strategy.RoleDeletionSuffix)
query = fmt.Sprintf(alterUserRenameSQL, user.Name, newName, "") query = fmt.Sprintf(alterUserRenameSQL, user.Name, newName, "")
} else { } else {
query = fmt.Sprintf(alterUserRenameSQL, user.Name, user.Name, strategy.RoleDeprecationSuffix) query = fmt.Sprintf(alterUserRenameSQL, user.Name, user.Name, strategy.RoleDeletionSuffix)
} }
if _, err := db.Exec(query); err != nil { if _, err := db.Exec(query); err != nil {