Add custom AWX Execution Environment with NetBox support and related scripts

This commit is contained in:
alex-local
2025-09-12 09:44:55 +02:00
parent 585fa54336
commit e423305242
10 changed files with 500 additions and 84 deletions

158
integrate_github_netbox.sh Executable file
View File

@@ -0,0 +1,158 @@
#!/usr/bin/env bash
set -euo pipefail
# integrate_github_netbox.sh
# Create AWX Project (Git) and NetBox inventory source via AWX API.
# Usage (dry-run by default):
# ./integrate_github_netbox.sh --github-repo https://github.com/owner/repo.git \
# --github-pat GH_PAT --netbox-url https://netbox.example/api/ --netbox-token NETBOX_TOKEN [--apply]
AWX_URL=${AWX_URL:-http://localhost:30081}
AWX_USER=${AWX_USER:-admin}
AWX_PW="${AWX_PW:-}"
GITHUB_REPO=""
GITHUB_PAT=""
NETBOX_URL=""
NETBOX_TOKEN=""
PROJECT_NAME="awx-github-project"
INV_NAME="netbox-inventory"
DRY_RUN=1
usage(){
cat <<EOF
Usage: $0 --github-repo REPO_URL --github-pat PAT --netbox-url URL --netbox-token TOKEN [--project-name NAME] [--inventory-name NAME] [--apply]
This script is dry-run by default. Add --apply to execute API POSTs.
Secrets can also be provided via env vars: GITHUB_PAT, NETBOX_TOKEN, AWX_PW.
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--github-repo) GITHUB_REPO="$2"; shift 2;;
--github-pat) GITHUB_PAT="$2"; shift 2;;
--netbox-url) NETBOX_URL="$2"; shift 2;;
--netbox-token) NETBOX_TOKEN="$2"; shift 2;;
--project-name) PROJECT_NAME="$2"; shift 2;;
--inventory-name) INV_NAME="$2"; shift 2;;
--apply) DRY_RUN=0; shift;;
-h|--help) usage; exit 0;;
*) echo "Unknown arg: $1"; usage; exit 1;;
esac
done
# pick up env secrets if not provided
: "${GITHUB_PAT:-}" && GITHUB_PAT=${GITHUB_PAT:-$GITHUB_PAT}
AWX_PW=${AWX_PW:-}
NETBOX_TOKEN=${NETBOX_TOKEN:-$NETBOX_TOKEN}
for cmd in curl jq; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "missing dependency: $cmd" >&2
exit 1
fi
done
if [ -z "$AWX_PW" ]; then
# try to read from k8s secret
if command -v kubectl >/dev/null 2>&1; then
if AWX_PW_RAW=$(kubectl -n awx get secret awx-admin-password -o jsonpath='{.data.password}' 2>/dev/null || true); then
if [ -n "$AWX_PW_RAW" ]; then
AWX_PW=$(echo "$AWX_PW_RAW" | base64 --decode)
fi
fi
fi
fi
# Require github repo, netbox url and token. Either GITHUB_PAT OR a local SSH key file must exist.
if [ -z "$GITHUB_REPO" ] || [ -z "$NETBOX_URL" ] || [ -z "${NETBOX_TOKEN:-}" ] || { [ -z "${GITHUB_PAT:-}" ] && [ ! -f "$HOME/.ssh/awx_deploy_key" ]; }; then
echo "Missing required inputs." >&2
echo "Provide --github-repo, --netbox-url, --netbox-token and either --github-pat or a private key at $HOME/.ssh/awx_deploy_key." >&2
usage
exit 1
fi
AUTH="${AWX_USER}:${AWX_PW}"
api_get(){
local path=$1
curl -sS -u "$AUTH" "$AWX_URL/api/v2/$path"
}
api_post(){
local path=$1
local data=$2
if [ "$DRY_RUN" -ne 0 ]; then
echo "[DRY-RUN] POST $AWX_URL/api/v2/$path -> payload:" >&2
echo "$data" | jq . >&2 || true
return 0
fi
curl -sS -u "$AUTH" -H 'Content-Type: application/json' -X POST "$AWX_URL/api/v2/$path" -d "$data" | jq .
}
echo "AWX: $AWX_URL (user: $AWX_USER)"
echo "Repo: $GITHUB_REPO"
echo "Project: $PROJECT_NAME"
echo "Inventory: $INV_NAME"
echo "Dry-run: $DRY_RUN"
echo "Listing credential types (to pick SCM type)..."
api_get credential_types/ | jq -r '.results[] | "id:\(.id) name:\(.name) kind:\(.kind)"'
# User-friendly heuristic to pick SCM credential_type id
SCM_CT_ID=$(api_get credential_types/ | jq -r '.results[] | select((.name|test("Source Control|Git|SCM";"i")) or (.kind == "scm")) | .id' | head -n1)
if [ -z "$SCM_CT_ID" ]; then
echo "Could not auto-detect SCM credential_type id. You must create credentials manually using AWX UI or list credential_types." >&2
else
echo "Detected SCM credential_type id: $SCM_CT_ID"
fi
echo "Creating Git credential (token or ssh key)"
if [ -n "${GITHUB_PAT:-}" ]; then
git_cred_payload=$(jq -n --arg name "github-pat" --argjson ct "$SCM_CT_ID" --arg inputs "{\"token\":\"$GITHUB_PAT\"}" '{name:$name, credential_type:$ct, inputs:( $inputs | fromjson ) }')
else
# fall back to SSH private key if available
if [ -f "$HOME/.ssh/awx_deploy_key" ]; then
SSH_KEY_DATA=$(sed -n '1,2000p' "$HOME/.ssh/awx_deploy_key")
# use --arg to safely inject SSH private key text into JSON
git_cred_payload=$(jq -n --arg name "github-ssh" --argjson ct "$SCM_CT_ID" --arg ssh "$SSH_KEY_DATA" '{name:$name, credential_type:$ct, inputs:{ssh_key_data:$ssh}}')
else
echo "No GITHUB_PAT and no $HOME/.ssh/awx_deploy_key - cannot create SCM credential" >&2
exit 1
fi
fi
CREDS_OUT=$(api_post credentials/ "$git_cred_payload" || true)
SCM_CRED_ID=$(echo "$CREDS_OUT" | jq -r '.id // empty' 2>/dev/null || true)
if [ -z "$SCM_CRED_ID" ]; then
SCM_CRED_ID=null
echo "SCM credential id: (none - dry-run or failed)"
else
echo "SCM credential id: $SCM_CRED_ID"
fi
echo "Creating Project pointing to $GITHUB_REPO"
proj_payload=$(jq -n --arg name "$PROJECT_NAME" --arg scm_type "git" --arg scm_url "$GITHUB_REPO" --argjson cred "$SCM_CRED_ID" '{name:$name, scm_type:$scm_type, scm_url:$scm_url, scm_update_on_launch:true, scm_branch:null, scm_clean:false, scm_ref:null, scm_credential:$cred }')
api_post projects/ "$proj_payload"
echo "Creating Inventory: $INV_NAME"
inv_payload=$(jq -n --arg name "$INV_NAME" '{name:$name, organization:1}')
INV_OUT=$(api_post inventories/ "$inv_payload" || true)
INV_ID=$(echo "$INV_OUT" | jq -r '.id // empty')
if [ -z "$INV_ID" ]; then
echo "Could not create inventory (check output)." >&2
else
echo "Inventory id: $INV_ID"
fi
echo "Creating NetBox inventory source for inventory id $INV_ID"
source_vars=$(cat <<EOF
token: "$NETBOX_TOKEN"
url: "$NETBOX_URL"
validate_certs: true
EOF
)
src_payload=$(jq -n --arg name "netbox-src" --arg source "netbox" --arg source_vars "$source_vars" --argjson update_on_launch true '{name:$name, source:$source, source_vars:$source_vars, update_on_launch:$update_on_launch}')
api_post "inventories/$INV_ID/inventory_sources/" "$src_payload"
echo "Done. If run in dry-run mode, re-run with --apply to execute the API calls."
exit 0