You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

144 lines
4.1 KiB

#!/bin/bash
. /etc/shlib
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && SOURCED=true
include common
include pretty
include cmdline
desc='Adds YAML key quite crudely in given compose.yml.'
help="\
$WHITE$exname$NORMAL will find a add or replace SSH key to
given identifier for rsync-backup-target charm.
For now, it only use detection of '## INSERTION-POINT' to manage
edition of 'compose.yml', and verification it didn't break anything
before overwriting.
"
[ "$SOURCED" ] && return 0
##
## Command line processing
##
# remove all lines from regex to regex (not included).
remove_lines_from_to() {
local from="$1" to="$2"
sed -r "/$from/,/$to/{/$to/"'!'"d};/$from/d"
}
check_valid_yaml() {
shyaml get-value >/dev/null 2>&1;
}
cmdline.spec.gnu
cmdline.spec.reporting
service_name=${SERVICE_NAME:-rsync-backup-target}
compose_file=${COMPOSE_FILE:-/etc/compose/compose.yml}
cmdline.spec::valued:--compose-file,-f:usage() {
echo "Compose file location. Defaults to '/etc/compose/compose.yml'"; }
cmdline.spec::valued:--compose-file,-f:run() { compose_file="$1"; }
cmdline.spec::valued:--service-name,-s:usage() {
echo "YAML service name in compose file to check for existence of key. Defaults to 'rsync-backup-target'"; }
cmdline.spec::valued:--service-name,-s:run() { service_name="$1"; }
cmdline.spec::cmd:__main__:run() {
: :posarg: DOMAIN 'domain identifier'
: :posarg: SSH_PUBLIC_KEY 'ssh public key'
if ! existing_domains=$(shyaml keys "${service_name//./\\.}.options.keys" < "$compose_file"); then
err "Couldn't query file '$compose_file' for keys of" \
"service ${DARKYELLOW}${service_name}${NORMAL}."
exit 1
fi
content=$(cat "$compose_file")
if echo "$existing_domains" | grep "^${DOMAIN}$" >/dev/null 2>&1; then
if ! prev_key=$(shyaml get-value "${service_name//./\\.}.options.keys.${DOMAIN//./\\.}" \
< "$compose_file"); then
err "Couldn't query file '$compose_file' for key of domain '$DOMAIN'."
exit 1
fi
if [ "${prev_key}" == "$SSH_PUBLIC_KEY" ]; then
echo "Key was already setup."
exit 0
fi
content=$(echo "$content" | remove_lines_from_to '^ '"${DOMAIN//./\\.}"': ".*\\$' \
'^ ([A-Za-z0-9.-]+: "|## END MARKER)')
if [ -z "$content" ]; then
err "Didn't manage to remove key to compose file '$DOMAIN' in '$compose_file'."
exit 1
fi
if [ "$content" == "$(cat "$compose_file")" ]; then
err "Couldn't remove previous key for '$DOMAIN' in '$compose_file'."
exit 1
fi
## check we didn't break yaml
if ! echo "$content" | check_valid_yaml; then
err "Couldn't safely remove previous key for '$DOMAIN' in '$compose_file'."
exit 1
fi
fi
excerpt=$(cat <<EOF
$DOMAIN: "$(
echo "$SSH_PUBLIC_KEY" |
fold -w 67 | sed -r 's/$/\\/g;2,$ s/^/ /g;$,$ s/\\$//g')"
EOF
)
excerpt="${excerpt//\\/\\\\\\}"
content="$(echo "$content" | sed -r '/^ ## INSERTION-POINT/a\'"${excerpt}")"
if [ -z "$content" ]; then
err "Didn't manage to add key to compose file '$DOMAIN' in '$compose_file'."
exit 1
fi
if ! echo "$content" | check_valid_yaml; then
err "Couldn't safely add key to compose file '$DOMAIN' in '$compose_file'."
exit 1
fi
if diff=$(diff -u "$compose_file" <(echo "$content")); then
err "No difference, this is not expected, and something went wrong."
exit 1
fi
echo "${WHITE}Applying these changes:${NORMAL}"
echo "$diff"
cp "$compose_file" "${compose_file}.old"
echo "$content" > "$compose_file"
## reloading (could be much faster)
compose --debug down && compose --debug up
if [ "$?" == 0 ]; then
echo "Added key, and restarted service ${DARKYELLOW}$service_name${NORMAL}."
else
echo "something went wrong ! Should check the state of '$DOMAIN' !!"
exit 1
fi
}
cmdline::parse "$@"