mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-18 17:18:30 +02:00
cleanup on username mismatch if rotation was switched off
This commit is contained in:
+44
-28
@@ -620,6 +620,8 @@ func (c *Cluster) syncSecrets() error {
|
|||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
secret *v1.Secret
|
secret *v1.Secret
|
||||||
|
updateSecret bool
|
||||||
|
updateSecretMsg string
|
||||||
nextRotationDate time.Time
|
nextRotationDate time.Time
|
||||||
nextRotationDateStr string
|
nextRotationDateStr string
|
||||||
)
|
)
|
||||||
@@ -640,11 +642,6 @@ func (c *Cluster) syncSecrets() error {
|
|||||||
if secret, err = c.KubeClient.Secrets(secretSpec.Namespace).Get(context.TODO(), secretSpec.Name, metav1.GetOptions{}); err != nil {
|
if secret, err = c.KubeClient.Secrets(secretSpec.Namespace).Get(context.TODO(), secretSpec.Name, metav1.GetOptions{}); err != nil {
|
||||||
return fmt.Errorf("could not get current secret: %v", err)
|
return fmt.Errorf("could not get current secret: %v", err)
|
||||||
}
|
}
|
||||||
/*username := string(secret.Data["username"])
|
|
||||||
if secretUsername != username {
|
|
||||||
c.logger.Errorf("secret %s does not contain the role %s", secretSpec.Name, secretUsername)
|
|
||||||
continue
|
|
||||||
}*/
|
|
||||||
|
|
||||||
c.logger.Debugf("secret %s already exists, fetching its password", util.NameFromMeta(secret.ObjectMeta))
|
c.logger.Debugf("secret %s already exists, fetching its password", util.NameFromMeta(secret.ObjectMeta))
|
||||||
if secretUsername == c.systemUsers[constants.SuperuserKeyName].Name {
|
if secretUsername == c.systemUsers[constants.SuperuserKeyName].Name {
|
||||||
@@ -658,14 +655,10 @@ func (c *Cluster) syncSecrets() error {
|
|||||||
}
|
}
|
||||||
pwdUser := userMap[secretUsername]
|
pwdUser := userMap[secretUsername]
|
||||||
|
|
||||||
c.Secrets[secret.UID] = secret
|
|
||||||
|
|
||||||
// if this secret belongs to the infrastructure role and the password has changed - replace it in the secret
|
// if this secret belongs to the infrastructure role and the password has changed - replace it in the secret
|
||||||
if pwdUser.Password != string(secret.Data["password"]) && pwdUser.Origin == spec.RoleOriginInfrastructure {
|
if pwdUser.Password != string(secret.Data["password"]) && pwdUser.Origin == spec.RoleOriginInfrastructure {
|
||||||
c.logger.Debugf("updating the secret %s from the infrastructure roles", secretSpec.Name)
|
updateSecret = true
|
||||||
if _, err = c.KubeClient.Secrets(secretSpec.Namespace).Update(context.TODO(), secretSpec, metav1.UpdateOptions{}); err != nil {
|
updateSecretMsg = fmt.Sprintf("updating the secret %s from the infrastructure roles", secretSpec.Name)
|
||||||
return fmt.Errorf("could not update infrastructure role secret for role %q: %v", secretUsername, err)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// for non-infrastructure role - update the role with the password from the secret
|
// for non-infrastructure role - update the role with the password from the secret
|
||||||
pwdUser.Password = string(secret.Data["password"])
|
pwdUser.Password = string(secret.Data["password"])
|
||||||
@@ -674,26 +667,23 @@ func (c *Cluster) syncSecrets() error {
|
|||||||
|
|
||||||
// if password rotation is enabled update password and username if rotation interval has been passed
|
// if password rotation is enabled update password and username if rotation interval has been passed
|
||||||
if (c.OpConfig.EnablePasswordRotation && pwdUser.Origin != spec.RoleOriginInfrastructure && !pwdUser.IsDbOwner) ||
|
if (c.OpConfig.EnablePasswordRotation && pwdUser.Origin != spec.RoleOriginInfrastructure && !pwdUser.IsDbOwner) ||
|
||||||
util.SliceContains(c.Spec.UsersWithSecretRotation, pwdUser.Name) || util.SliceContains(c.Spec.UsersWithInPlaceSecretRotation, pwdUser.Name) {
|
util.SliceContains(c.Spec.UsersWithSecretRotation, secretUsername) || util.SliceContains(c.Spec.UsersWithInPlaceSecretRotation, secretUsername) {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
|
|
||||||
// initialize password rotation setting first rotation date
|
// initialize password rotation setting first rotation date
|
||||||
nextRotationDateStr = string(secret.Data["nextRotation"])
|
nextRotationDateStr = string(secret.Data["nextRotation"])
|
||||||
if nextRotationDate, err = time.Parse("2006-01-02 15:04:05", nextRotationDateStr); err != nil {
|
if nextRotationDate, err = time.Parse("2006-01-02 15:04:05", nextRotationDateStr); err != nil {
|
||||||
nextRotationDate, nextRotationDateStr = c.getNextRotationDate(currentTime)
|
nextRotationDate, nextRotationDateStr = c.getNextRotationDate(currentTime)
|
||||||
c.logger.Warningf("rotation date not found in secret %q. Setting it to %s", secretSpec.Name, nextRotationDateStr)
|
|
||||||
secret.Data["nextRotation"] = []byte(nextRotationDateStr)
|
secret.Data["nextRotation"] = []byte(nextRotationDateStr)
|
||||||
if _, err = c.KubeClient.Secrets(secretSpec.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
|
updateSecret = true
|
||||||
c.logger.Warningf("could not update secret %q: %v", secretSpec.Name, err)
|
updateSecretMsg = fmt.Sprintf("rotation date not found in secret %q. Setting it to %s", secretSpec.Name, nextRotationDateStr)
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentTime.After(nextRotationDate) {
|
if currentTime.After(nextRotationDate) {
|
||||||
if !util.SliceContains(c.Spec.UsersWithInPlaceSecretRotation, pwdUser.Name) {
|
if !util.SliceContains(c.Spec.UsersWithInPlaceSecretRotation, secretUsername) {
|
||||||
retentionUsers = append(retentionUsers, pwdUser.Name)
|
retentionUsers = append(retentionUsers, secretUsername)
|
||||||
newRotationUsername := pwdUser.Name + currentTime.Format("060102")
|
newRotationUsername := secretUsername + currentTime.Format("060102")
|
||||||
pwdUser.MemberOf = []string{pwdUser.Name}
|
pwdUser.MemberOf = []string{secretUsername}
|
||||||
pwdUser.Name = newRotationUsername
|
pwdUser.Name = newRotationUsername
|
||||||
rotationUsers[newRotationUsername] = pwdUser
|
rotationUsers[newRotationUsername] = pwdUser
|
||||||
secret.Data["username"] = []byte(newRotationUsername)
|
secret.Data["username"] = []byte(newRotationUsername)
|
||||||
@@ -703,15 +693,30 @@ func (c *Cluster) syncSecrets() error {
|
|||||||
_, nextRotationDateStr = c.getNextRotationDate(nextRotationDate)
|
_, nextRotationDateStr = c.getNextRotationDate(nextRotationDate)
|
||||||
secret.Data["nextRotation"] = []byte(nextRotationDateStr)
|
secret.Data["nextRotation"] = []byte(nextRotationDateStr)
|
||||||
|
|
||||||
c.logger.Debugf("updating secret %q due to password rotation - next rotation date: %s", secretSpec.Name, nextRotationDateStr)
|
updateSecret = true
|
||||||
if _, err = c.KubeClient.Secrets(secretSpec.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
|
updateSecretMsg = fmt.Sprintf("updating secret %q due to password rotation - next rotation date: %s", secretSpec.Name, nextRotationDateStr)
|
||||||
c.logger.Warningf("could not update secret %q: %v", secretSpec.Name, err)
|
}
|
||||||
continue
|
} else {
|
||||||
}
|
// username might not match if password rotation has been disabled again
|
||||||
|
if secretUsername != string(secret.Data["username"]) {
|
||||||
|
retentionUsers = append(retentionUsers, secretUsername)
|
||||||
|
secret.Data["username"] = []byte(secretUsername)
|
||||||
|
secret.Data["password"] = []byte(util.RandomPassword(constants.PasswordLength))
|
||||||
|
secret.Data["nextRotation"] = []byte{}
|
||||||
|
updateSecret = true
|
||||||
|
updateSecretMsg = fmt.Sprintf("secret %s does not contain the role %s - updating username and resetting password", secretSpec.Name, secretUsername)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Secrets[secret.UID] = secret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if updateSecret {
|
||||||
|
c.logger.Debugln(updateSecretMsg)
|
||||||
|
if _, err = c.KubeClient.Secrets(secretSpec.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
|
||||||
|
c.logger.Warningf("could not update secret %q: %v", secretSpec.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Secrets[secret.UID] = secret
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("could not create secret for user %s: in namespace %s: %v", secretUsername, secretSpec.Namespace, err)
|
return fmt.Errorf("could not create secret for user %s: in namespace %s: %v", secretUsername, secretSpec.Namespace, err)
|
||||||
}
|
}
|
||||||
@@ -727,6 +732,17 @@ func (c *Cluster) syncSecrets() error {
|
|||||||
if err = c.userSyncStrategy.ExecuteSyncRequests(pgSyncRequests, c.pgDb); err != nil {
|
if err = c.userSyncStrategy.ExecuteSyncRequests(pgSyncRequests, c.pgDb); err != nil {
|
||||||
return fmt.Errorf("error creating database roles for password rotation: %v", err)
|
return fmt.Errorf("error creating database roles for password rotation: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := c.closeDbConn(); err != nil {
|
||||||
|
c.logger.Errorf("could not close database connection during secret rotation: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove rotation users that exceed the retention interval
|
||||||
|
if len(retentionUsers) > 0 {
|
||||||
|
err = c.initDbConn()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not init db connection: %v", err)
|
||||||
|
}
|
||||||
if err = c.cleanupRotatedUsers(retentionUsers, c.pgDb); err != nil {
|
if err = c.cleanupRotatedUsers(retentionUsers, c.pgDb); err != nil {
|
||||||
return fmt.Errorf("error creating database roles for password rotation: %v", err)
|
return fmt.Errorf("error creating database roles for password rotation: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user