173 lines
5.6 KiB
Bash
Executable file
173 lines
5.6 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
# Usage: $0 [ -f old_password_file | -i old_vault_id ] [ -F new_password_file | -I new_vault_id ] vars_file.yaml
|
|
|
|
usage() {
|
|
printf '%s\n' "USAGE: $0 [ -f old_password_file | -i old_vault_id ] [ -F new_password_file | -I new_vault_id ] <vars_file.yaml>"
|
|
printf '%s\n' "Example: $0 -f old.passphrase -I other/ansible-vault/default@pass-client.sh inventory/group_vars/all.yaml"
|
|
}
|
|
|
|
hasold=0
|
|
hasnew=0
|
|
|
|
if [ $# -ge 1 ]; then
|
|
while getopts 'f:i:F:I:h' opt; do
|
|
case $opt in
|
|
f) OLD_PASSWORD_FILE=$OPTARG
|
|
OLD_PASS_OPT="--vault-password-file ${OLD_PASSWORD_FILE}"
|
|
hasold=1 ;;
|
|
i) OLD_VAULT_ID=$OPTARG
|
|
OLD_PASS_OPT="--vault-id ${OLD_VAULT_ID}"
|
|
hasold=1 ;;
|
|
F) NEW_PASSWORD_FILE=$OPTARG
|
|
NEW_PASS_OPT="--vault-password-file ${NEW_PASSWORD_FILE}"
|
|
REKEY_NEW_PASS_OPT="--new-vault-password-file ${NEW_PASSWORD_FILE}"
|
|
hasnew=1 ;;
|
|
I) NEW_VAULT_ID=$OPTARG
|
|
NEW_PASS_OPT="--vault-id ${NEW_VAULT_ID}"
|
|
REKEY_NEW_PASS_OPT="--new-vault-id ${NEW_VAULT_ID}"
|
|
hasnew=1 ;;
|
|
h) usage && exit 0;;
|
|
esac
|
|
done
|
|
fi;
|
|
|
|
shift $(($OPTIND-1))
|
|
|
|
if [ "x$OLD_PASSWORD_FILE" != "x" ] && [ "x$OLD_VAULT_ID" != "x" ]; then
|
|
printf '%s\n' "ERROR: Both old_password_file and old_vault_id provided."
|
|
usage && exit 1;
|
|
fi
|
|
|
|
if [ "x$NEW_PASSWORD_FILE" != "x" ] && [ "x$NEW_VAULT_ID" != "x" ]; then
|
|
printf '%s\n' "ERROR: Both new_password_file and new_vault_id provided."
|
|
usage && exit 1;
|
|
fi
|
|
|
|
if [ $# -eq 1 ] && [ $hasold -eq 1 ] && [ $hasnew -eq 1 ] ; then
|
|
VARS_FILE="$1"
|
|
else
|
|
usage && exit 1;
|
|
fi;
|
|
|
|
FILE=$(cat "$VARS_FILE")
|
|
# Read file line by line
|
|
# when line is of type ^[^(: )]: !vault |$
|
|
# get variable name
|
|
# go to vault mode
|
|
# if next line begins with a ' ', stay in vault mode and get the number of spaces before '$ANSIBLE_VAULT;(.*)'
|
|
# else, exit vault mode
|
|
# if next line begins with a ' ' (number of spaces matching indentation), stay in vault mode
|
|
# else, exit vault mode
|
|
isvault=0
|
|
isvault_data=0
|
|
n=0
|
|
prevline=''
|
|
while IFS= read -r line; do
|
|
if [ $isvault -eq 0 ]; then
|
|
# if the previous line exists and is a "normal" line,
|
|
# print it
|
|
if [ $n -gt 0 ]; then
|
|
# printf '%s\n' "$n $prevline"
|
|
printf '%s\n' "$prevline"
|
|
fi
|
|
# if we are not in a vault yet, check if the current line
|
|
# looks like a vaulted var
|
|
printf '%s\n' "$line" | grep -q '^[^#:]*: !vault |$'
|
|
if [ $? -eq 0 ]; then
|
|
# if the line looks like a vaulted var, save its name
|
|
var_name=$(printf '%s\n' "$line" | cut -d':' -f1)
|
|
isvault=1
|
|
else
|
|
# if the line doesn't look like a vaulted var, do nothing
|
|
isvault=0
|
|
fi
|
|
else
|
|
# the previous line was a vault line
|
|
if [ $isvault_data -eq 0 ]; then
|
|
# if we are not in vaulted data yet, check if the line
|
|
# starts with a space
|
|
printf '%s\n' "$line" | grep -q '^ .*'
|
|
if [ $? -eq 0 ]; then
|
|
# if this is the first line of vaulted data,
|
|
# save the line indentation
|
|
data_indent=$(printf '%s\n' "$line" | grep -o '^ *')
|
|
# and print the var name
|
|
# printf '%s\n' "var_name: $var_name"
|
|
isvault_data=1
|
|
# printf '%s\n' "${data_indent}nothing"
|
|
# printf '%s\n' "ANSIBLE_CALLBACK_RESULT_FORMAT=yaml ansible localhost -m debug -a var=${var_name} -e @${VARS_FILE} ${OLD_PASS_OPT} 2>/dev/null | grep -v 'localhost | .* =>' | sed s/'^ *'//g" >&2
|
|
var_value_plain=$( ANSIBLE_CALLBACK_RESULT_FORMAT=yaml ansible localhost -m debug -a var=${var_name} -e @${VARS_FILE} ${OLD_PASS_OPT} 2>/dev/null | grep -v 'localhost | .* =>' | sed s/'^[^:]*: '//g )
|
|
if [ $? -eq 0 ]; then
|
|
# and print the var name and its plain data
|
|
# printf '%s\n' "var_name: $var_name" >&2
|
|
# printf '%s\n' "$var_value_plain"
|
|
# printf '%s\n' "ansible-vault encrypt_string \"${var_value_plain}\" --name ${var_name} ${NEW_PASS_OPT}" >&2
|
|
ansible-vault encrypt_string "${var_value_plain}" --name ${var_name} ${NEW_PASS_OPT} 2>/dev/null
|
|
printf '\n'
|
|
else
|
|
printf '%s\n' "Error when decrypting data for variable ${var_name}. Skipping." >&2
|
|
fi
|
|
else
|
|
# if this is not the first line of vaulted data,
|
|
# we are not in a vault
|
|
isvault=0
|
|
isvault_data=0
|
|
# reset vault-related variables
|
|
var_name=''
|
|
data_indent=''
|
|
# # exit with an error
|
|
# printf '%s\n' "ERROR: No vault data found at line $n, exiting." >&2
|
|
# exit 2
|
|
# check if the current line
|
|
# looks like a vaulted var
|
|
printf '%s\n' "$line" | grep -q '^[^#: ]*: !vault |$'
|
|
if [ $? -eq 0 ]; then
|
|
# if the line looks like a vaulted var, save its name
|
|
var_name=$(printf '%s\n' "$line" | cut -d':' -f1)
|
|
isvault=1
|
|
else
|
|
# if the line doesn't look like a vaulted var, do nothing
|
|
isvault=0
|
|
fi
|
|
fi
|
|
else
|
|
# if we are in the vaulted data section, check if the line
|
|
# starts with the same indentation as the first
|
|
# echo "${data_indent}plop"
|
|
# printf '%s\n' "$line"
|
|
printf '%s\n' "$line" | grep -qE "^${data_indent}[^ ]+"
|
|
if [ $? -eq 0 ]; then
|
|
# if we are still in the vaulted data section, do nothing
|
|
# printf '%s\n' "${data_indent}nothing"
|
|
:
|
|
else
|
|
# if we are out of the vaulted data section, register it
|
|
isvault_data=0
|
|
isvault=0
|
|
# reset vault-related variables
|
|
var_name=''
|
|
data_indent=''
|
|
# check if the current line
|
|
# looks like a vaulted var
|
|
printf '%s\n' "$line" | grep -q '^[^#: ]*: !vault |$'
|
|
if [ $? -eq 0 ]; then
|
|
# if the line looks like a vaulted var, save its name
|
|
var_name=$(printf '%s\n' "$line" | cut -d':' -f1)
|
|
isvault=1
|
|
else
|
|
# if the line doesn't look like a vaulted var, do nothing
|
|
isvault=0
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
prevline="$line"
|
|
n=$(( $n + 1 ))
|
|
done <<EOF
|
|
$FILE
|
|
EOF
|
|
|
|
# print the last line
|
|
# printf '%s\n' "$n $prevline"
|
|
printf '%s\n' "$prevline"
|