@@ -94,7 +94,10 @@ created on every cluster managed by the operator.
94
94
* ` teams API roles ` : automatically create users for every member of the team
95
95
owning the database cluster.
96
96
97
- In the next sections, we will cover those use cases in more details.
97
+ In the next sections, we will cover those use cases in more details. Note, that
98
+ the Postgres Operator can also create databases with pre-defined owner, reader
99
+ and writer roles which saves you the manual setup. Read more in the next
100
+ chapter.
98
101
99
102
### Manifest roles
100
103
@@ -216,6 +219,166 @@ to choose superusers, group roles, [PAM configuration](https://github.com/CyberD
216
219
etc. An OAuth2 token can be passed to the Teams API via a secret. The name for
217
220
this secret is configurable with the `oauth_token_secret_name` parameter.
218
221
222
+ # # Prepared databases with roles and default privileges
223
+
224
+ The `users` section in the manifests only allows for creating database roles
225
+ with global privileges. Fine-grained data access control or role membership can
226
+ not be defined and must be set up by the user in the database. But, the Postgres
227
+ Operator offers a separate section to specify `preparedDatabases` that will be
228
+ created with pre-defined owner, reader and writer roles for each individual
229
+ database and, optionally, for each database schema, too. `preparedDatabases`
230
+ also enable users to specify PostgreSQL extensions that shall be created in a
231
+ given database schema.
232
+
233
+ # ## Default database and schema
234
+
235
+ A prepared database is already created by adding an empty `preparedDatabases`
236
+ section to the manifest. The database will then be called like the Postgres
237
+ cluster manifest (`-` are replaced with `_`) and will also contain a schema
238
+ called `data`.
239
+
240
+ ` ` ` yaml
241
+ spec:
242
+ preparedDatabases: {}
243
+ ` ` `
244
+
245
+ # ## Default NOLOGIN roles
246
+
247
+ Given an example with a specified database and schema :
248
+
249
+ ` ` ` yaml
250
+ spec:
251
+ preparedDatabases:
252
+ foo:
253
+ schemas:
254
+ bar: {}
255
+ ` ` `
256
+
257
+ Postgres Operator will create the following NOLOGIN roles :
258
+
259
+ | Role name | Member of | Admin |
260
+ | -------------- | -------------- | ------------- |
261
+ | foo_owner | | admin |
262
+ | foo_reader | | foo_owner |
263
+ | foo_writer | foo_reader | foo_owner |
264
+ | foo_bar_owner | | foo_owner |
265
+ | foo_bar_reader | | foo_bar_owner |
266
+ | foo_bar_writer | foo_bar_reader | foo_bar_owner |
267
+
268
+ The `<dbname>_owner` role is the database owner and should be used when creating
269
+ new database objects. All members of the `admin` role, e.g. teams API roles, can
270
+ become the owner with the `SET ROLE` command. [Default privileges](https://www.postgresql.org/docs/12/sql-alterdefaultprivileges.html)
271
+ are configured for the owner role so that the `<dbname>_reader` role
272
+ automatically gets read-access (SELECT) to new tables and sequences and the
273
+ ` <dbname>_writer` receives write-access (INSERT, UPDATE, DELETE on tables,
274
+ USAGE and UPDATE on sequences). Both get USAGE on types and EXECUTE on
275
+ functions.
276
+
277
+ The same principle applies for database schemas which are owned by the
278
+ ` <dbname>_<schema>_owner` role. `<dbname>_<schema>_reader` is read-only,
279
+ ` <dbname>_<schema>_writer` has write access and inherit reading from the reader
280
+ role. Note, that the `<dbname>_*` roles have access incl. default privileges on
281
+ all schemas, too. If you don't need the dedicated schema roles - i.e. you only
282
+ use one schema - you can disable the creation like this :
283
+
284
+ ` ` ` yaml
285
+ spec:
286
+ preparedDatabases:
287
+ foo:
288
+ schemas:
289
+ bar:
290
+ defaultRoles: false
291
+ ` ` `
292
+
293
+ Then, the schemas are owned by the database owner, too.
294
+
295
+ # ## Default LOGIN roles
296
+
297
+ The roles described in the previous paragraph can be granted to LOGIN roles from
298
+ the `users` section in the manifest. Optionally, the Postgres Operator can also
299
+ create default LOGIN roles for the database an each schema individually. These
300
+ roles will get the `_user` suffix and they inherit all rights from their NOLOGIN
301
+ counterparts.
302
+
303
+ | Role name | Member of | Admin |
304
+ | ------------------- | -------------- | ------------- |
305
+ | foo_owner_user | foo_owner | admin |
306
+ | foo_reader_user | foo_reader | foo_owner |
307
+ | foo_writer_user | foo_writer | foo_owner |
308
+ | foo_bar_owner_user | foo_bar_owner | foo_owner |
309
+ | foo_bar_reader_user | foo_bar_reader | foo_bar_owner |
310
+ | foo_bar_writer_user | foo_bar_writer | foo_bar_owner |
311
+
312
+ These default users are enabled in the manifest with the `defaultUsers` flag :
313
+
314
+ ` ` ` yaml
315
+ spec:
316
+ preparedDatabases:
317
+ foo:
318
+ defaultUsers: true
319
+ schemas:
320
+ bar:
321
+ defaultUsers: true
322
+ ` ` `
323
+
324
+ # ## Database extensions
325
+
326
+ Prepared databases also allow for creating Postgres extensions. They will be
327
+ created by the database owner in the specified schema.
328
+
329
+ ` ` ` yaml
330
+ spec:
331
+ preparedDatabases:
332
+ foo:
333
+ extensions:
334
+ pg_partman: public
335
+ postgis: data
336
+ ` ` `
337
+
338
+ Some extensions require SUPERUSER rights on creation unless they are not
339
+ whitelisted by the [pgextwlist](https://github.com/dimitri/pgextwlist)
340
+ extension, that is shipped with the Spilo image. To see which extensions are
341
+ on the list check the `extwlist.extension` parameter in the postgresql.conf
342
+ file.
343
+
344
+ ` ` ` bash
345
+ SHOW extwlist.extensions;
346
+ ` ` `
347
+
348
+ Make sure that `pgextlist` is also listed under `shared_preload_libraries` in
349
+ the PostgreSQL configuration. Then the database owner should be able to create
350
+ the extension specified in the manifest.
351
+
352
+ # ## From `databases` to `preparedDatabases`
353
+
354
+ If you wish to create the role setup described above for databases listed under
355
+ the `databases` key, you have to make sure that the owner role follows the
356
+ ` <dbname>_owner` naming convention of `preparedDatabases`. As roles are synced
357
+ first, this can be done with one edit :
358
+
359
+ ` ` ` yaml
360
+ # before
361
+ spec:
362
+ databases:
363
+ foo: db_owner
364
+
365
+ # after
366
+ spec:
367
+ databases:
368
+ foo: foo_owner
369
+ preparedDatabases:
370
+ foo:
371
+ schemas:
372
+ my_existing_schema: {}
373
+ ` ` `
374
+
375
+ Adding existing database schemas to the manifest to create roles for them as
376
+ well is up the user and not done by the operator. Remember that if you don't
377
+ specify any schema a new database schema called `data` will be created. When
378
+ everything got synced (roles, schemas, extensions), you are free to remove the
379
+ database from the `databases` section. Note, that the operator does not delete
380
+ database objects or revoke privileges when removed from the manifest.
381
+
219
382
# # Resource definition
220
383
221
384
The compute resources to be used for the Postgres containers in the pods can be
@@ -586,8 +749,8 @@ don't know the value, use `103` which is the GID from the default spilo image
586
749
OpenShift allocates the users and groups dynamically (based on scc), and their
587
750
range is different in every namespace. Due to this dynamic behaviour, it's not
588
751
trivial to know at deploy time the uid/gid of the user in the cluster.
589
- Therefore, instead of using a global `spilo_fsgroup` setting, use the `spiloFSGroup` field
590
- per Postgres cluster.
752
+ Therefore, instead of using a global `spilo_fsgroup` setting, use the
753
+ ` spiloFSGroup ` field per Postgres cluster.
591
754
592
755
Upload the cert as a kubernetes secret :
593
756
` ` ` sh
0 commit comments