From cecee585907800e1254ae0dfea6daa0cde885b70 Mon Sep 17 00:00:00 2001 From: Bruno Willenborg Date: Thu, 23 Feb 2023 15:42:33 +0100 Subject: [PATCH] Make role and DB creation idempotent --- CHANGELOG.md | 1 + .../templates/postgis-configMap-init.yml | 81 ++++++++++++++----- 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a58fb92..e989be8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ For releases `< 1.0.0` minor version step indicate breaking changes. - Minor docs update for CKAN api token values - Update PostGIS chart to PostgreSQL 15, PostGIS 3.3 - Reworked database initialization scripts + - Made role and database creation idempotent - DB users for CKAN and datastore databases are no longer superusers. Separate credentials for the postgres database superuser can now be specified in values. diff --git a/charts/sddi-ckan/charts/postgis/templates/postgis-configMap-init.yml b/charts/sddi-ckan/charts/postgis/templates/postgis-configMap-init.yml index 24d73c8..041c4f1 100644 --- a/charts/sddi-ckan/charts/postgis/templates/postgis-configMap-init.yml +++ b/charts/sddi-ckan/charts/postgis/templates/postgis-configMap-init.yml @@ -19,19 +19,55 @@ data: psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL -- CKAN role - CREATE ROLE {{ .Values.global.db.auth.username | default .Values.db.auth.username | quote }} - NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN - PASSWORD {{ .Values.global.db.auth.password | default .Values.db.auth.password | squote }}; + DO + \$do\$ + BEGIN + IF EXISTS ( + SELECT FROM pg_catalog.pg_roles + WHERE rolname = {{ .Values.global.db.auth.username | default .Values.db.auth.username | squote }}) THEN + + RAISE NOTICE 'Role {{ .Values.global.db.auth.username | default .Values.db.auth.username | quote }} already exists. Skipping.'; + ELSE + CREATE ROLE {{ .Values.global.db.auth.username | default .Values.db.auth.username | quote }} + NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN + PASSWORD {{ .Values.global.db.auth.password | default .Values.db.auth.password | squote }}; + END IF; + END + \$do\$; -- Datastore RW - CREATE ROLE {{ .Values.global.datastore.auth.rw.username | default .Values.datastore.auth.rw.username | quote }} - NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN - PASSWORD {{ .Values.global.datastore.auth.rw.password | default .Values.datastore.auth.rw.password | squote }}; + DO + \$do\$ + BEGIN + IF EXISTS ( + SELECT FROM pg_catalog.pg_roles + WHERE rolname = {{ .Values.global.datastore.auth.rw.username | default .Values.datastore.auth.rw.username | squote }}) THEN + + RAISE NOTICE 'Role {{ .Values.global.datastore.auth.rw.username | default .Values.datastore.auth.rw.username | quote }} already exists. Skipping.'; + ELSE + CREATE ROLE {{ .Values.global.datastore.auth.rw.username | default .Values.datastore.auth.rw.username | quote }} + NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN + PASSWORD {{ .Values.global.datastore.auth.rw.password | default .Values.datastore.auth.rw.password | squote }}; + END IF; + END + \$do\$; -- Datastore RO - CREATE ROLE {{ .Values.global.datastore.auth.ro.username | default .Values.datastore.auth.ro.username | quote }} - NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN - PASSWORD {{ .Values.global.datastore.auth.ro.password | default .Values.datastore.auth.ro.password | squote }}; + DO + \$do\$ + BEGIN + IF EXISTS ( + SELECT FROM pg_catalog.pg_roles + WHERE rolname = {{ .Values.global.datastore.auth.ro.username | default .Values.datastore.auth.ro.username | squote }}) THEN + + RAISE NOTICE 'Role {{ .Values.global.datastore.auth.ro.username | default .Values.datastore.auth.ro.username | quote }} already exists. Skipping.'; + ELSE + CREATE ROLE {{ .Values.global.datastore.auth.ro.username | default .Values.datastore.auth.ro.username | quote }} + NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN + PASSWORD {{ .Values.global.datastore.auth.ro.password | default .Values.datastore.auth.ro.password | squote }}; + END IF; + END + \$do\$; EOSQL @@ -44,17 +80,26 @@ data: echo "Create databases..." export PGPASSWORD="$POSTGRES_PASSWORD" - psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - -- CKAN database - CREATE DATABASE {{ .Values.global.db.dbname | default .Values.db.dbname | quote }} - OWNER {{ .Values.global.db.auth.username | default .Values.db.auth.username | quote }} - ENCODING 'utf-8'; + # CKAN database + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -tc \ + "SELECT 1 FROM pg_database WHERE datname = {{ .Values.global.db.dbname | default .Values.db.dbname | squote }}" | grep -q 1 || \ + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + + CREATE DATABASE {{ .Values.global.db.dbname | default .Values.db.dbname | quote }} + OWNER {{ .Values.global.db.auth.username | default .Values.db.auth.username | quote }} + ENCODING 'utf-8'; + + EOSQL + + # Datastore database + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -tc \ + "SELECT 1 FROM pg_database WHERE datname = {{ .Values.global.datastore.dbname | default .Values.datastore.dbname | squote }}" | grep -q 1 || \ + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - -- Datastore database - CREATE DATABASE {{ .Values.global.datastore.dbname | default .Values.datastore.dbname | quote }} - OWNER {{ .Values.global.datastore.auth.rw.username | default .Values.datastore.auth.rw.username | quote }} - ENCODING 'utf-8'; + CREATE DATABASE {{ .Values.global.datastore.dbname | default .Values.datastore.dbname | quote }} + OWNER {{ .Values.global.datastore.auth.rw.username | default .Values.datastore.auth.rw.username | quote }} + ENCODING 'utf-8'; EOSQL