#!/bin/bash function help() { echo echo "$1 [options]" echo echo "commands:" echo cmd_width=23 opt_width=22 desc_width=70 printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "Command" "Option" "Description" echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|" printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "generate-vault-password" "[vault_id] [password]" "Generate a password file for Ansible vault." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "convert-vault-file" "[vault_id] [path]" "Re-encrypt vault file as single strings." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "encrypt-string" "[vault_id] [key:value] -q" "Generate encrypted string with Ansible Vault." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install" "" "Install Ansible and dependencies with uv." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "install-exo" "" "Install Exoscale CLI." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "upgrade" "" "Upgrade Ansible and dependencies with uv." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "lint" "" "Lint Ansible roles and playbooks." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "galaxy-build" "" "Create tarball of collection." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "galaxy-publish" "" "Publish tarball to Ansible Galaxy." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-install" "" "Install build dependencies." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-dev" "" "Start vuepress development server." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-build" "" "Create vuepress build." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "node-serve-build" "" "Serve vuepress build." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "list-hosts" "[path]" "Lists all hosts of an inventory." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "version" "" "Show tool versions." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "source" "" "Source the Python virtual env." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "test-localhost" "[clean]" "Deploy to localhost. Pass option 'clean' to clean up." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "show-passwordless-sudo" "[username]" "Give instructions to setup passwordless sudo." printf "| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" "llm-update" "[path]" "Feed role files with prompt to LLM and apply updates with git path." echo } # Set env vars GIT_BRANCH=$(git symbolic-ref --short -q HEAD) LLM_MODEL=${LLM_MODEL:="deepseek-coder"} if [[ -a ".env" ]]; then export $(cat .env | sed 's/^#.*//g' | xargs) fi function generate-vault-password() { if test -z "$1"; then echo "\$1 is empty"; exit; fi if test -z "$2"; then echo "\$1 is empty"; exit; fi export VAULT_ID=$1 export VAULTPASSWORD=$2 echo "$VAULTPASSWORD" > ".vault_pass_$VAULT_ID" chmod 600 ".vault_pass_$VAULT_ID" echo "Password file ".vault_pass_$VAULT_ID" created." } function encrypt-string() { if test -z "$1"; then echo "\$1 is empty"; exit; fi if test -z "$2"; then echo "\$2 is empty"; exit; fi # Split multiline STRING_KEY=$(echo "$2" | cut -d ':' -f 1) STRING_VALUE=$(echo "$2" | cut -d ':' -f 2 | sed 's/^ *//') if [ "$3" != "-q" ]; then echo "Found key: $STRING_KEY" echo "Encrypting value: $STRING_VALUE" fi ansible-vault encrypt_string --encrypt-vault-id="$1" --name "$STRING_KEY" "$STRING_VALUE" } function convert-vault-file() { if test -z "$1"; then echo "\$1 is empty"; exit; fi if test -z "$1"; then echo "\$1 is empty"; exit; fi # python convert-vault-file "$1" "$2" } function init-venv() { if [ ! -d "venv$GIT_BRANCH" ]; then echo "Init venv$GIT_BRANCH with $(uv --version)." uv venv "venv$GIT_BRANCH" fi } function activate-venv() { echo "Source virtualenv venv$GIT_BRANCH." source "venv$GIT_BRANCH/bin/activate" } function install() { echo "Setup Ansible log file" sudo touch /var/log/ansible.log sudo chown $USER: /var/log/ansible.log init-venv activate-venv echo "Install Ansible and Python dependencies" uv pip install -r requirements.txt ansible-galaxy collection install community.general } function install-exo() { curl -fsSL https://raw.githubusercontent.com/exoscale/cli/master/install-latest.sh | sh } function upgrade() { echo "Update Ansible" uv pip install --upgrade ansible } function list-hosts() { if test -z "$1"; then echo "\$1 is empty"; exit; fi activate-venv ansible -i $1 all --list-hosts } function version() { activate-venv uv --version ansible --version } function show-passwordless-sudo() { USER=${1:-"$USERNAME"} echo "echo \"$USER ALL=(ALL) NOPASSWD: ALL\" >> /etc/sudoers" } function galaxy-build() { activate-venv VERSION=$(yq -r .version galaxy.yml) NAMESPACE=$(yq -r .namespace galaxy.yml) NAME=$(yq -r .name galaxy.yml) ansible-galaxy collection build mv $NAMESPACE-$NAME-$VERSION.tar.gz tmp/ } function galaxy-publish() { activate-venv VERSION=$(yq -r .version galaxy.yml) NAMESPACE=$(yq -r .namespace galaxy.yml) NAME=$(yq -r .name galaxy.yml) ansible-galaxy collection publish tmp/$NAMESPACE-$NAME-$VERSION.tar.gz --token "$GALAXY_API_TOKEN" } function test-localhost() { activate-venv version if [ "$1" = "clean" ]; then echo "Cleanup localhost" ansible-playbook -i test plays/clean.yml -t odoo,odoo_data,odoo_volume,postgres,postgres_data,postgres_volume,meilisearch,meilisearch_data,meilisearch_volume,pgadmin,pgadmin_data,pgadmin_volume,n8n,n8n_data,n8n_volume,nginx,nginx_data,nginx_volume,metabase,metabase_data,metabase_volume else echo "Setup localhost" ansible-playbook -i test plays/localhost.yml --skip-tags check fi } function llm-update() { if test -z "$1"; then echo "\$1 is empty."; exit 1; fi # Get list of files FILES=$(find "$1" -type f -name "*.yml") } if declare -f "$1" > /dev/null; then "$1" "${@:2}" else case "$1" in help) help task exit 1 ;; node-install) npm install ;; node-dev) npm run dev ;; node-build) npm run build ;; node-serve-build) cd .vuepress/dist npx serve ;; lint) activate-venv ansible-lint --write --offline roles/* ;; source) activate-venv ;; *) echo "Unknown command: $1" help task exit 1 ;; esac fi