Add custom AWX Execution Environment with NetBox support and related scripts
This commit is contained in:
158
integrate_github_netbox.sh
Executable file
158
integrate_github_netbox.sh
Executable 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
|
||||
Reference in New Issue
Block a user