Browse Source

new: [postgres-stub] add service mapping for ``dbname`` and ``user``.

upd
Valentin Lab 2 months ago
parent
commit
5be32bebd9
  1. 17
      postgres-stub/README.org
  2. 11
      postgres-stub/hooks/postgres_database-relation-joined
  3. 86
      postgres-stub/lib/common

17
postgres-stub/README.org

@ -44,3 +44,20 @@ myservice:
#+end_src
** database name and user automatic assignation
It can be useful, if you have several services in the same ~compose.yml~
to assign database names and user automatically to avoid repeating them.
#+begin_src yaml
my-postgres-stub:
charm: postgres-stub
options:
host: my-host.mydomain.fr:20432
service-dbname-map:
service1: u_foo
## Leveraging regex replacement for all other services
.*: xyz_$0
service-user-map:
.*: u_$0
#+end_src

11
postgres-stub/hooks/postgres_database-relation-joined

@ -7,14 +7,19 @@
## - the target of the link is launched first, and get a chance to ``relation-set``
## - both side of the scripts get to use ``relation-get``.
. lib/common
set -e
DBNAME=$(relation-get dbname) || {
DBNAME="$BASE_SERVICE_NAME"
DBNAME=$(service:map:get_one "dbname") || exit 1
DBNAME="${DBNAME:-$BASE_SERVICE_NAME}"
relation-set dbname "$DBNAME"
}
USER=$(relation-get user) || {
USER="$BASE_SERVICE_NAME"
USER=$(service:map:get_one "user") || exit 1
USER="${USER:-$BASE_SERVICE_NAME}"
relation-set user "$USER"
}
@ -41,8 +46,6 @@ PORT=${PORT:-5432}
relation-set host "$HOST"
relation-set port "$PORT"
. lib/common
set -e
if ! PASSWORD="$(relation-get password 2>/dev/null)"; then

86
postgres-stub/lib/common

@ -3,6 +3,92 @@
POSTGRES_IMAGE=docker.0k.io/postgres:12.15.0-myc
## Mappings
replace_by_rematch_pattern() {
local input="$1" output="" char next_char i
# Loop through each character in the string
for (( i=0; i<${#input}; i++ )); do
char="${input:$i:1}"
# If a dollar sign is found
if [[ "$char" == '$' ]]; then
next_char="${input:$((i+1)):1}"
# Check if next character is a digit
if [[ "$next_char" =~ [0-9] ]]; then
# Replace $N with ${rematch[N]}
output+='${rematch['"$next_char"']}'
((i++)) # Skip next character as it's already processed
continue
fi
fi
output+="$char"
done
echo "$output"
}
export -f replace_by_rematch_pattern
service:map:get_one() {
local map_label="$1"
res=()
if service_map=$(options-get "service-${map_label}-map" 2>/dev/null) &&
[ -n "$service_map" ]; then
while read-0 regex map; do
if [[ "$BASE_SERVICE_NAME" =~ ^$regex$ ]]; then
rematch=("${BASH_REMATCH[@]}")
maps=()
type=$(e "$map" | shyaml -q get-type 2>/dev/null) || true
value=$(e "$map" | shyaml -q get-value -y 2>/dev/null) || true
case "$type" in
sequence)
while read-0 m; do
if [[ "$m" != "None" ]] && [ -n "$m" ]; then
maps+=("$m")
fi
done < <(e "$value" | shyaml get-values-0)
;;
str)
if ! m=$(e "$value" | shyaml get-value 2>/dev/null); then
err "Failed to get mapping value from config."
return 1
fi
[ -z "$m" ] && continue
maps+=("$m")
;;
NoneType|"")
:
;;
esac
for map in "${maps[@]}"; do
if ! [[ "$map" =~ ^([a-zA-Z0-9_*\{\}\ \,.-]|\$[0-9])+$ ]]; then
err "Invalid mapping value '$map' in ${WHITE}service-${map_label}-map$NORMAL option."
return 1
fi
map="${map//\*/\\*}" ## protect star from eval
map=$(replace_by_rematch_pattern "$map")
res+=($(set -- "${BASH_REMATCH[@]}"; eval echo "${map//\*/\\*}"))
done
break
fi
done < <(e "$service_map" | yq e -0 'to_entries | .[] | [.key, .value] |.[]')
fi
if [ "${#res[@]}" -gt 1 ]; then
err "Multiple databases found for service '$BASE_SERVICE_NAME': ${dbnames[*]}." \
"Please specify a single database in the service-${map_label}-map option."
return 1
fi
echo "${res[0]}"
}
##
## DB
##
ddb () {
docker run --rm -i \
-e PGPASSWORD="$PASSWORD" \

Loading…
Cancel
Save