Files
dzentra_bot/infra/docker/postgres/init-application-role.sh

131 lines
3.2 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
set -eu
read_secret_file() {
secret_path=$1
if [ ! -r "$secret_path" ]; then
echo "Не удалось прочитать обязательный PostgreSQL secret file" >&2
return 1
fi
# Маркер сохраняет переводы строк внутри command substitution.
secret_with_marker="$(cat "$secret_path"; printf '\001')"
secret=${secret_with_marker%?}
carriage_return="$(printf '\r')"
newline='
'
case "$secret" in
*"${carriage_return}${newline}")
secret=${secret%"${carriage_return}${newline}"}
;;
*"${newline}")
secret=${secret%"${newline}"}
;;
*"${carriage_return}")
secret=${secret%"${carriage_return}"}
;;
esac
if [ -z "$(printf '%s' "$secret" | tr -d '[:space:]')" ]; then
echo "PostgreSQL secret file содержит пустое значение" >&2
return 1
fi
printf '%s' "$secret"
}
if [ -z "${APP_DB_USER:-}" ]; then
echo "APP_DB_USER должен содержать имя роли приложения" >&2
exit 1
fi
if [ "$APP_DB_USER" = "$POSTGRES_USER" ]; then
echo "APP_DB_USER не должен совпадать с PostgreSQL admin role" >&2
exit 1
fi
app_db_password="$(read_secret_file /run/secrets/db_password)"
# Официальный entrypoint уже прочитал secret file и применил собственную
# нормализацию конечных переводов строк. Сравниваем именно фактический пароль.
if [ -z "$(printf '%s' "${POSTGRES_PASSWORD:-}" | tr -d '[:space:]')" ]; then
echo "POSTGRES_PASSWORD должен содержать пароль admin role" >&2
exit 1
fi
postgres_admin_password=$POSTGRES_PASSWORD
if [ "$app_db_password" = "$postgres_admin_password" ]; then
echo "Пароли PostgreSQL admin и application roles должны различаться" >&2
exit 1
fi
export DZENTRA_APP_DB_PASSWORD="$app_db_password"
psql \
--no-psqlrc \
--single-transaction \
--set ON_ERROR_STOP=1 \
--username "$POSTGRES_USER" \
--dbname "$POSTGRES_DB" <<'SQL'
\getenv app_user APP_DB_USER
\getenv app_password DZENTRA_APP_DB_PASSWORD
SELECT format(
'CREATE ROLE %I LOGIN PASSWORD %L NOSUPERUSER NOCREATEDB '
'NOCREATEROLE INHERIT NOREPLICATION NOBYPASSRLS',
:'app_user',
:'app_password'
)
WHERE NOT EXISTS (
SELECT 1
FROM pg_catalog.pg_roles
WHERE rolname = :'app_user'
)
\gexec
SELECT format(
'ALTER ROLE %I WITH LOGIN PASSWORD %L NOSUPERUSER NOCREATEDB '
'NOCREATEROLE INHERIT NOREPLICATION NOBYPASSRLS',
:'app_user',
:'app_password'
)
\gexec
SELECT format(
'ALTER DATABASE %I OWNER TO %I',
current_database(),
:'app_user'
)
\gexec
SELECT format(
'REVOKE ALL ON DATABASE %I FROM PUBLIC',
current_database()
)
\gexec
SELECT format(
'GRANT CONNECT, TEMPORARY ON DATABASE %I TO %I',
current_database(),
:'app_user'
)
\gexec
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
SELECT format(
'GRANT USAGE, CREATE ON SCHEMA public TO %I',
:'app_user'
)
\gexec
SQL
unset DZENTRA_APP_DB_PASSWORD
unset app_db_password
unset postgres_admin_password