kolla-ansible/tools/kolla-ansible
Radosław Piliszek 32fc2599a6 Check that used Ansible can see Kolla Ansible
Fix-feature following up on the original check [1] to make it
test the correct interpreter.

Additionally, this change removes last, unneeded call to
random python - getting script directory is perfectly
doable in bash.

All checks are done from Python, not Ansible, due to its
performance. Python version feels snappy (0.2 s to check),
compared to sluggish Ansible (2.0 s to check).
What is more, relying on Ansible would require hacky solutions
to e.g. prevent custom config from interfering with it.
We might be willing to steer Ansible from Python in the future
anyhow.

[1] Icf0399d21b3fde8d530d73e6e7ee4a57665da276

Change-Id: Ib8f2e6b6672e7c06aa94bc226c4d72640d25d8c2
Closes-Bug: #1856346
2020-04-27 17:18:31 +02:00

458 lines
14 KiB
Bash
Executable File

#!/bin/bash
#
# This script can be used to interact with kolla via ansible.
function check_environment_coherence {
local ansible_path
ansible_path=$(which ansible)
if [[ $? -ne 0 ]]; then
echo "ERROR: Ansible is not installed in the current (virtual) environment." >&2
exit 1
fi
local ansible_shebang_line
ansible_shebang_line=$(head -n1 "$ansible_path")
if ! echo "$ansible_shebang_line" | egrep "^#!" &>/dev/null; then
echo "ERROR: Ansible script is malformed (missing shebang line)." >&2
exit 1
fi
local ansible_python_cmdline
# NOTE(yoctozepto): may have multiple parts
ansible_python_cmdline=${ansible_shebang_line#\#\!}
if ! $ansible_python_cmdline --version &>/dev/null; then
echo "ERROR: Ansible Python is not functional." >&2
echo "Tried '$ansible_python_cmdline'" >&2
exit 1
fi
# Check for existence of kolla_ansible module using Ansible's Python.
if ! $ansible_python_cmdline -c 'import kolla_ansible' &>/dev/null; then
echo "ERROR: kolla_ansible has to be available in the Ansible PYTHONPATH." >&2
echo "Please install both in the same (virtual) environment." >&2
exit 1
fi
local ansible_version_output
ansible_full_version=$($ansible_python_cmdline -c 'import ansible; print(ansible.__version__)')
if [[ $? -ne 0 ]]; then
echo "ERROR: Failed to obtain Ansible version:" >&2
echo "$ansible_full_version" >&2
exit 1
fi
local ansible_version
ansible_version=$(echo "$ansible_full_version" | egrep -o '^[0-9]+\.[0-9]+')
if [[ $? -ne 0 ]]; then
echo "ERROR: Failed to parse Ansible version:" >&2
echo "$ansible_full_version" >&2
exit 1
fi
local ANSIBLE_VERSION_MIN=2.8
local ANSIBLE_VERSION_MAX=2.9
if [[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ansible_version" | sort -V | head -n1) != "$ANSIBLE_VERSION_MIN" ]] ||
[[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ansible_version" | sort -V | tail -n1) != "$ANSIBLE_VERSION_MAX" ]]; then
echo "ERROR: Ansible version should be between $ANSIBLE_VERSION_MIN and $ANSIBLE_VERSION_MAX. Current version is $ANSIBLE_VERSION_HOST which is not supported."
exit 1
fi
}
function find_base_dir {
local dir_name
dir_name=$(cd "$(dirname "$0")" &>/dev/null && pwd)
if [ -z "$SNAP" ]; then
if [[ ${dir_name} == "/usr/bin" ]]; then
BASEDIR=/usr/share/kolla-ansible
elif [[ ${dir_name} == "/usr/local/bin" ]]; then
BASEDIR=/usr/local/share/kolla-ansible
elif [[ -n ${VIRTUAL_ENV} ]] && [[ ${dir_name} == "${VIRTUAL_ENV}/bin" ]]; then
BASEDIR="${VIRTUAL_ENV}/share/kolla-ansible"
else
BASEDIR="$(dirname ${dir_name})"
fi
else
BASEDIR="$SNAP/share/kolla-ansible"
fi
}
function process_cmd {
echo "$ACTION : $CMD"
$CMD
if [[ $? -ne 0 ]]; then
echo "Command failed $CMD"
exit 1
fi
}
function usage {
cat <<EOF
Usage: $0 COMMAND [options]
Options:
--inventory, -i <inventory_path> Specify path to ansible inventory file
--playbook, -p <playbook_path> Specify path to ansible playbook file
--configdir <config_path> Specify path to directory with globals.yml
--key -k <key_path> Specify path to ansible vault keyfile
--help, -h Show this usage information
--tags, -t <tags> Only run plays and tasks tagged with these values
--skip-tags <tags> Only run plays and tasks whose tags do not match these values
--extra, -e <ansible variables> Set additional variables as key=value or YAML/JSON passed to ansible-playbook
--passwords <passwords_path> Specify path to the passwords file
--limit <host> Specify host to run plays
--forks <forks> Number of forks to run Ansible with
--vault-id <@prompt or path> Specify @prompt or password file (Ansible >= 2.4)
--ask-vault-pass Ask for vault password
--vault-password-file <path> Specify password file for vault decrypt
--verbose, -v Increase verbosity of ansible-playbook
Environment variables:
EXTRA_OPTS Additional arguments to pass to ansible-playbook
Commands:
prechecks Do pre-deployment checks for hosts
check Do post-deployment smoke tests
mariadb_recovery Recover a completely stopped mariadb cluster
mariadb_backup Take a backup of MariaDB databases
--full (default)
--incremental
bootstrap-servers Bootstrap servers with kolla deploy dependencies
destroy Destroy Kolla containers, volumes and host configuration
--include-images to also destroy Kolla images
--include-dev to also destroy dev mode repos
deploy Deploy and start all kolla containers
deploy-bifrost Deploy and start bifrost container
deploy-servers Enroll and deploy servers with bifrost
deploy-containers Only deploy and start containers (no config updates or bootstrapping)
post-deploy Do post deploy on deploy node
pull Pull all images for containers (only pulls, no running container changes)
reconfigure Reconfigure OpenStack service
stop Stop Kolla containers
certificates Generate self-signed certificate for TLS *For Development Only*
upgrade Upgrades existing OpenStack Environment
upgrade-bifrost Upgrades an existing bifrost container
genconfig Generate configuration files for enabled OpenStack services
prune-images Prune orphaned Kolla images
EOF
}
function bash_completion {
cat <<EOF
--inventory -i
--playbook -p
--configdir
--key -k
--help -h
--skip-tags
--tags -t
--extra -e
--passwords
--limit
--forks
--vault-id
--ask-vault-pass
--vault-password-file
--verbose -v
prechecks
check
mariadb_recovery
mariadb_backup
bootstrap-servers
destroy
deploy
deploy-bifrost
deploy-containers
deploy-servers
post-deploy
pull
reconfigure
stop
certificates
upgrade
upgrade-bifrost
genconfig
prune-images
EOF
}
check_environment_coherence
SHORT_OPTS="hi:p:t:k:e:v"
LONG_OPTS="help,inventory:,playbook:,skip-tags:,tags:,key:,extra:,verbose,configdir:,passwords:,limit:,forks:,vault-id:,ask-vault-pass,vault-password-file:,yes-i-really-really-mean-it,include-images,include-dev:,full,incremental"
RAW_ARGS="$*"
ARGS=$(getopt -o "${SHORT_OPTS}" -l "${LONG_OPTS}" --name "$0" -- "$@") || { usage >&2; exit 2; }
eval set -- "$ARGS"
find_base_dir
INVENTORY="${BASEDIR}/ansible/inventory/all-in-one"
PLAYBOOK="${BASEDIR}/ansible/site.yml"
VERBOSITY=
EXTRA_OPTS=${EXTRA_OPTS}
CONFIG_DIR="/etc/kolla"
PASSWORDS_FILE="${CONFIG_DIR}/passwords.yml"
DANGER_CONFIRM=
INCLUDE_IMAGES=
INCLUDE_DEV=
BACKUP_TYPE="full"
# Serial is not recommended and disabled by default. Users can enable it by
# configuring ANSIBLE_SERIAL variable.
ANSIBLE_SERIAL=${ANSIBLE_SERIAL:-0}
while [ "$#" -gt 0 ]; do
case "$1" in
(--inventory|-i)
INVENTORY="$2"
shift 2
;;
(--playbook|-p)
PLAYBOOK="$2"
shift 2
;;
(--skip-tags)
EXTRA_OPTS="$EXTRA_OPTS --skip-tags $2"
shift 2
;;
(--tags|-t)
EXTRA_OPTS="$EXTRA_OPTS --tags $2"
shift 2
;;
(--verbose|-v)
VERBOSITY="$VERBOSITY --verbose"
shift 1
;;
(--configdir)
CONFIG_DIR="$2"
shift 2
;;
(--yes-i-really-really-mean-it)
if [[ ${RAW_ARGS} =~ "$1" ]]
then
DANGER_CONFIRM="$1"
fi
shift 1
;;
(--include-images)
INCLUDE_IMAGES="$1"
shift 1
;;
(--include-dev)
INCLUDE_DEV="$1"
shift 1
;;
(--key|-k)
VAULT_PASS_FILE="$2"
EXTRA_OPTS="$EXTRA_OPTS --vault-password-file=$VAULT_PASS_FILE"
shift 2
;;
(--extra|-e)
EXTRA_OPTS="$EXTRA_OPTS -e $2"
shift 2
;;
(--passwords)
PASSWORDS_FILE="$2"
shift 2
;;
(--limit)
EXTRA_OPTS="$EXTRA_OPTS --limit $2"
shift 2
;;
(--forks)
EXTRA_OPTS="$EXTRA_OPTS --forks $2"
shift 2
;;
(--vault-id)
EXTRA_OPTS="$EXTRA_OPTS --vault-id $2"
shift 2
;;
(--ask-vault-pass)
VERBOSITY="$EXTRA_OPTS --ask-vault-pass"
shift 1
;;
(--vault-password-file)
EXTRA_OPTS="$EXTRA_OPTS --vault-password-file $2"
shift 2
;;
(--full)
BACKUP_TYPE="full"
shift 1
;;
(--incremental)
BACKUP_TYPE="incremental"
shift 1
;;
(--help|-h)
usage
shift
exit 0
;;
(--)
shift
break
;;
(*)
echo "error"
exit 3
;;
esac
done
case "$1" in
(prechecks)
ACTION="Pre-deployment checking"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=precheck"
;;
(check)
ACTION="Post-deployment checking"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=check"
;;
(mariadb_recovery)
ACTION="Attempting to restart mariadb cluster"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy -e common_run=true"
PLAYBOOK="${BASEDIR}/ansible/mariadb_recovery.yml"
;;
(mariadb_backup)
ACTION="Backup MariaDB databases"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=backup -e mariadb_backup_type=${BACKUP_TYPE} -e common_run=true"
PLAYBOOK="${BASEDIR}/ansible/mariadb_backup.yml"
;;
(destroy)
ACTION="Destroy Kolla containers, volumes and host configuration"
PLAYBOOK="${BASEDIR}/ansible/destroy.yml"
if [[ "${INCLUDE_IMAGES}" == "--include-images" ]]; then
EXTRA_OPTS="$EXTRA_OPTS -e destroy_include_images=yes"
fi
if [[ "${INCLUDE_DEV}" == "--include-dev" ]]; then
EXTRA_OPTS="$EXTRA_OPTS -e destroy_include_dev=yes"
fi
if [[ "${DANGER_CONFIRM}" != "--yes-i-really-really-mean-it" ]]; then
cat << EOF
WARNING:
This will PERMANENTLY DESTROY all deployed kolla containers, volumes and host configuration.
There is no way to recover from this action. To confirm, please add the following option:
--yes-i-really-really-mean-it
EOF
exit 1
fi
;;
(bootstrap-servers)
ACTION="Bootstrapping servers"
PLAYBOOK="${BASEDIR}/ansible/kolla-host.yml"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=bootstrap-servers"
;;
(deploy)
ACTION="Deploying Playbooks"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy"
;;
(deploy-bifrost)
ACTION="Deploying Bifrost"
PLAYBOOK="${BASEDIR}/ansible/bifrost.yml"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy"
;;
(deploy-containers)
ACTION="Deploying Containers"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy-containers"
;;
(deploy-servers)
ACTION="Deploying servers with bifrost"
PLAYBOOK="${BASEDIR}/ansible/bifrost.yml"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy-servers"
;;
(post-deploy)
ACTION="Post-Deploying Playbooks"
PLAYBOOK="${BASEDIR}/ansible/post-deploy.yml"
;;
(pull)
ACTION="Pulling Docker images"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=pull"
;;
(upgrade)
ACTION="Upgrading OpenStack Environment"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=upgrade -e kolla_serial=${ANSIBLE_SERIAL}"
;;
(upgrade-bifrost)
ACTION="Upgrading Bifrost"
PLAYBOOK="${BASEDIR}/ansible/bifrost.yml"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=upgrade"
;;
(reconfigure)
ACTION="Reconfigure OpenStack service"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=reconfigure -e kolla_serial=${ANSIBLE_SERIAL}"
;;
(stop)
ACTION="Stop Kolla containers"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=stop"
if [[ "${DANGER_CONFIRM}" != "--yes-i-really-really-mean-it" ]]; then
cat << EOF
WARNING:
This will stop all deployed kolla containers, limit with tags is possible and also with
skip_stop_containers variable. To confirm, please add the following option:
--yes-i-really-really-mean-it
EOF
exit 1
fi
;;
(certificates)
ACTION="Generate TLS Certificates"
PLAYBOOK="${BASEDIR}/ansible/certificates.yml"
;;
(genconfig)
ACTION="Generate configuration files for enabled OpenStack services"
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=config"
;;
(prune-images)
ACTION="Prune orphaned Kolla images"
PLAYBOOK="${BASEDIR}/ansible/prune-images.yml"
if [[ "${DANGER_CONFIRM}" != "--yes-i-really-really-mean-it" ]]; then
cat << EOF
WARNING:
This will PERMANENTLY DELETE all orphaned kolla images. To confirm, please add the following option:
--yes-i-really-really-mean-it
EOF
exit 1
fi
;;
(bash-completion)
bash_completion
exit 0
;;
(*) usage
exit 0
;;
esac
CONFIG_OPTS="-e @${CONFIG_DIR}/globals.yml -e @${PASSWORDS_FILE} -e CONFIG_DIR=${CONFIG_DIR}"
CMD="ansible-playbook -i $INVENTORY $CONFIG_OPTS $EXTRA_OPTS $PLAYBOOK $VERBOSITY"
process_cmd