|
@ -476,6 +476,121 @@ EOF |
|
|
export -f yaml_key_val_str |
|
|
export -f yaml_key_val_str |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## |
|
|
|
|
|
## Intended for charm |
|
|
|
|
|
## |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
password:get() { |
|
|
|
|
|
local service="$SERVICE_NAME" label="$1" type="$2" size="${2:-32}" |
|
|
|
|
|
|
|
|
|
|
|
local password_file |
|
|
|
|
|
password_file="$(password:get-location "$label" "$type" "$size")" || return 1 |
|
|
|
|
|
cat "$password_file" |
|
|
|
|
|
} |
|
|
|
|
|
export -f password:get |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
password:get-location() { |
|
|
|
|
|
local service="$SERVICE_NAME" label="$1" type="$2" size="${2:-32}" |
|
|
|
|
|
|
|
|
|
|
|
if [ -z "$service" ]; then |
|
|
|
|
|
err "${FUNCNAME[0]}: should be called from a charm hook" |
|
|
|
|
|
return 1 |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
charm=$(get_service_charm "$service") || return 1 |
|
|
|
|
|
case "$type" in |
|
|
|
|
|
"internal") |
|
|
|
|
|
: |
|
|
|
|
|
;; |
|
|
|
|
|
"user") |
|
|
|
|
|
if ! fn.exists "$charm:password:check"; then |
|
|
|
|
|
err "Charm '$charm' doesn't provide a '$charm:password:check' function." |
|
|
|
|
|
echo " This function is required to check if a user password was changed." >&2 |
|
|
|
|
|
return 1 |
|
|
|
|
|
fi |
|
|
|
|
|
;; |
|
|
|
|
|
*) |
|
|
|
|
|
err "${FUNCNAME[0]}: unknown type '$type'" |
|
|
|
|
|
echo " Should be 'internal' or 'user'." >&2 |
|
|
|
|
|
return 1 |
|
|
|
|
|
;; |
|
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
|
|
local password_file="$SERVICE_DATASTORE"/.compose/passwords/"$type"/"$label" |
|
|
|
|
|
|
|
|
|
|
|
if ! [ -f "$password_file" ]; then |
|
|
|
|
|
info "Generating password" >&2 |
|
|
|
|
|
mkdir -p "${password_file%/*}" && |
|
|
|
|
|
umask 077 && |
|
|
|
|
|
openssl rand -base64 32 | tr -d '\n' > "$password_file" |
|
|
|
|
|
e "$password_file" |
|
|
|
|
|
return 0 |
|
|
|
|
|
fi |
|
|
|
|
|
if [ "$type" != "user" ]; then |
|
|
|
|
|
info "Using existing secret password" >&2 |
|
|
|
|
|
e "$password_file" |
|
|
|
|
|
return 0 |
|
|
|
|
|
fi |
|
|
|
|
|
if [ -s "$password_file" ]; then |
|
|
|
|
|
## password was already set by user through the service |
|
|
|
|
|
e "$password_file" |
|
|
|
|
|
return 0 |
|
|
|
|
|
fi |
|
|
|
|
|
if ! out=$("$charm:password:check" "$label" "$password_file"); then |
|
|
|
|
|
err "Failed to check password for '$label' in '$charm'." |
|
|
|
|
|
return 1 |
|
|
|
|
|
fi |
|
|
|
|
|
case "$out" in |
|
|
|
|
|
"changed") |
|
|
|
|
|
info "Password for '$label' has changed, forgetting it." >&2 |
|
|
|
|
|
e "" > "$password_file" ## empty file |
|
|
|
|
|
e "$password_file" |
|
|
|
|
|
return 0 |
|
|
|
|
|
;; |
|
|
|
|
|
"ok") |
|
|
|
|
|
e "$password_file" |
|
|
|
|
|
return 0 |
|
|
|
|
|
;; |
|
|
|
|
|
*) |
|
|
|
|
|
err "Unknown return value from '$charm:password:check': $out" |
|
|
|
|
|
return 1 |
|
|
|
|
|
;; |
|
|
|
|
|
esac |
|
|
|
|
|
} |
|
|
|
|
|
export -f password:get-location |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
passwords:advertise() { |
|
|
|
|
|
local services file label |
|
|
|
|
|
services=("$@") |
|
|
|
|
|
local service |
|
|
|
|
|
complete_msg="" |
|
|
|
|
|
for service in "${services[@]}"; do |
|
|
|
|
|
dir="$DATASTORE"/"$service"/.compose/passwords/user |
|
|
|
|
|
[ -d "$dir" ] || continue |
|
|
|
|
|
msg="" |
|
|
|
|
|
for file in "$dir"/*; do |
|
|
|
|
|
[ -s "$file" ] || continue |
|
|
|
|
|
ls -al "$file" >&2 |
|
|
|
|
|
label=${file##*/} |
|
|
|
|
|
msg+=" - $label is $(cat "$file")"$'\n' |
|
|
|
|
|
done |
|
|
|
|
|
if [ -n "$msg" ]; then |
|
|
|
|
|
msg=" ${DARKYELLOW}$service${NORMAL}:"$'\n'"$msg" |
|
|
|
|
|
fi |
|
|
|
|
|
complete_msg+="$msg" |
|
|
|
|
|
done |
|
|
|
|
|
if [ -n "$complete_msg" ]; then |
|
|
|
|
|
echo |
|
|
|
|
|
echo "${WHITE}Compose generated passwords${NORMAL}:" |
|
|
|
|
|
echo " (Consider changing these password in their respective services)" |
|
|
|
|
|
echo |
|
|
|
|
|
echo "$complete_msg" |
|
|
|
|
|
fi >&2 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
## |
|
|
## |
|
|
## Docker |
|
|
## Docker |
|
|
## |
|
|
## |
|
|