#!/usr/bin/env bash set -euo pipefail # Hardcoded NetBox access (DEV ONLY!) NETBOX_URL="http://netbox.gt-tiso.ikeja.co.za" NETBOX_TOKEN="7648e4f5ee370cda7834682e61b47c2ee8e95623" usage() { cat >&2 < [ansible-playbook args...] --pwfile PATH Path to password/vars file: - YAML/JSON: must contain ansible_ssh_pass (and optionally ansible_user) - Plain text: first line is the password (wrapped as ansible_ssh_pass) --user USER ansible_user to use (overrides file value unless omitted) Examples: nbplay uptime.yml ikeja12345 --pwfile /opt/containers/ansible-worker/data/ssh.yml nbplay uptime.yml ikeja12345 --pwfile /opt/.../ssh.txt --user root EOF exit 2 } # ---- Parse args PWFILE="" USER_OVERRIDE="" ARGS=() while (( $# )); do case "${1:-}" in --pwfile) shift; PWFILE="${1:-}"; [[ -n "$PWFILE" ]] || usage; shift;; --user) shift; USER_OVERRIDE="${1:-}"; [[ -n "$USER_OVERRIDE" ]] || usage; shift;; -h|--help) usage;; *) ARGS+=("$1"); shift;; esac done set -- "${ARGS[@]}" if [[ $# -lt 2 ]]; then usage; fi PLAYBOOK="$1"; shift NAME="$1"; shift if [[ -z "${PWFILE}" ]]; then DEFAULT_PWFILE="${NBPLAY_PWFILE:-/opt/containers/ansible-worker/data/ssh.yml}" if [[ -f "$DEFAULT_PWFILE" ]]; then PWFILE="$DEFAULT_PWFILE" fi fi # ---- Deps command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 127; } command -v curl >/dev/null 2>&1 || { echo "curl not found" >&2; exit 127; } BASE="${NETBOX_URL%/}" hdr=(-H "Authorization: Token ${NETBOX_TOKEN}" -H "Accept: application/json") # ---- Resolve device -> IP dev_json="$(curl -fsS "${hdr[@]}" "${BASE}/api/dcim/devices/?name=${NAME}&limit=1")" count="$(printf '%s' "$dev_json" | jq -r '.count // 0')" if [[ "$count" != "1" ]]; then echo "Device '${NAME}' not found or not unique (count=${count})." >&2 exit 1 fi addr_v4="$(printf '%s' "$dev_json" | jq -r '.results[0].primary_ip4.address // empty')" addr_v6="$(printf '%s' "$dev_json" | jq -r '.results[0].primary_ip6.address // empty')" addr_any="$(printf '%s' "$dev_json" | jq -r '.results[0].primary_ip.address // empty')" addr="${addr_v4:-${addr_v6:-${addr_any:-}}}" [[ -n "$addr" && "$addr" != "null" ]] || { echo "Device '${NAME}' has no primary IP." >&2; exit 1; } ip="${addr%%/*}" # ---- Temp inventory tmpinv="$(mktemp)"; trap 'rm -f "$tmpinv" "$tmpvars"' EXIT cat >"$tmpinv" <&2; exit 1; } pass="$(head -n1 "$PWFILE" | tr -d '\r\n')" tmpvars="$(mktemp)" { echo "ansible_ssh_pass: \"$pass\"" [[ -n "$USER_OVERRIDE" ]] && echo "ansible_user: \"$USER_OVERRIDE\"" } > "$tmpvars" chmod 600 "$tmpvars" extravars+=(-e "@${tmpvars}") fi fi # If user override provided and not already set via tmpvars/YAML, add it safely if [[ -n "$USER_OVERRIDE" && -z "$tmpvars" ]]; then tmpvars="$(mktemp)" echo "ansible_user: \"$USER_OVERRIDE\"" > "$tmpvars" chmod 600 "$tmpvars" extravars+=(-e "@${tmpvars}") fi # ---- Run playbook (do NOT use --ask-pass) ANSIBLE_ASK_PASS=False exec ansible-playbook -i "$tmpinv" "$PLAYBOOK" -l "$NAME" \ "${extravars[@]}" "$@"