mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-18 16:05:41 +02:00
do not reset secrets of standby clusters (#3044)
* do not reset secrets of standby clusters align error message with unit test * check for other env vars, too
This commit is contained in:
+53
-31
@@ -1174,42 +1174,15 @@ func (c *Cluster) updateSecret(
|
||||
pwdUser := userMap[userKey]
|
||||
secretName := util.NameFromMeta(secret.ObjectMeta)
|
||||
|
||||
// if password rotation is enabled update password and username if rotation interval has been passed
|
||||
// rotation can be enabled globally or via the manifest (excluding the Postgres superuser)
|
||||
rotationEnabledInManifest := secretUsername != constants.SuperuserKeyName &&
|
||||
(slices.Contains(c.Spec.UsersWithSecretRotation, secretUsername) ||
|
||||
slices.Contains(c.Spec.UsersWithInPlaceSecretRotation, secretUsername))
|
||||
|
||||
// globally enabled rotation is only allowed for manifest and bootstrapped roles
|
||||
allowedRoleTypes := []spec.RoleOrigin{spec.RoleOriginManifest, spec.RoleOriginBootstrap}
|
||||
rotationAllowed := !pwdUser.IsDbOwner && slices.Contains(allowedRoleTypes, pwdUser.Origin) && c.Spec.StandbyCluster == nil
|
||||
|
||||
// users can ignore any kind of rotation
|
||||
isIgnoringRotation := slices.Contains(c.Spec.UsersIgnoringSecretRotation, secretUsername)
|
||||
|
||||
if ((c.OpConfig.EnablePasswordRotation && rotationAllowed) || rotationEnabledInManifest) && !isIgnoringRotation {
|
||||
updateSecretMsg, err = c.rotatePasswordInSecret(secret, secretUsername, pwdUser.Origin, currentTime, retentionUsers)
|
||||
// do not perform any rotation of reset for standby clusters
|
||||
if !isStandbyCluster(&c.Spec) {
|
||||
updateSecretMsg, err = c.checkForPasswordRotation(secret, secretUsername, pwdUser, retentionUsers, currentTime)
|
||||
if err != nil {
|
||||
c.logger.Warnf("password rotation failed for user %s: %v", secretUsername, err)
|
||||
return nil, fmt.Errorf("error while checking for password rotation: %v", err)
|
||||
}
|
||||
if updateSecretMsg != "" {
|
||||
updateSecret = true
|
||||
}
|
||||
} else {
|
||||
// username might not match if password rotation has been disabled again
|
||||
usernameFromSecret := string(secret.Data["username"])
|
||||
if secretUsername != usernameFromSecret {
|
||||
// handle edge case when manifest user conflicts with a user from prepared databases
|
||||
if strings.Replace(usernameFromSecret, "-", "_", -1) == strings.Replace(secretUsername, "-", "_", -1) {
|
||||
return nil, fmt.Errorf("could not update secret because of user name mismatch: expected: %s, got: %s", secretUsername, usernameFromSecret)
|
||||
}
|
||||
*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 does not contain the role %s - updating username and resetting password", secretUsername)
|
||||
}
|
||||
}
|
||||
|
||||
// if this secret belongs to the infrastructure role and the password has changed - replace it in the secret
|
||||
@@ -1256,6 +1229,55 @@ func (c *Cluster) updateSecret(
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
func (c *Cluster) checkForPasswordRotation(
|
||||
secret *v1.Secret,
|
||||
secretUsername string,
|
||||
pwdUser spec.PgUser,
|
||||
retentionUsers *[]string,
|
||||
currentTime time.Time) (string, error) {
|
||||
|
||||
var (
|
||||
passwordRotationMsg string
|
||||
err error
|
||||
)
|
||||
|
||||
// if password rotation is enabled update password and username if rotation interval has been passed
|
||||
// rotation can be enabled globally or via the manifest (excluding the Postgres superuser)
|
||||
rotationEnabledInManifest := secretUsername != constants.SuperuserKeyName &&
|
||||
(slices.Contains(c.Spec.UsersWithSecretRotation, secretUsername) ||
|
||||
slices.Contains(c.Spec.UsersWithInPlaceSecretRotation, secretUsername))
|
||||
|
||||
// globally enabled rotation is only allowed for manifest and bootstrapped roles
|
||||
allowedRoleTypes := []spec.RoleOrigin{spec.RoleOriginManifest, spec.RoleOriginBootstrap}
|
||||
rotationAllowed := !pwdUser.IsDbOwner && slices.Contains(allowedRoleTypes, pwdUser.Origin)
|
||||
|
||||
// users can ignore any kind of rotation
|
||||
isIgnoringRotation := slices.Contains(c.Spec.UsersIgnoringSecretRotation, secretUsername)
|
||||
|
||||
if ((c.OpConfig.EnablePasswordRotation && rotationAllowed) || rotationEnabledInManifest) && !isIgnoringRotation {
|
||||
passwordRotationMsg, err = c.rotatePasswordInSecret(secret, secretUsername, pwdUser.Origin, currentTime, retentionUsers)
|
||||
if err != nil {
|
||||
c.logger.Warnf("password rotation failed for user %s: %v", secretUsername, err)
|
||||
}
|
||||
} else {
|
||||
// username might not match if password rotation has been disabled again
|
||||
usernameFromSecret := string(secret.Data["username"])
|
||||
if secretUsername != usernameFromSecret {
|
||||
// handle edge case when manifest user conflicts with a user from prepared databases
|
||||
if strings.Replace(usernameFromSecret, "-", "_", -1) == strings.Replace(secretUsername, "-", "_", -1) {
|
||||
return "", fmt.Errorf("could not update secret because of user name mismatch: expected: %s, got: %s", secretUsername, usernameFromSecret)
|
||||
}
|
||||
*retentionUsers = append(*retentionUsers, secretUsername)
|
||||
secret.Data["username"] = []byte(secretUsername)
|
||||
secret.Data["password"] = []byte(util.RandomPassword(constants.PasswordLength))
|
||||
secret.Data["nextRotation"] = []byte{}
|
||||
passwordRotationMsg = fmt.Sprintf("secret does not contain the role %s - updating username and resetting password", secretUsername)
|
||||
}
|
||||
}
|
||||
|
||||
return passwordRotationMsg, nil
|
||||
}
|
||||
|
||||
func (c *Cluster) rotatePasswordInSecret(
|
||||
secret *v1.Secret,
|
||||
secretUsername string,
|
||||
|
||||
Reference in New Issue
Block a user