Files
gochat/deploy/docker/database_client_entrypoint.sh

126 lines
4.3 KiB
Bash
Executable File

#!/bin/sh
set -eu
is_local_database_host() {
database_host_value=$1
case $database_host_value in
'' | postgres | localhost | 127.*) return 0 ;;
esac
if [ "$(printf '%s' "$database_host_value" | tr -d '0:')" = 1 ]; then
return 0
fi
database_ipv6_prefix=${database_host_value%:*}
database_ipv6_tail=${database_host_value##*:}
database_ipv6_marker=$(printf '%s' "$database_ipv6_prefix" | tr -d '0:')
case $database_ipv6_tail in
0.0.0.1) [ -z "$database_ipv6_marker" ] && return 0 ;;
127.*) [ "$database_ipv6_marker" = ffff ] && return 0 ;;
esac
database_ipv6_high=${database_ipv6_prefix##*:}
database_ipv6_prefix=${database_ipv6_prefix%:*}
database_ipv6_marker=$(printf '%s' "$database_ipv6_prefix" | tr -d '0:')
case $database_ipv6_high in
7f[0-9a-f][0-9a-f]) [ "$database_ipv6_marker" = ffff ] && return 0 ;;
esac
return 1
}
validate_production_database_dsn() {
database_dsn=$1
database_dsn_label=${2:-production database DSN}
database_dsn_uses_certificate_files=0
if [ -z "$database_dsn" ]; then
echo "$database_dsn_label is required" >&2
return 1
fi
database_authority=${database_dsn#*://}
database_authority=${database_authority%%/*}
database_hostport=${database_authority##*@}
case $database_hostport in
\[* ) database_host=${database_hostport#\[}; database_host=${database_host%%\]*} ;;
* ) database_host=${database_hostport%%:*} ;;
esac
database_host=$(printf '%s' "$database_host" | tr '[:upper:]' '[:lower:]')
database_host=${database_host%.}
database_host=${database_host%%%*}
if is_local_database_host "$database_host"; then
echo "$database_dsn_label must use an external PostgreSQL host" >&2
return 1
fi
database_query=
case $database_dsn in
*\?*) database_query=${database_dsn#*\?}; database_query=${database_query%%#*} ;;
esac
sslmode_count=0
sslmode=
sslrootcert_count=0
sslcert_count=0
sslkey_count=0
database_parameters=$database_query
while [ -n "$database_parameters" ]; do
case $database_parameters in
*'&'*) database_parameter=${database_parameters%%&*}; database_parameters=${database_parameters#*&} ;;
*) database_parameter=$database_parameters; database_parameters= ;;
esac
database_key=${database_parameter%%=*}
database_value=${database_parameter#*=}
case $database_key in
sslmode) sslmode_count=$((sslmode_count + 1)); sslmode=$database_value ;;
sslrootcert)
sslrootcert_count=$((sslrootcert_count + 1))
[ "$database_value" = /run/secrets/external-db-ca.crt ] || { echo "$database_dsn_label sslrootcert must use /run/secrets/external-db-ca.crt" >&2; return 1; }
;;
sslcert)
sslcert_count=$((sslcert_count + 1))
[ "$database_value" = /run/secrets/external-db-client.crt ] || { echo "$database_dsn_label sslcert must use /run/secrets/external-db-client.crt" >&2; return 1; }
;;
sslkey)
sslkey_count=$((sslkey_count + 1))
[ "$database_value" = /run/secrets/external-db-client.key ] || { echo "$database_dsn_label sslkey must use /run/secrets/external-db-client.key" >&2; return 1; }
;;
esac
done
if [ "$sslmode_count" -ne 1 ]; then
echo "$database_dsn_label must contain exactly one sslmode" >&2
return 1
fi
if [ "$sslmode" != disable ] && [ "$sslmode" != verify-ca ] && [ "$sslmode" != verify-full ]; then
echo "$database_dsn_label sslmode must be disable, verify-ca or verify-full" >&2
return 1
fi
tls_count=$((sslrootcert_count + sslcert_count + sslkey_count))
if [ "$tls_count" -ne 0 ]; then
database_dsn_uses_certificate_files=1
if [ "$sslrootcert_count" -ne 1 ] || [ "$sslcert_count" -ne 1 ] || [ "$sslkey_count" -ne 1 ]; then
echo "$database_dsn_label must contain each fixed TLS certificate parameter exactly once" >&2
return 1
fi
fi
}
dsn=${GOCHAT_DATABASE_DSN:-${DATA_SOURCE_NAME:-}}
validate_production_database_dsn "$dsn"
if [ "${1:-}" = --preflight ]; then
exit 0
fi
if [ "$database_dsn_uses_certificate_files" -eq 1 ]; then
for file in /run/secrets/external-db-ca.crt /run/secrets/external-db-client.crt /run/secrets/external-db-client.key; do
[ -f "$file" ] && [ -r "$file" ] || { echo "database TLS file is missing or unreadable: $file" >&2; exit 1; }
done
fi
if [ "${1:-}" = --check ]; then
exit 0
fi
exec "$@"