[postgres] Fix database deletion lifecycle management (#2247)
## What this PR does Previously, removing a database from `values.databases` had no effect — the database and its associated roles (`<db>_admin`, `<db>_readonly`) persisted in PostgreSQL indefinitely. This made it impossible to declaratively manage database lifecycle via Helm values. Added two cleanup stages to the init script, mirroring the existing user deletion logic: - **Delete databases** that have the `database managed by helm` comment but are no longer listed in `values.databases` — active connections are terminated before dropping - **Delete orphaned roles** (`<db>_admin`, `<db>_readonly`) with proper membership revocation (`REVOKE ... FROM`) before `REASSIGN OWNED` / `DROP OWNED` / `DROP ROLE` This also fixes the reported issue where creating a database, removing it, and creating it again would silently retain stale data from the first instance. ### Release note ```release-note [postgres] Databases removed from `values.databases` are now properly dropped along with their associated roles. Previously removed databases and roles would persist indefinitely. ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Enhanced database initialization to automatically remove databases and roles that were removed from your Helm configuration, avoiding orphaned resources. * Now force-terminates active sessions, reassigns owned objects, and cleans up role memberships to ensure reliable removals. * Improves consistency of database state during upgrades and configuration changes. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
commit
4f22f075e0
1 changed files with 32 additions and 0 deletions
|
|
@ -66,6 +66,38 @@ stringData:
|
|||
EOT
|
||||
done
|
||||
|
||||
echo "== delete databases"
|
||||
MANAGED_DBS=$(psql -v ON_ERROR_STOP=1 -t -A -c "SELECT datname FROM pg_database d JOIN pg_shdescription s ON d.oid = s.objoid WHERE s.description = 'database managed by helm'")
|
||||
DEFINED_DBS="{{ join " " (keys .Values.databases) }}"
|
||||
DELETE_DBS=$(for db in $MANAGED_DBS; do case " $DEFINED_DBS " in *" $db "*) :;; *) echo $db;; esac; done)
|
||||
|
||||
echo "databases to delete: $DELETE_DBS"
|
||||
for db in $DELETE_DBS; do
|
||||
psql -v ON_ERROR_STOP=1 --echo-all -c "DROP DATABASE IF EXISTS \"$db\" WITH (FORCE);"
|
||||
done
|
||||
|
||||
echo "== delete orphaned managed roles"
|
||||
MANAGED_ROLES=$(psql -v ON_ERROR_STOP=1 -t -A -c "SELECT rolname FROM pg_roles r JOIN pg_shdescription s ON r.oid = s.objoid WHERE s.description = 'role managed by helm'")
|
||||
DEFINED_ROLES="{{ range $database, $d := .Values.databases }}{{ $database }}_admin {{ $database }}_readonly {{ end }}"
|
||||
DELETE_ROLES=$(for role in $MANAGED_ROLES; do case " $DEFINED_ROLES " in *" $role "*) :;; *) echo $role;; esac; done)
|
||||
|
||||
echo "roles to delete: $DELETE_ROLES"
|
||||
for role in $DELETE_ROLES; do
|
||||
psql -v ON_ERROR_STOP=1 --echo-all <<EOT
|
||||
DO \$\$
|
||||
DECLARE
|
||||
member record;
|
||||
BEGIN
|
||||
FOR member IN SELECT m.rolname FROM pg_auth_members am JOIN pg_roles m ON am.member = m.oid JOIN pg_roles r ON am.roleid = r.oid WHERE r.rolname = '$role' LOOP
|
||||
EXECUTE format('REVOKE %I FROM %I', '$role', member.rolname);
|
||||
END LOOP;
|
||||
END\$\$;
|
||||
REASSIGN OWNED BY "$role" TO postgres;
|
||||
DROP OWNED BY "$role";
|
||||
DROP ROLE IF EXISTS "$role";
|
||||
EOT
|
||||
done
|
||||
|
||||
echo "== create databases and roles"
|
||||
{{- if .Values.databases }}
|
||||
psql -v ON_ERROR_STOP=1 --echo-all <<\EOT
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue