make suffix configurable and add deprecated field to pgUser struct

This commit is contained in:
Felix Kunde
2021-04-23 09:57:34 +02:00
parent eb20c5829b
commit 1e2dbe4712
18 changed files with 89 additions and 30 deletions
+15 -10
View File
@@ -130,7 +130,9 @@ func New(cfg Config, kubeClient k8sutil.KubernetesClient, pgSpec acidv1.Postgres
Secrets: make(map[types.UID]*v1.Secret),
Services: make(map[PostgresRole]*v1.Service),
Endpoints: make(map[PostgresRole]*v1.Endpoints)},
userSyncStrategy: users.DefaultUserSyncStrategy{PasswordEncryption: passwordEncryption},
userSyncStrategy: users.DefaultUserSyncStrategy{
PasswordEncryption: passwordEncryption,
RoleDeprecationSuffix: cfg.OpConfig.RoleDeprecationSuffix},
deleteOptions: metav1.DeleteOptions{PropagationPolicy: &deletePropagationPolicy},
podEventsQueue: podEventsQueue,
KubeClient: kubeClient,
@@ -191,6 +193,14 @@ func (c *Cluster) isNewCluster() bool {
func (c *Cluster) initUsers() error {
c.setProcessName("initializing users")
// save current state of pgUsers to check for deleted roles later
c.pgUsersCache = map[string]spec.PgUser{}
for k, v := range c.pgUsers {
if v.Origin == spec.RoleOriginTeamsAPI {
c.pgUsersCache[k] = v
}
}
// clear our the previous state of the cluster users (in case we are
// running a sync).
c.systemUsers = map[string]spec.PgUser{}
@@ -644,12 +654,6 @@ func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error {
needReplicaConnectionPoolerWorker(&newSpec.Spec)
if !sameUsers || needConnectionPooler {
c.logger.Debugf("initialize users")
// save current state of pgUsers to check for deleted roles later
c.pgUsersCache = map[string]spec.PgUser{}
for k, v := range c.pgUsers {
c.pgUsersCache[k] = v
}
if err := c.initUsers(); err != nil {
c.logger.Errorf("could not init users: %v", err)
updateFailed = true
@@ -1140,6 +1144,7 @@ func (c *Cluster) initTeamMembers(teamID string, isPostgresSuperuserTeam bool) e
Flags: flags,
MemberOf: memberOf,
Parameters: c.OpConfig.TeamAPIRoleConfiguration,
Deprecated: false,
}
if currentRole, present := c.pgUsers[username]; present {
@@ -1170,7 +1175,7 @@ func (c *Cluster) initHumanUsers() error {
for _, superuserTeam := range superuserTeams {
err := c.initTeamMembers(superuserTeam, true)
if err != nil {
return fmt.Errorf("Cannot initialize members for team %q of Postgres superusers: %v", superuserTeam, err)
return fmt.Errorf("cannot initialize members for team %q of Postgres superusers: %v", superuserTeam, err)
}
if superuserTeam == c.Spec.TeamID {
clusterIsOwnedBySuperuserTeam = true
@@ -1183,7 +1188,7 @@ func (c *Cluster) initHumanUsers() error {
if !(util.SliceContains(superuserTeams, additionalTeam)) {
err := c.initTeamMembers(additionalTeam, false)
if err != nil {
return fmt.Errorf("Cannot initialize members for additional team %q for cluster owned by %q: %v", additionalTeam, c.Spec.TeamID, err)
return fmt.Errorf("cannot initialize members for additional team %q for cluster owned by %q: %v", additionalTeam, c.Spec.TeamID, err)
}
}
}
@@ -1196,7 +1201,7 @@ func (c *Cluster) initHumanUsers() error {
err := c.initTeamMembers(c.Spec.TeamID, false)
if err != nil {
return fmt.Errorf("Cannot initialize members for team %q who owns the Postgres cluster: %v", c.Spec.TeamID, err)
return fmt.Errorf("cannot initialize members for team %q who owns the Postgres cluster: %v", c.Spec.TeamID, err)
}
return nil
+6 -1
View File
@@ -198,6 +198,7 @@ func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUser
rolname, rolpassword string
rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool
roloptions, memberof []string
roldeprecated bool
)
err := rows.Scan(&rolname, &rolpassword, &rolsuper, &rolinherit,
&rolcreaterole, &rolcreatedb, &rolcanlogin, pq.Array(&roloptions), pq.Array(&memberof))
@@ -216,7 +217,11 @@ func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUser
parameters[fields[0]] = fields[1]
}
users[rolname] = spec.PgUser{Name: rolname, Password: rolpassword, Flags: flags, MemberOf: memberof, Parameters: parameters}
if strings.HasSuffix(rolname, c.OpConfig.RoleDeprecationSuffix) {
roldeprecated = true
}
users[rolname] = spec.PgUser{Name: rolname, Password: rolpassword, Flags: flags, MemberOf: memberof, Parameters: parameters, Deprecated: roldeprecated}
}
return users, nil
+19 -11
View File
@@ -37,12 +37,6 @@ func (c *Cluster) Sync(newSpec *acidv1.Postgresql) error {
}
}()
// save current state of pgUsers to check for deleted roles later
c.pgUsersCache = map[string]spec.PgUser{}
for k, v := range c.pgUsers {
c.pgUsersCache[k] = v
}
if err = c.initUsers(); err != nil {
err = fmt.Errorf("could not init users: %v", err)
return err
@@ -582,25 +576,29 @@ func (c *Cluster) syncRoles() (err error) {
}
}()
// mapping between deprecated and original role name
deprecatedUsers := map[string]string{}
// create list of database roles to query
for _, u := range c.pgUsers {
userNames = append(userNames, u.Name)
// add team member role name with rename suffix in case we need to rename it back
if u.Origin == spec.RoleOriginTeamsAPI {
userNames = append(userNames, u.Name+constants.RoleRenameSuffix)
deprecatedUsers[u.Name+c.OpConfig.RoleDeprecationSuffix] = u.Name
userNames = append(userNames, u.Name+c.OpConfig.RoleDeprecationSuffix)
}
}
// add removed additional team members from cache
// add team members that exist only in cache
// to trigger a rename of the role in ProduceSyncRequests
for _, cachedUser := range c.pgUsersCache {
if cachedUser.Origin != spec.RoleOriginTeamsAPI {
continue
}
if _, exists := c.pgUsers[cachedUser.Name]; !exists {
userNames = append(userNames, cachedUser.Name)
}
}
// add pooler user to list of pgUsers, too
// to check if the pooler user exists or has to be created
if needMasterConnectionPooler(&c.Spec) || needReplicaConnectionPooler(&c.Spec) {
connectionPoolerUser := c.systemUsers[constants.ConnectionPoolerUserKeyName]
userNames = append(userNames, connectionPoolerUser.Name)
@@ -615,6 +613,16 @@ func (c *Cluster) syncRoles() (err error) {
return fmt.Errorf("error getting users from the database: %v", err)
}
// update pgUsers where a deprecated role was found
// so that they are skipped in ProduceSyncRequests
for _, dbUser := range dbUsers {
if originalUser, exists := deprecatedUsers[dbUser.Name]; exists {
recreatedUser := c.pgUsers[originalUser]
recreatedUser.Deprecated = true
c.pgUsers[originalUser] = recreatedUser
}
}
pgSyncRequests := c.userSyncStrategy.ProduceSyncRequests(dbUsers, c.pgUsers)
if err = c.userSyncStrategy.ExecuteSyncRequests(pgSyncRequests, c.pgDb); err != nil {
return fmt.Errorf("error executing sync statements: %v", err)