Skip to content

Commit d658b96

Browse files
authored
PostgresTeam CRD for advanced team management (#1165)
* PostgresTeamCRD for advanced team management * rework internal structure to be closer to CRD * superusers instead of admin * add more util functions and unit tests * fix initHumanUsers * check for superusers when creating normal teams * polishing and fixes * adding the essential missing pieces * add documentation and update rbac * reflect some feedback * reflect more feedback * fixing debug logs and raise QueueResyncPeriodTPR * add two more flags to disable CRD and its superuser support * fix chart * update go modules * move to client 1.19.3 and update codegen
1 parent 3a86dfc commit d658b96

39 files changed

+1508
-46
lines changed

charts/postgres-operator/crds/operatorconfigurations.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ spec:
319319
properties:
320320
enable_admin_role_for_users:
321321
type: boolean
322+
enable_postgres_team_crd:
323+
type: boolean
324+
enable_postgres_team_crd_superusers:
325+
type: boolean
322326
enable_team_superuser:
323327
type: boolean
324328
enable_teams_api:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: postgresteams.acid.zalan.do
5+
labels:
6+
app.kubernetes.io/name: postgres-operator
7+
annotations:
8+
"helm.sh/hook": crd-install
9+
spec:
10+
group: acid.zalan.do
11+
names:
12+
kind: PostgresTeam
13+
listKind: PostgresTeamList
14+
plural: postgresteams
15+
singular: postgresteam
16+
shortNames:
17+
- pgteam
18+
scope: Namespaced
19+
subresources:
20+
status: {}
21+
version: v1
22+
validation:
23+
openAPIV3Schema:
24+
type: object
25+
required:
26+
- kind
27+
- apiVersion
28+
- spec
29+
properties:
30+
kind:
31+
type: string
32+
enum:
33+
- PostgresTeam
34+
apiVersion:
35+
type: string
36+
enum:
37+
- acid.zalan.do/v1
38+
spec:
39+
type: object
40+
properties:
41+
additionalSuperuserTeams:
42+
type: object
43+
description: "Map for teamId and associated additional superuser teams"
44+
additionalProperties:
45+
type: array
46+
nullable: true
47+
description: "List of teams to become Postgres superusers"
48+
items:
49+
type: string
50+
additionalTeams:
51+
type: object
52+
description: "Map for teamId and associated additional teams"
53+
additionalProperties:
54+
type: array
55+
nullable: true
56+
description: "List of teams whose members will also be added to the Postgres cluster"
57+
items:
58+
type: string
59+
additionalMembers:
60+
type: object
61+
description: "Map for teamId and associated additional users"
62+
additionalProperties:
63+
type: array
64+
nullable: true
65+
description: "List of users who will also be added to the Postgres cluster"
66+
items:
67+
type: string

charts/postgres-operator/templates/clusterrole.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ rules:
2525
- patch
2626
- update
2727
- watch
28+
# operator only reads PostgresTeams
29+
- apiGroups:
30+
- acid.zalan.do
31+
resources:
32+
- postgresteams
33+
verbs:
34+
- get
35+
- list
36+
- watch
2837
# to create or get/update CRDs when starting up
2938
- apiGroups:
3039
- apiextensions.k8s.io

charts/postgres-operator/values-crd.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ configTeamsApi:
256256
# team_admin_role will have the rights to grant roles coming from PG manifests
257257
# enable_admin_role_for_users: true
258258

259+
# operator watches for PostgresTeam CRs to assign additional teams and members to clusters
260+
enable_postgres_team_crd: true
261+
# toogle to create additional superuser teams from PostgresTeam CRs
262+
# enable_postgres_team_crd_superusers: "false"
263+
259264
# toggle to grant superuser to team members created from the Teams API
260265
enable_team_superuser: false
261266
# toggles usage of the Teams API by the operator

charts/postgres-operator/values.yaml

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
image:
22
registry: registry.opensource.zalan.do
33
repository: acid/postgres-operator
4-
tag: v1.5.0
4+
tag: v1.5.0-61-ged2b3239-dirty
55
pullPolicy: "IfNotPresent"
66

77
# Optionally specify an array of imagePullSecrets.
@@ -248,6 +248,11 @@ configTeamsApi:
248248
# team_admin_role will have the rights to grant roles coming from PG manifests
249249
# enable_admin_role_for_users: "true"
250250

251+
# operator watches for PostgresTeam CRs to assign additional teams and members to clusters
252+
enable_postgres_team_crd: "true"
253+
# toogle to create additional superuser teams from PostgresTeam CRs
254+
# enable_postgres_team_crd_superusers: "false"
255+
251256
# toggle to grant superuser to team members created from the Teams API
252257
# enable_team_superuser: "false"
253258

docs/administrator.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,12 @@ database.
561561
* **Human users** originate from the [Teams API](user.md#teams-api-roles) that
562562
returns a list of the team members given a team id. The operator differentiates
563563
between (a) product teams that own a particular Postgres cluster and are granted
564-
admin rights to maintain it, and (b) Postgres superuser teams that get the
565-
superuser access to all Postgres databases running in a K8s cluster for the
566-
purposes of maintaining and troubleshooting.
564+
admin rights to maintain it, (b) Postgres superuser teams that get superuser
565+
access to all Postgres databases running in a K8s cluster for the purposes of
566+
maintaining and troubleshooting, and (c) additional teams, superuser teams or
567+
members associated with the owning team. The latter is managed via the
568+
[PostgresTeam CRD](user.md#additional-teams-and-members-per-cluster).
569+
567570

568571
## Understanding rolling update of Spilo pods
569572

docs/reference/operator_parameters.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,8 @@ key.
598598
The default is `"log_statement:all"`
599599
600600
* **enable_team_superuser**
601-
whether to grant superuser to team members created from the Teams API.
602-
The default is `false`.
601+
whether to grant superuser to members of the cluster's owning team created
602+
from the Teams API. The default is `false`.
603603

604604
* **team_admin_role**
605605
role name to grant to team members created from the Teams API. The default is
@@ -632,6 +632,16 @@ key.
632632
cluster to administer Postgres and maintain infrastructure built around it.
633633
The default is empty.
634634

635+
* **enable_postgres_team_crd**
636+
toggle to make the operator watch for created or updated `PostgresTeam` CRDs
637+
and create roles for specified additional teams and members.
638+
The default is `true`.
639+
640+
* **enable_postgres_team_crd_superusers**
641+
in a `PostgresTeam` CRD additional superuser teams can assigned to teams that
642+
own clusters. With this flag set to `false`, it will be ignored.
643+
The default is `false`.
644+
635645
## Logging and REST API
636646

637647
Parameters affecting logging and REST API listener. In the CRD-based

docs/user.md

+61
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,67 @@ to choose superusers, group roles, [PAM configuration](https://github.com/CyberD
269269
etc. An OAuth2 token can be passed to the Teams API via a secret. The name for
270270
this secret is configurable with the `oauth_token_secret_name` parameter.
271271

272+
### Additional teams and members per cluster
273+
274+
Postgres clusters are associated with one team by providing the `teamID` in
275+
the manifest. Additional superuser teams can be configured as mentioned in
276+
the previous paragraph. However, this is a global setting. To assign
277+
additional teams, superuser teams and single users to clusters of a given
278+
team, use the [PostgresTeam CRD](../manifests/postgresteam.yaml). It provides
279+
a simple mapping structure.
280+
281+
282+
```yaml
283+
apiVersion: "acid.zalan.do/v1"
284+
kind: PostgresTeam
285+
metadata:
286+
name: custom-team-membership
287+
spec:
288+
additionalSuperuserTeams:
289+
acid:
290+
- "postgres_superusers"
291+
additionalTeams:
292+
acid: []
293+
additionalMembers:
294+
acid:
295+
- "elephant"
296+
```
297+
298+
One `PostgresTeam` resource could contain mappings of multiple teams but you
299+
can choose to create separate CRDs, alternatively. On each CRD creation or
300+
update the operator will gather all mappings to create additional human users
301+
in databases the next time they are synced. Additional teams are resolved
302+
transitively, meaning you will also add users for their `additionalTeams`
303+
or (not and) `additionalSuperuserTeams`.
304+
305+
For each additional team the Teams API would be queried. Additional members
306+
will be added either way. There can be "virtual teams" that do not exists in
307+
your Teams API but users of associated teams as well as members will get
308+
created. With `PostgresTeams` it's also easy to cover team name changes. Just
309+
add the mapping between old and new team name and the rest can stay the same.
310+
311+
```yaml
312+
apiVersion: "acid.zalan.do/v1"
313+
kind: PostgresTeam
314+
metadata:
315+
name: virtualteam-membership
316+
spec:
317+
additionalSuperuserTeams:
318+
acid:
319+
- "virtual_superusers"
320+
virtual_superusers:
321+
- "real_teamA"
322+
- "real_teamB"
323+
real_teamA:
324+
- "real_teamA_renamed"
325+
additionalTeams:
326+
real_teamA:
327+
- "real_teamA_renamed"
328+
additionalMembers:
329+
virtual_superusers:
330+
- "foo"
331+
```
332+
272333
## Prepared databases with roles and default privileges
273334

274335
The `users` section in the manifests only allows for creating database roles

manifests/configmap.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ data:
4141
enable_master_load_balancer: "false"
4242
# enable_pod_antiaffinity: "false"
4343
# enable_pod_disruption_budget: "true"
44+
# enable_postgres_team_crd: "true"
45+
# enable_postgres_team_crd_superusers: "false"
4446
enable_replica_load_balancer: "false"
4547
# enable_shm_volume: "true"
4648
# enable_sidecars: "true"

manifests/custom-team-membership.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: "acid.zalan.do/v1"
2+
kind: PostgresTeam
3+
metadata:
4+
name: custom-team-membership
5+
spec:
6+
additionalSuperuserTeams:
7+
acid:
8+
- "postgres_superusers"
9+
additionalTeams:
10+
acid: []
11+
additionalMembers:
12+
acid:
13+
- "elephant"

manifests/operator-service-account-rbac.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ rules:
2626
- patch
2727
- update
2828
- watch
29+
# operator only reads PostgresTeams
30+
- apiGroups:
31+
- acid.zalan.do
32+
resources:
33+
- postgresteams
34+
verbs:
35+
- get
36+
- list
37+
- watch
2938
# to create or get/update CRDs when starting up
3039
- apiGroups:
3140
- apiextensions.k8s.io

manifests/operatorconfiguration.crd.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ spec:
325325
properties:
326326
enable_admin_role_for_users:
327327
type: boolean
328+
enable_postgres_team_crd:
329+
type: boolean
330+
enable_postgres_team_crd_superusers:
331+
type: boolean
328332
enable_team_superuser:
329333
type: boolean
330334
enable_teams_api:

manifests/postgresql-operator-default-configuration.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ configuration:
122122
enable_database_access: true
123123
teams_api:
124124
# enable_admin_role_for_users: true
125+
# enable_postgres_team_crd: true
126+
# enable_postgres_team_crd_superusers: false
125127
enable_team_superuser: false
126128
enable_teams_api: false
127129
# pam_configuration: ""

manifests/postgresteam.crd.yaml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: postgresteams.acid.zalan.do
5+
spec:
6+
group: acid.zalan.do
7+
names:
8+
kind: PostgresTeam
9+
listKind: PostgresTeamList
10+
plural: postgresteams
11+
singular: postgresteam
12+
shortNames:
13+
- pgteam
14+
scope: Namespaced
15+
subresources:
16+
status: {}
17+
version: v1
18+
validation:
19+
openAPIV3Schema:
20+
type: object
21+
required:
22+
- kind
23+
- apiVersion
24+
- spec
25+
properties:
26+
kind:
27+
type: string
28+
enum:
29+
- PostgresTeam
30+
apiVersion:
31+
type: string
32+
enum:
33+
- acid.zalan.do/v1
34+
spec:
35+
type: object
36+
properties:
37+
additionalSuperuserTeams:
38+
type: object
39+
description: "Map for teamId and associated additional superuser teams"
40+
additionalProperties:
41+
type: array
42+
nullable: true
43+
description: "List of teams to become Postgres superusers"
44+
items:
45+
type: string
46+
additionalTeams:
47+
type: object
48+
description: "Map for teamId and associated additional teams"
49+
additionalProperties:
50+
type: array
51+
nullable: true
52+
description: "List of teams whose members will also be added to the Postgres cluster"
53+
items:
54+
type: string
55+
additionalMembers:
56+
type: object
57+
description: "Map for teamId and associated additional users"
58+
additionalProperties:
59+
type: array
60+
nullable: true
61+
description: "List of users who will also be added to the Postgres cluster"
62+
items:
63+
type: string

pkg/apis/acid.zalan.do/v1/crds.go

+6
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,12 @@ var OperatorConfigCRDResourceValidation = apiextv1beta1.CustomResourceValidation
12351235
"enable_admin_role_for_users": {
12361236
Type: "boolean",
12371237
},
1238+
"enable_postgres_team_crd": {
1239+
Type: "boolean",
1240+
},
1241+
"enable_postgres_team_crd_superusers": {
1242+
Type: "boolean",
1243+
},
12381244
"enable_team_superuser": {
12391245
Type: "boolean",
12401246
},

0 commit comments

Comments
 (0)