grant db owners to cron_admin
This commit is contained in:
parent
ca0c27a51b
commit
89801ef30a
|
|
@ -130,6 +130,8 @@ spec:
|
||||||
users:
|
users:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
cron_admin_username:
|
||||||
|
type: string
|
||||||
enable_password_rotation:
|
enable_password_rotation:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,14 @@ configGeneral:
|
||||||
|
|
||||||
# parameters describing Postgres users
|
# parameters describing Postgres users
|
||||||
configUsers:
|
configUsers:
|
||||||
|
# username used to grant rights to set up and maintain cron jobs to database owners
|
||||||
|
cron_admin_username: cron_admin
|
||||||
|
# enable password rotation for app users that are not database owners
|
||||||
|
enable_password_rotation: false
|
||||||
|
# rotation interval for updating credentials in K8s secrets of app users
|
||||||
|
password_rotation_interval: 90
|
||||||
|
# retention interval to keep rotation users
|
||||||
|
password_rotation_user_retention: 180
|
||||||
# postgres username used for replication between instances
|
# postgres username used for replication between instances
|
||||||
replication_username: standby
|
replication_username: standby
|
||||||
# postgres superuser name to be created by initdb
|
# postgres superuser name to be created by initdb
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,13 @@ under the `users` key.
|
||||||
Postgres username used for replication between instances. The default is
|
Postgres username used for replication between instances. The default is
|
||||||
`standby`.
|
`standby`.
|
||||||
|
|
||||||
|
* **cron_admin_username**
|
||||||
|
Specifies the role that owns rights to set up cron jobs with `pg_cron`
|
||||||
|
extension inside the `postgres` database. The must be pre-configured in the
|
||||||
|
docker image. In Spilo this role is called `cron_admin`. This role will
|
||||||
|
become a member of all database owners so that they can set up cron jobs
|
||||||
|
e.g. as part of a migration script. Default is `empty`.
|
||||||
|
|
||||||
* **enable_password_rotation**
|
* **enable_password_rotation**
|
||||||
For all `LOGIN` roles that are not database owners the operator can rotate
|
For all `LOGIN` roles that are not database owners the operator can rotate
|
||||||
credentials in the corresponding K8s secrets by replacing the username and
|
credentials in the corresponding K8s secrets by replacing the username and
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ data:
|
||||||
# connection_pooler_schema: "pooler"
|
# connection_pooler_schema: "pooler"
|
||||||
# connection_pooler_user: "pooler"
|
# connection_pooler_user: "pooler"
|
||||||
crd_categories: "all"
|
crd_categories: "all"
|
||||||
|
# cron_admin_username: "cron_admin"
|
||||||
# custom_service_annotations: "keyx:valuez,keya:valuea"
|
# custom_service_annotations: "keyx:valuez,keya:valuea"
|
||||||
# custom_pod_annotations: "keya:valuea,keyb:valueb"
|
# custom_pod_annotations: "keya:valuea,keyb:valueb"
|
||||||
db_hosted_zone: db.example.com
|
db_hosted_zone: db.example.com
|
||||||
|
|
@ -109,7 +110,7 @@ data:
|
||||||
# pod_service_account_role_binding_definition: ""
|
# pod_service_account_role_binding_definition: ""
|
||||||
pod_terminate_grace_period: 5m
|
pod_terminate_grace_period: 5m
|
||||||
# postgres_superuser_teams: "postgres_superusers"
|
# postgres_superuser_teams: "postgres_superusers"
|
||||||
# protected_role_names: "admin"
|
# protected_role_names: "admin,cron_admin"
|
||||||
ready_wait_interval: 3s
|
ready_wait_interval: 3s
|
||||||
ready_wait_timeout: 30s
|
ready_wait_timeout: 30s
|
||||||
repair_period: 5m
|
repair_period: 5m
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,8 @@ spec:
|
||||||
users:
|
users:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
cron_admin_username:
|
||||||
|
type: string
|
||||||
enable_password_rotation:
|
enable_password_rotation:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ configuration:
|
||||||
password_rotation_user_retention: 180
|
password_rotation_user_retention: 180
|
||||||
replication_username: standby
|
replication_username: standby
|
||||||
super_username: postgres
|
super_username: postgres
|
||||||
|
# cron_admin_username: cron_admin
|
||||||
major_version_upgrade:
|
major_version_upgrade:
|
||||||
major_version_upgrade_mode: "off"
|
major_version_upgrade_mode: "off"
|
||||||
# major_version_upgrade_team_allow_list:
|
# major_version_upgrade_team_allow_list:
|
||||||
|
|
@ -163,6 +164,7 @@ configuration:
|
||||||
# - postgres_superusers
|
# - postgres_superusers
|
||||||
protected_role_names:
|
protected_role_names:
|
||||||
- admin
|
- admin
|
||||||
|
- cron_admin
|
||||||
role_deletion_suffix: "_deleted"
|
role_deletion_suffix: "_deleted"
|
||||||
team_admin_role: admin
|
team_admin_role: admin
|
||||||
team_api_role_configuration:
|
team_api_role_configuration:
|
||||||
|
|
|
||||||
|
|
@ -1142,6 +1142,18 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
|
||||||
"users": {
|
"users": {
|
||||||
Type: "object",
|
Type: "object",
|
||||||
Properties: map[string]apiextv1.JSONSchemaProps{
|
Properties: map[string]apiextv1.JSONSchemaProps{
|
||||||
|
"cron_admin_username": {
|
||||||
|
Type: "string",
|
||||||
|
},
|
||||||
|
"enable_password_rotation": {
|
||||||
|
Type: "boolean",
|
||||||
|
},
|
||||||
|
"password_rotation_interval": {
|
||||||
|
Type: "integer",
|
||||||
|
},
|
||||||
|
"password_rotation_user_retention": {
|
||||||
|
Type: "integer",
|
||||||
|
},
|
||||||
"replication_username": {
|
"replication_username": {
|
||||||
Type: "string",
|
Type: "string",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ type OperatorConfigurationList struct {
|
||||||
type PostgresUsersConfiguration struct {
|
type PostgresUsersConfiguration struct {
|
||||||
SuperUsername string `json:"super_username,omitempty"`
|
SuperUsername string `json:"super_username,omitempty"`
|
||||||
ReplicationUsername string `json:"replication_username,omitempty"`
|
ReplicationUsername string `json:"replication_username,omitempty"`
|
||||||
|
CronAdminUsername string `json:"cron_admin_username,omitempty"`
|
||||||
EnablePasswordRotation bool `json:"enable_password_rotation,omitempty"`
|
EnablePasswordRotation bool `json:"enable_password_rotation,omitempty"`
|
||||||
PasswordRotationInterval uint32 `json:"password_rotation_interval,omitempty"`
|
PasswordRotationInterval uint32 `json:"password_rotation_interval,omitempty"`
|
||||||
PasswordRotationUserRetention uint32 `json:"password_rotation_user_retention,omitempty"`
|
PasswordRotationUserRetention uint32 `json:"password_rotation_user_retention,omitempty"`
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,8 @@ func (c *Cluster) initUsers() error {
|
||||||
return fmt.Errorf("could not init human users: %v", err)
|
return fmt.Errorf("could not init human users: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.initCronAdmin()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1297,6 +1299,40 @@ func (c *Cluster) initRobotUsers() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) initCronAdmin() {
|
||||||
|
cronAdminName := c.OpConfig.CronAdminUsername
|
||||||
|
if cronAdminName == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
memberOf := make([]string, 0)
|
||||||
|
for username, pgUser := range c.pgUsers {
|
||||||
|
if pgUser.IsDbOwner {
|
||||||
|
memberOf = append(memberOf, username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(memberOf) > 1 {
|
||||||
|
namespace := c.Namespace
|
||||||
|
adminRole := ""
|
||||||
|
if c.OpConfig.EnableAdminRoleForUsers && cronAdminName != c.OpConfig.TeamAdminRole {
|
||||||
|
adminRole = c.OpConfig.TeamAdminRole
|
||||||
|
}
|
||||||
|
cronAdmin := spec.PgUser{
|
||||||
|
Origin: spec.RoleOriginSpilo,
|
||||||
|
MemberOf: memberOf,
|
||||||
|
Name: cronAdminName,
|
||||||
|
Namespace: namespace,
|
||||||
|
Flags: []string{constants.RoleFlagNoLogin},
|
||||||
|
AdminRole: adminRole,
|
||||||
|
}
|
||||||
|
if currentRole, present := c.pgUsers[cronAdminName]; present {
|
||||||
|
c.pgUsers[cronAdminName] = c.resolveNameConflict(¤tRole, &cronAdmin)
|
||||||
|
} else {
|
||||||
|
c.pgUsers[cronAdminName] = cronAdmin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Cluster) initTeamMembers(teamID string, isPostgresSuperuserTeam bool) error {
|
func (c *Cluster) initTeamMembers(teamID string, isPostgresSuperuserTeam bool) error {
|
||||||
teamMembers, err := c.getTeamMembers(teamID)
|
teamMembers, err := c.getTeamMembers(teamID)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1622,7 +1622,7 @@ func (c *Cluster) generateUserSecrets() map[string]*v1.Secret {
|
||||||
func (c *Cluster) generateSingleUserSecret(namespace string, pgUser spec.PgUser) *v1.Secret {
|
func (c *Cluster) generateSingleUserSecret(namespace string, pgUser spec.PgUser) *v1.Secret {
|
||||||
//Skip users with no password i.e. human users (they'll be authenticated using pam)
|
//Skip users with no password i.e. human users (they'll be authenticated using pam)
|
||||||
if pgUser.Password == "" {
|
if pgUser.Password == "" {
|
||||||
if pgUser.Origin != spec.RoleOriginTeamsAPI {
|
if pgUser.Origin != spec.RoleOriginTeamsAPI && pgUser.Origin != spec.RoleOriginSpilo {
|
||||||
c.logger.Warningf("could not generate secret for a non-teamsAPI role %q: role has no password",
|
c.logger.Warningf("could not generate secret for a non-teamsAPI role %q: role has no password",
|
||||||
pgUser.Name)
|
pgUser.Name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
// user config
|
// user config
|
||||||
result.SuperUsername = util.Coalesce(fromCRD.PostgresUsersConfiguration.SuperUsername, "postgres")
|
result.SuperUsername = util.Coalesce(fromCRD.PostgresUsersConfiguration.SuperUsername, "postgres")
|
||||||
result.ReplicationUsername = util.Coalesce(fromCRD.PostgresUsersConfiguration.ReplicationUsername, "standby")
|
result.ReplicationUsername = util.Coalesce(fromCRD.PostgresUsersConfiguration.ReplicationUsername, "standby")
|
||||||
|
result.CronAdminUsername = fromCRD.PostgresUsersConfiguration.CronAdminUsername
|
||||||
result.EnablePasswordRotation = fromCRD.PostgresUsersConfiguration.EnablePasswordRotation
|
result.EnablePasswordRotation = fromCRD.PostgresUsersConfiguration.EnablePasswordRotation
|
||||||
result.PasswordRotationInterval = util.CoalesceUInt32(fromCRD.PostgresUsersConfiguration.PasswordRotationInterval, 90)
|
result.PasswordRotationInterval = util.CoalesceUInt32(fromCRD.PostgresUsersConfiguration.PasswordRotationInterval, 90)
|
||||||
result.PasswordRotationUserRetention = util.CoalesceUInt32(fromCRD.PostgresUsersConfiguration.DeepCopy().PasswordRotationUserRetention, 180)
|
result.PasswordRotationUserRetention = util.CoalesceUInt32(fromCRD.PostgresUsersConfiguration.DeepCopy().PasswordRotationUserRetention, 180)
|
||||||
|
|
@ -186,7 +187,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.TeamAdminRole = fromCRD.TeamsAPI.TeamAdminRole
|
result.TeamAdminRole = fromCRD.TeamsAPI.TeamAdminRole
|
||||||
result.PamRoleName = util.Coalesce(fromCRD.TeamsAPI.PamRoleName, "zalandos")
|
result.PamRoleName = util.Coalesce(fromCRD.TeamsAPI.PamRoleName, "zalandos")
|
||||||
result.PamConfiguration = util.Coalesce(fromCRD.TeamsAPI.PamConfiguration, "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees")
|
result.PamConfiguration = util.Coalesce(fromCRD.TeamsAPI.PamConfiguration, "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees")
|
||||||
result.ProtectedRoles = util.CoalesceStrArr(fromCRD.TeamsAPI.ProtectedRoles, []string{"admin"})
|
result.ProtectedRoles = util.CoalesceStrArr(fromCRD.TeamsAPI.ProtectedRoles, []string{"admin", "cron_admin"})
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ const (
|
||||||
RoleOriginManifest
|
RoleOriginManifest
|
||||||
RoleOriginInfrastructure
|
RoleOriginInfrastructure
|
||||||
RoleOriginTeamsAPI
|
RoleOriginTeamsAPI
|
||||||
|
RoleOriginSpilo
|
||||||
RoleOriginSystem
|
RoleOriginSystem
|
||||||
RoleOriginBootstrap
|
RoleOriginBootstrap
|
||||||
RoleConnectionPooler
|
RoleConnectionPooler
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ type Auth struct {
|
||||||
InfrastructureRolesDefs string `name:"infrastructure_roles_secrets"`
|
InfrastructureRolesDefs string `name:"infrastructure_roles_secrets"`
|
||||||
SuperUsername string `name:"super_username" default:"postgres"`
|
SuperUsername string `name:"super_username" default:"postgres"`
|
||||||
ReplicationUsername string `name:"replication_username" default:"standby"`
|
ReplicationUsername string `name:"replication_username" default:"standby"`
|
||||||
|
CronAdminUsername string `name:"cron_admin_username" default:""`
|
||||||
EnablePasswordRotation bool `name:"enable_password_rotation" default:"false"`
|
EnablePasswordRotation bool `name:"enable_password_rotation" default:"false"`
|
||||||
PasswordRotationInterval uint32 `name:"password_rotation_interval" default:"90"`
|
PasswordRotationInterval uint32 `name:"password_rotation_interval" default:"90"`
|
||||||
PasswordRotationUserRetention uint32 `name:"password_rotation_user_retention" default:"180"`
|
PasswordRotationUserRetention uint32 `name:"password_rotation_user_retention" default:"180"`
|
||||||
|
|
@ -210,7 +211,7 @@ type Config struct {
|
||||||
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
|
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
|
||||||
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
||||||
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
|
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
|
||||||
ProtectedRoles []string `name:"protected_role_names" default:"admin"`
|
ProtectedRoles []string `name:"protected_role_names" default:"admin,cron_admin"`
|
||||||
PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""`
|
PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""`
|
||||||
SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" default:"false"`
|
SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" default:"false"`
|
||||||
EnableLazySpiloUpgrade bool `name:"enable_lazy_spilo_upgrade" default:"false"`
|
EnableLazySpiloUpgrade bool `name:"enable_lazy_spilo_upgrade" default:"false"`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue