allow specifiying more extra owner roles
This commit is contained in:
		
							parent
							
								
									89801ef30a
								
							
						
					
					
						commit
						78eaae2efc
					
				|  | @ -130,7 +130,10 @@ spec: | |||
|               users: | ||||
|                 type: object | ||||
|                 properties: | ||||
|                   cron_admin_username: | ||||
|                   additional_owner_roles: | ||||
|                     type: array | ||||
|                     nullable: true | ||||
|                     items: | ||||
|                       type: string | ||||
|                   enable_password_rotation: | ||||
|                     type: boolean | ||||
|  | @ -502,6 +505,7 @@ spec: | |||
|                       type: string | ||||
|                     default: | ||||
|                     - admin | ||||
|                     - cron_admin | ||||
|                   role_deletion_suffix: | ||||
|                     type: string | ||||
|                     default: "_deleted" | ||||
|  |  | |||
|  | @ -59,8 +59,10 @@ configGeneral: | |||
| 
 | ||||
| # parameters describing Postgres users | ||||
| configUsers: | ||||
|   # username used to grant rights to set up and maintain cron jobs to database owners | ||||
|   cron_admin_username: cron_admin | ||||
|   # roles to be granted to database owners | ||||
|   # additional_owner_roles: | ||||
|   # - 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 | ||||
|  | @ -346,6 +348,7 @@ configTeamsApi: | |||
|   # List of roles that cannot be overwritten by an application, team or infrastructure role | ||||
|   protected_role_names: | ||||
|     - admin | ||||
|     - cron_admin | ||||
|   # Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD | ||||
|   role_deletion_suffix: "_deleted" | ||||
|   # role name to grant to team members created from the Teams API | ||||
|  |  | |||
|  | @ -177,12 +177,14 @@ under the `users` key. | |||
|   Postgres username used for replication between instances. The default is | ||||
|   `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`. | ||||
| * **additional_owner_roles** | ||||
|   Specifies database roles that will become members of all database owners. | ||||
|   Then owners can use `SET ROLE` to obtain privileges of these roles to e.g. | ||||
|   create/update functionality from extensions as part of a migration script. | ||||
|   Note, that roles listed here should be preconfigured in the docker image | ||||
|   and already exist in the database cluster on startup. One such role can be | ||||
|   `cron_admin` which is provided by the Spilo docker image to set up cron | ||||
|   jobs inside the `postgres` database. Default is `empty`. | ||||
| 
 | ||||
| * **enable_password_rotation** | ||||
|   For all `LOGIN` roles that are not database owners the operator can rotate | ||||
|  | @ -755,7 +757,7 @@ key. | |||
| 
 | ||||
| * **protected_role_names** | ||||
|   List of roles that cannot be overwritten by an application, team or | ||||
|   infrastructure role. The default is `admin`. | ||||
|   infrastructure role. The default list is `admin` and `cron_admin`. | ||||
| 
 | ||||
| * **postgres_superuser_teams** | ||||
|   List of teams which members need the superuser role in each PG database | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ kind: ConfigMap | |||
| metadata: | ||||
|   name: postgres-operator | ||||
| data: | ||||
|   # additional_owner_roles: "cron_admin" | ||||
|   # additional_pod_capabilities: "SYS_NICE" | ||||
|   # additional_secret_mount: "some-secret-name" | ||||
|   # additional_secret_mount_path: "/some/dir" | ||||
|  | @ -23,7 +24,6 @@ data: | |||
|   # connection_pooler_schema: "pooler" | ||||
|   # connection_pooler_user: "pooler" | ||||
|   crd_categories: "all" | ||||
|   # cron_admin_username: "cron_admin" | ||||
|   # custom_service_annotations: "keyx:valuez,keya:valuea" | ||||
|   # custom_pod_annotations: "keya:valuea,keyb:valueb" | ||||
|   db_hosted_zone: db.example.com | ||||
|  |  | |||
|  | @ -128,7 +128,10 @@ spec: | |||
|               users: | ||||
|                 type: object | ||||
|                 properties: | ||||
|                   cron_admin_username: | ||||
|                   additional_owner_roles: | ||||
|                     type: array | ||||
|                     nullable: true | ||||
|                     items: | ||||
|                       type: string | ||||
|                   enable_password_rotation: | ||||
|                     type: boolean | ||||
|  | @ -500,6 +503,7 @@ spec: | |||
|                       type: string | ||||
|                     default: | ||||
|                     - admin | ||||
|                     - cron_admin | ||||
|                   role_deletion_suffix: | ||||
|                     type: string | ||||
|                     default: "_deleted" | ||||
|  |  | |||
|  | @ -26,12 +26,13 @@ configuration: | |||
|   #     protocol: TCP | ||||
|   workers: 8 | ||||
|   users: | ||||
|     # additional_owner_roles:  | ||||
|     # - cron_admin | ||||
|     enable_password_rotation: false | ||||
|     password_rotation_interval: 90 | ||||
|     password_rotation_user_retention: 180 | ||||
|     replication_username: standby | ||||
|     super_username: postgres | ||||
|     # cron_admin_username: cron_admin | ||||
|   major_version_upgrade: | ||||
|     major_version_upgrade_mode: "off" | ||||
|     # major_version_upgrade_team_allow_list: | ||||
|  |  | |||
|  | @ -1142,9 +1142,15 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{ | |||
| 					"users": { | ||||
| 						Type: "object", | ||||
| 						Properties: map[string]apiextv1.JSONSchemaProps{ | ||||
| 							"cron_admin_username": { | ||||
| 							"additional_owner_roles": { | ||||
| 								Type:     "array", | ||||
| 								Nullable: true, | ||||
| 								Items: &apiextv1.JSONSchemaPropsOrArray{ | ||||
| 									Schema: &apiextv1.JSONSchemaProps{ | ||||
| 										Type: "string", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 							"enable_password_rotation": { | ||||
| 								Type: "boolean", | ||||
| 							}, | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ type OperatorConfigurationList struct { | |||
| type PostgresUsersConfiguration struct { | ||||
| 	SuperUsername                 string   `json:"super_username,omitempty"` | ||||
| 	ReplicationUsername           string   `json:"replication_username,omitempty"` | ||||
| 	CronAdminUsername             string `json:"cron_admin_username,omitempty"` | ||||
| 	AddtionalOwnerRoles           []string `json:"additional_owner_roles,omitempty"` | ||||
| 	EnablePasswordRotation        bool     `json:"enable_password_rotation,omitempty"` | ||||
| 	PasswordRotationInterval      uint32   `json:"password_rotation_interval,omitempty"` | ||||
| 	PasswordRotationUserRetention uint32   `json:"password_rotation_user_retention,omitempty"` | ||||
|  |  | |||
|  | @ -401,7 +401,7 @@ func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData | |||
| 			(*in)[i].DeepCopyInto(&(*out)[i]) | ||||
| 		} | ||||
| 	} | ||||
| 	out.PostgresUsersConfiguration = in.PostgresUsersConfiguration | ||||
| 	in.PostgresUsersConfiguration.DeepCopyInto(&out.PostgresUsersConfiguration) | ||||
| 	in.MajorVersionUpgrade.DeepCopyInto(&out.MajorVersionUpgrade) | ||||
| 	in.Kubernetes.DeepCopyInto(&out.Kubernetes) | ||||
| 	out.PostgresPodResources = in.PostgresPodResources | ||||
|  | @ -916,6 +916,11 @@ func (in *PostgresTeamSpec) DeepCopy() *PostgresTeamSpec { | |||
| // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | ||||
| func (in *PostgresUsersConfiguration) DeepCopyInto(out *PostgresUsersConfiguration) { | ||||
| 	*out = *in | ||||
| 	if in.AddtionalOwnerRoles != nil { | ||||
| 		in, out := &in.AddtionalOwnerRoles, &out.AddtionalOwnerRoles | ||||
| 		*out = make([]string, len(*in)) | ||||
| 		copy(*out, *in) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -228,7 +228,7 @@ func (c *Cluster) initUsers() error { | |||
| 		return fmt.Errorf("could not init human users: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	c.initCronAdmin() | ||||
| 	c.initAdditionalOwnerRoles() | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
|  | @ -1299,11 +1299,9 @@ func (c *Cluster) initRobotUsers() error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (c *Cluster) initCronAdmin() { | ||||
| 	cronAdminName := c.OpConfig.CronAdminUsername | ||||
| 	if cronAdminName == "" { | ||||
| 		return | ||||
| 	} | ||||
| func (c *Cluster) initAdditionalOwnerRoles() { | ||||
| 	for _, additionalOwner := range c.OpConfig.AddtionalOwnerRoles { | ||||
| 		// fetch all database owners the additional should become a member of
 | ||||
| 		memberOf := make([]string, 0) | ||||
| 		for username, pgUser := range c.pgUsers { | ||||
| 			if pgUser.IsDbOwner { | ||||
|  | @ -1313,22 +1311,17 @@ func (c *Cluster) initCronAdmin() { | |||
| 
 | ||||
| 		if len(memberOf) > 1 { | ||||
| 			namespace := c.Namespace | ||||
| 		adminRole := "" | ||||
| 		if c.OpConfig.EnableAdminRoleForUsers && cronAdminName != c.OpConfig.TeamAdminRole { | ||||
| 			adminRole = c.OpConfig.TeamAdminRole | ||||
| 		} | ||||
| 		cronAdmin := spec.PgUser{ | ||||
| 			additionalOwnerPgUser := spec.PgUser{ | ||||
| 				Origin:    spec.RoleOriginSpilo, | ||||
| 				MemberOf:  memberOf, | ||||
| 			Name:      cronAdminName, | ||||
| 				Name:      additionalOwner, | ||||
| 				Namespace: namespace, | ||||
| 			Flags:     []string{constants.RoleFlagNoLogin}, | ||||
| 			AdminRole: adminRole, | ||||
| 			} | ||||
| 		if currentRole, present := c.pgUsers[cronAdminName]; present { | ||||
| 			c.pgUsers[cronAdminName] = c.resolveNameConflict(¤tRole, &cronAdmin) | ||||
| 			if currentRole, present := c.pgUsers[additionalOwner]; present { | ||||
| 				c.pgUsers[additionalOwner] = c.resolveNameConflict(¤tRole, &additionalOwnerPgUser) | ||||
| 			} else { | ||||
| 			c.pgUsers[cronAdminName] = cronAdmin | ||||
| 				c.pgUsers[additionalOwner] = additionalOwnerPgUser | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -101,7 +101,7 @@ type Auth struct { | |||
| 	InfrastructureRolesDefs       string                `name:"infrastructure_roles_secrets"` | ||||
| 	SuperUsername                 string                `name:"super_username" default:"postgres"` | ||||
| 	ReplicationUsername           string                `name:"replication_username" default:"standby"` | ||||
| 	CronAdminUsername             string                `name:"cron_admin_username" default:""` | ||||
| 	AddtionalOwnerRoles           []string              `name:"additional_owner_roles" default:""` | ||||
| 	EnablePasswordRotation        bool                  `name:"enable_password_rotation" default:"false"` | ||||
| 	PasswordRotationInterval      uint32                `name:"password_rotation_interval" default:"90"` | ||||
| 	PasswordRotationUserRetention uint32                `name:"password_rotation_user_retention" default:"180"` | ||||
|  |  | |||
|  | @ -53,25 +53,31 @@ func (strategy DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserM | |||
| 			} | ||||
| 		} else { | ||||
| 			r := spec.PgSyncUserRequest{} | ||||
| 			r.User = dbUser | ||||
| 			newMD5Password := util.NewEncryptor(strategy.PasswordEncryption).PGUserPassword(newUser) | ||||
| 
 | ||||
| 			// do not compare for roles coming from docker image
 | ||||
| 			if newUser.Origin != spec.RoleOriginSpilo { | ||||
| 				if dbUser.Password != newMD5Password { | ||||
| 					r.User.Password = newMD5Password | ||||
| 					r.Kind = spec.PGsyncUserAlter | ||||
| 				} | ||||
| 			if addNewRoles, equal := util.SubstractStringSlices(newUser.MemberOf, dbUser.MemberOf); !equal { | ||||
| 				r.User.MemberOf = addNewRoles | ||||
| 				r.Kind = spec.PGsyncUserAlter | ||||
| 			} | ||||
| 				if addNewFlags, equal := util.SubstractStringSlices(newUser.Flags, dbUser.Flags); !equal { | ||||
| 					r.User.Flags = addNewFlags | ||||
| 					r.Kind = spec.PGsyncUserAlter | ||||
| 				} | ||||
| 			} | ||||
| 			if addNewRoles, equal := util.SubstractStringSlices(newUser.MemberOf, dbUser.MemberOf); !equal { | ||||
| 				r.User.MemberOf = addNewRoles | ||||
| 				r.Kind = spec.PGsyncUserAlter | ||||
| 			} | ||||
| 			if r.Kind == spec.PGsyncUserAlter { | ||||
| 				r.User.Name = newUser.Name | ||||
| 				reqs = append(reqs, r) | ||||
| 			} | ||||
| 			if len(newUser.Parameters) > 0 && !reflect.DeepEqual(dbUser.Parameters, newUser.Parameters) { | ||||
| 			if newUser.Origin != spec.RoleOriginSpilo && | ||||
| 				len(newUser.Parameters) > 0 && | ||||
| 				!reflect.DeepEqual(dbUser.Parameters, newUser.Parameters) { | ||||
| 				reqs = append(reqs, spec.PgSyncUserRequest{Kind: spec.PGSyncAlterSet, User: newUser}) | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue