#!/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 </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 <