rename only team users using a cache

This commit is contained in:
Felix Kunde 2021-04-15 16:59:03 +02:00
parent 2efea31cfa
commit 7164adb74d
3 changed files with 38 additions and 22 deletions

View File

@ -74,6 +74,7 @@ type Cluster struct {
eventRecorder record.EventRecorder
patroni patroni.Interface
pgUsers map[string]spec.PgUser
pgUsersCache map[string]spec.PgUser
systemUsers map[string]spec.PgUser
podSubscribers map[spec.NamespacedName]chan PodEvent
podSubscribersMu sync.RWMutex
@ -642,7 +643,15 @@ func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error {
needConnectionPooler := needMasterConnectionPoolerWorker(&newSpec.Spec) ||
needReplicaConnectionPoolerWorker(&newSpec.Spec)
if !sameUsers || needConnectionPooler {
c.logger.Debugf("syncing secrets")
c.logger.Debugf("initialize users")
// save current state of pgUsers to check for deleted roles later
if len(c.pgUsers) > 0 {
usersCache := map[string]spec.PgUser{}
for k, v := range c.pgUsers {
usersCache[k] = v
}
c.pgUsersCache = usersCache
}
if err := c.initUsers(); err != nil {
c.logger.Errorf("could not init users: %v", err)
updateFailed = true

View File

@ -24,8 +24,7 @@ const (
JOIN pg_catalog.pg_authid b ON (m.roleid = b.oid)
WHERE m.member = a.oid) as memberof
FROM pg_catalog.pg_authid a LEFT JOIN pg_db_role_setting s ON (a.oid = s.setrole AND s.setdatabase = 0::oid)
WHERE a.rolname != ALL($1)
AND (rolcanlogin OR (NOT rolcanlogin AND rolpassword IS NOT NULL))
WHERE a.rolname = ANY($1)
ORDER BY 1;`
getDatabasesSQL = `SELECT datname, pg_get_userbyid(datdba) AS owner FROM pg_database;`

View File

@ -37,6 +37,14 @@ func (c *Cluster) Sync(newSpec *acidv1.Postgresql) error {
}
}()
// save current state of pgUsers to check for deleted roles later
if len(c.pgUsers) > 0 {
usersCache := map[string]spec.PgUser{}
for k, v := range c.pgUsers {
usersCache[k] = v
}
c.pgUsersCache = usersCache
}
if err = c.initUsers(); err != nil {
err = fmt.Errorf("could not init users: %v", err)
return err
@ -557,8 +565,8 @@ func (c *Cluster) syncRoles() (err error) {
c.setProcessName("syncing roles")
var (
dbUsers spec.PgUserMap
systemUserNames []string
dbUsers spec.PgUserMap
userNames []string
)
err = c.initDbConn()
@ -576,35 +584,35 @@ func (c *Cluster) syncRoles() (err error) {
}
}()
for _, u := range c.systemUsers {
systemUserNames = append(systemUserNames, u.Name)
for _, u := range c.pgUsers {
userNames = append(userNames, u.Name)
}
dbUsers, err = c.readPgUsersFromDatabase(systemUserNames)
if err != nil {
return fmt.Errorf("error getting users from the database: %v", err)
// add removed additional team members from 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)
}
}
if needMasterConnectionPooler(&c.Spec) || needReplicaConnectionPooler(&c.Spec) {
connectionPoolerUser := c.systemUsers[constants.ConnectionPoolerUserKeyName]
userNames = append(userNames, connectionPoolerUser.Name)
// check if pooler user exists in the database
dbPoolerUserMap, err := c.readPgUsersFromDatabase([]string{})
if err != nil {
return fmt.Errorf("error getting pooler user from the database: %v", err)
}
// if yes add role to dbUsers list so that there will be no add request
if _, exists := dbPoolerUserMap[connectionPoolerUser.Name]; exists {
dbUsers[connectionPoolerUser.Name] = dbPoolerUserMap[connectionPoolerUser.Name]
}
// add to pgUsers to trigger add request in case no pooler user exists in DB
if _, exists := c.pgUsers[connectionPoolerUser.Name]; !exists {
c.pgUsers[connectionPoolerUser.Name] = connectionPoolerUser
}
}
dbUsers, err = c.readPgUsersFromDatabase(userNames)
if err != nil {
return fmt.Errorf("error getting users from the database: %v", err)
}
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)