mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-09 22:13:18 +09:00
fix(postgres): tolerate databases declared without roles
`databases.<name>.roles` and its `admin`/`readonly` lists are optional in
the schema, but the init script dereferenced `$d.roles.admin` for every
database. A database declared with only `extensions`, or with an empty
body, failed the whole render with a nil pointer error instead of simply
granting nothing.
Treat a missing `roles`, `admin` or `readonly` as an empty list, so such a
database reconciles the same way as `roles: {}`: no grants, every managed
role revoked.
Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
This commit is contained in:
2 files changed
+104
-2
No files matched your search
@@ -204,13 +204,18 @@ stringData:
|
||||
echo "== assign roles to users"
|
||||
psql -v ON_ERROR_STOP=1 --echo-all <<\EOT
|
||||
{{- range $database, $d := .Values.databases }}
|
||||
{{- /* roles, roles.admin and roles.readonly are all optional: a database
|
||||
declared without them grants nothing and revokes every managed role. */}}
|
||||
{{- $roles := default dict (default dict $d).roles }}
|
||||
{{- $admin := default list $roles.admin }}
|
||||
{{- $readonly := default list $roles.readonly }}
|
||||
{{- range $user, $u := $.Values.users }}
|
||||
{{- if has $user $d.roles.admin }}
|
||||
{{- if has $user $admin }}
|
||||
GRANT "{{ $database }}_admin" TO "{{ $user }}";
|
||||
{{- else }}
|
||||
REVOKE "{{ $database }}_admin" FROM "{{ $user }}";
|
||||
{{- end }}
|
||||
{{- if has $user $d.roles.readonly }}
|
||||
{{- if has $user $readonly }}
|
||||
GRANT "{{ $database }}_readonly" TO "{{ $user }}";
|
||||
{{- else }}
|
||||
REVOKE "{{ $database }}_readonly" FROM "{{ $user }}";
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
suite: databases render without roles
|
||||
|
||||
# `databases.<name>.roles`, `roles.admin` and `roles.readonly` are all optional
|
||||
# in the schema. The init script used to dereference `$d.roles.admin` for every
|
||||
# database, so a database declared with only `extensions` (or with nothing at
|
||||
# all) failed the whole render with "nil pointer evaluating interface {}.admin".
|
||||
# A missing list must read as an empty list: no user is granted the role, and
|
||||
# every managed role is revoked from every user, exactly as `roles: {}` does.
|
||||
|
||||
templates:
|
||||
- templates/init-script.yaml
|
||||
|
||||
release:
|
||||
name: pg-test
|
||||
namespace: tenant-test
|
||||
|
||||
set:
|
||||
_cluster:
|
||||
scheduling: {}
|
||||
users:
|
||||
app:
|
||||
password: secret
|
||||
|
||||
tests:
|
||||
- it: "a database with only extensions renders and revokes both managed roles"
|
||||
set:
|
||||
databases:
|
||||
events:
|
||||
extensions:
|
||||
- hstore
|
||||
documentSelector:
|
||||
path: metadata.name
|
||||
value: pg-test-init-script
|
||||
asserts:
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'REVOKE "events_admin" FROM "app";'
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'REVOKE "events_readonly" FROM "app";'
|
||||
- notMatchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'GRANT "events_(admin|readonly)" TO'
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'CREATE EXTENSION IF NOT EXISTS hstore;'
|
||||
|
||||
- it: "a database with an empty body renders the same as roles: {}"
|
||||
set:
|
||||
databases:
|
||||
events: {}
|
||||
documentSelector:
|
||||
path: metadata.name
|
||||
value: pg-test-init-script
|
||||
asserts:
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'REVOKE "events_admin" FROM "app";'
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'REVOKE "events_readonly" FROM "app";'
|
||||
|
||||
- it: "roles with only admin grants admin and revokes readonly"
|
||||
set:
|
||||
databases:
|
||||
events:
|
||||
roles:
|
||||
admin:
|
||||
- app
|
||||
documentSelector:
|
||||
path: metadata.name
|
||||
value: pg-test-init-script
|
||||
asserts:
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'GRANT "events_admin" TO "app";'
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'REVOKE "events_readonly" FROM "app";'
|
||||
|
||||
- it: "roles with only readonly grants readonly and revokes admin"
|
||||
set:
|
||||
databases:
|
||||
events:
|
||||
roles:
|
||||
readonly:
|
||||
- app
|
||||
documentSelector:
|
||||
path: metadata.name
|
||||
value: pg-test-init-script
|
||||
asserts:
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'REVOKE "events_admin" FROM "app";'
|
||||
- matchRegex:
|
||||
path: stringData["init.sh"]
|
||||
pattern: 'GRANT "events_readonly" TO "app";'
|
||||
Reference in new issue
Block a user