Files
docker/scripts/codex-maintenance.sh

155 lines
4.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
echo "== Refresh Python tools =="
python3 -m pip install --break-system-packages --upgrade \
pip \
yamllint \
ansible \
ansible-lint
echo "== Sanity check installed tools =="
for cmd in docker terraform tflint ansible-lint yamllint yq jq shellcheck; do
if command -v "$cmd" >/dev/null 2>&1; then
echo "OK: $cmd -> $(command -v "$cmd")"
else
echo "MISSING: $cmd"
fi
done
echo "== Reconcile dummy secret material =="
REPO_ROOT="${CODEX_REPO_DIR:-$PWD}"
SECRETS_DIR="$REPO_ROOT/secrets"
INVENTORY_JSON="$SECRETS_DIR/inventory.json"
EXAMPLE_ENV="$SECRETS_DIR/.env.secrets.example"
STACK_ENV="$SECRETS_DIR/stack-secrets.env"
if [[ ! -f "$INVENTORY_JSON" ]]; then
echo "Missing inventory file: $INVENTORY_JSON"
exit 1
fi
if [[ ! -f "$EXAMPLE_ENV" ]]; then
echo "Missing example env file: $EXAMPLE_ENV"
exit 1
fi
mkdir -p "$SECRETS_DIR"
dummy_value_for_key() {
local key="$1"
case "$key" in
*EMAIL* ) echo "dummy@example.com" ;;
*DB_USER* ) echo "dummyuser" ;;
*USERNAME*|*USER* ) echo "dummy-user" ;;
*DOMAIN* ) echo "example.lan.ddnsgeek.com" ;;
*TZ ) echo "Australia/Brisbane" ;;
*URL* ) echo "https://example.lan.ddnsgeek.com" ;;
*PORT* ) echo "1234" ;;
*PASSWORD*|*PASS*|*TOKEN*|*SECRET*|*KEY*|*JWT* ) echo "dummy-${key,,}" ;;
*FINGERPRINT* ) echo "0000000000000000000000000000000000000000" ;;
*DB_NAME* ) echo "dummydb" ;;
*NAME* ) echo "dummy-name" ;;
*ADDRESS* ) echo "dummy" ;;
* ) echo "dummy-value" ;;
esac
}
rebuild_dummy_stack_env() {
local tmp
tmp="$(mktemp)"
cp "$EXAMPLE_ENV" "$tmp"
while IFS= read -r var; do
[[ -z "$var" ]] && continue
dummy="$(dummy_value_for_key "$var")"
if grep -Eq "^[[:space:]]*${var}=" "$tmp"; then
sed -i "s|^[[:space:]]*${var}=.*|${var}=${dummy}|" "$tmp"
else
printf '%s=%s\n' "$var" "$dummy" >> "$tmp"
fi
done < <(jq -r '.env_template_variables[].variable' "$INVENTORY_JSON")
mv "$tmp" "$STACK_ENV"
chmod 600 "$STACK_ENV" || true
echo "Updated $STACK_ENV"
}
reconcile_file_based_secrets() {
local wanted existing relpath abspath
wanted="$(mktemp)"
existing="$(mktemp)"
jq -r '.file_based_secrets[].path' "$INVENTORY_JSON" | sort -u > "$wanted"
find "$SECRETS_DIR" -maxdepth 1 -type f -name '*.txt' -printf '%P\n' \
| sed "s#^#secrets/#" \
| sort -u > "$existing"
# Create missing listed files
while IFS= read -r relpath; do
[[ -z "$relpath" ]] && continue
abspath="$REPO_ROOT/$relpath"
if [[ ! -f "$abspath" ]]; then
mkdir -p "$(dirname "$abspath")"
printf 'dummy-secret\n' > "$abspath"
chmod 600 "$abspath" || true
echo "Created $relpath"
fi
done < <(comm -23 "$wanted" "$existing")
# Remove stale files no longer listed in inventory.json
while IFS= read -r relpath; do
[[ -z "$relpath" ]] && continue
abspath="$REPO_ROOT/$relpath"
if [[ -f "$abspath" ]]; then
rm -f "$abspath"
echo "Removed stale $relpath"
fi
done < <(comm -13 "$wanted" "$existing")
rm -f "$wanted" "$existing"
}
rebuild_dummy_stack_env
reconcile_file_based_secrets
echo "== Dummy secret reconciliation complete =="
echo "stack env: $STACK_ENV"
jq -r '.file_based_secrets[].path' "$INVENTORY_JSON" | sed 's/^/file secret: /'
REPO_ROOT="${CODEX_REPO_DIR:-$PWD}"
ANSIBLE_DIR="$REPO_ROOT/infrastructure/ansible"
ANSIBLE_CONFIG="$ANSIBLE_DIR/ansible.cfg"
ANSIBLE_COLLECTIONS_REQ="$ANSIBLE_DIR/collections/requirements.yml"
ANSIBLE_INVENTORY="$ANSIBLE_DIR/inventory/hosts.yml"
ANSIBLE_PING_PLAYBOOK="$ANSIBLE_DIR/playbooks/ping.yml"
if [[ -f "$ANSIBLE_COLLECTIONS_REQ" ]]; then
echo "== Refresh Ansible collections (bootstrap) =="
ansible-galaxy collection install -r "$ANSIBLE_COLLECTIONS_REQ" -p "$ANSIBLE_DIR/collections" || true
fi
if command -v ansible >/dev/null 2>&1; then
echo "== Ansible bootstrap validation =="
ANSIBLE_CONFIG="$ANSIBLE_CONFIG" ansible --version | head -n 1 || true
if command -v ansible-lint >/dev/null 2>&1; then
ansible-lint --version || true
fi
if [[ -f "$ANSIBLE_INVENTORY" ]]; then
ANSIBLE_CONFIG="$ANSIBLE_CONFIG" \
ansible-inventory -i "$ANSIBLE_INVENTORY" --list > /dev/null || true
fi
if [[ -f "$ANSIBLE_PING_PLAYBOOK" && -f "$ANSIBLE_INVENTORY" ]]; then
ANSIBLE_CONFIG="$ANSIBLE_CONFIG" \
ansible-playbook -i "$ANSIBLE_INVENTORY" "$ANSIBLE_PING_PLAYBOOK" --syntax-check || true
fi
fi