#!/usr/bin/env bash set -e if [ $# -ne 3 ]; then echo "Usage: $0 " exit 1 fi CONTROLLER_URL="$1" API_TOKEN="$2" INVENTORY_NAME="$3" # ----------------------------- # Detect OS + environment # ----------------------------- echo "[INFO] Detecting OS and environment..." if [ -f /etc/os-release ]; then . /etc/os-release DISTRO=$ID DISTRO_PRETTY=$PRETTY_NAME else DISTRO="unknown" DISTRO_PRETTY="Unknown OS" fi ARCH=$(uname -m) # ----------------------------- # Detect virtualization (with hardware detection) # ----------------------------- RAW_VIRT=$(systemd-detect-virt 2>/dev/null || echo "unknown") case "$RAW_VIRT" in none) VIRT_TYPE="hardware" ;; docker|podman|lxc|container) VIRT_TYPE="container" ;; kvm|qemu|vmware|xen|microsoft|oracle|hyperv) VIRT_TYPE="$RAW_VIRT" ;; *) VIRT_TYPE="unknown" ;; esac # ----------------------------- # Detect cloud provider # ----------------------------- if curl -s --connect-timeout 1 http://169.254.169.254/latest/meta-data/ >/dev/null; then CLOUD="aws" elif curl -s --connect-timeout 1 -H Metadata:true http://169.254.169.254/metadata/instance?api-version=2021-02-01 >/dev/null; then CLOUD="azure" elif curl -s --connect-timeout 1 http://metadata.google.internal >/dev/null; then CLOUD="gcp" else CLOUD="none" fi IPA_HOSTNAME=$(hostname -f) echo "[INFO] Hostname: $IPA_HOSTNAME" echo "[INFO] OS: $DISTRO_PRETTY" echo "[INFO] Architecture: $ARCH" echo "[INFO] Virtualization: $VIRT_TYPE" echo "[INFO] Cloud provider: $CLOUD" # ----------------------------- # Install Python # ----------------------------- install_python() { case "$DISTRO" in arch) sudo pacman -Sy --noconfirm python ;; debian|ubuntu) sudo apt update && sudo apt install -y python3 ;; rhel|centos|rocky|almalinux) sudo yum install -y python3 || sudo dnf install -y python3 ;; fedora) sudo dnf install -y python3 ;; opensuse*|sles) sudo zypper install -y python3 ;; *) echo "[WARN] Unknown distro, trying generic python3 install..." sudo bash -c "apt install -y python3 || yum install -y python3 || dnf install -y python3 || pacman -Sy --noconfirm python" ;; esac } if ! command -v python3 >/dev/null 2>&1; then echo "[INFO] Installing Python..." install_python fi # ----------------------------- # Ensure SSH + GSSAPI # ----------------------------- echo "[INFO] Ensuring SSH is running..." sudo systemctl enable sshd --now 2>/dev/null || sudo systemctl enable ssh --now || true if ! grep -q "GSSAPIAuthentication yes" /etc/ssh/sshd_config; then echo "GSSAPIAuthentication yes" | sudo tee -a /etc/ssh/sshd_config sudo systemctl restart sshd || sudo systemctl restart ssh fi # ----------------------------- # Helper: API GET # ----------------------------- api_get() { curl -s -H "Authorization: Bearer $API_TOKEN" "$CONTROLLER_URL$1" } # ----------------------------- # Helper: API POST # ----------------------------- api_post() { curl -s -X POST -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d "$2" "$CONTROLLER_URL$1" } # ----------------------------- # Ensure inventory exists # ----------------------------- echo "[INFO] Checking inventory '$INVENTORY_NAME'..." INVENTORY_ID=$(api_get "/api/v2/inventories/?name=$INVENTORY_NAME" \ | python3 -c "import sys, json; d=json.load(sys.stdin); print(d['results'][0]['id'] if d['count'] else '')") if [ -z "$INVENTORY_ID" ]; then echo "[INFO] Inventory not found. Creating..." INVENTORY_ID=$(api_post "/api/v2/inventories/" \ "{\"name\": \"$INVENTORY_NAME\", \"organization\": 1}" \ | python3 -c "import sys, json; print(json.load(sys.stdin)['id'])") else echo "[INFO] Inventory exists with ID $INVENTORY_ID" fi # ----------------------------- # Ensure groups exist # ----------------------------- create_group_if_missing() { local GROUP="$1" local GROUP_ID=$(api_get "/api/v2/groups/?name=$GROUP&inventory=$INVENTORY_ID" \ | python3 -c "import sys, json; d=json.load(sys.stdin); print(d['results'][0]['id'] if d['count'] else '')") if [ -z "$GROUP_ID" ]; then echo "[INFO] Creating group: $GROUP" GROUP_ID=$(api_post "/api/v2/groups/" \ "{\"name\": \"$GROUP\", \"inventory\": $INVENTORY_ID}" \ | python3 -c "import sys, json; print(json.load(sys.stdin)['id'])") fi echo "$GROUP_ID" } GROUP_OS=$(create_group_if_missing "$DISTRO") GROUP_ARCH=$(create_group_if_missing "arch-$ARCH") GROUP_VIRT=$(create_group_if_missing "virt-$VIRT_TYPE") GROUP_CLOUD=$(create_group_if_missing "cloud-$CLOUD") # ----------------------------- # Register host # ----------------------------- echo "[INFO] Registering host..." HOST_ID=$(api_post "/api/v2/hosts/" \ "{\"name\": \"$IPA_HOSTNAME\", \"inventory\": $INVENTORY_ID, \"enabled\": true}" \ | python3 -c "import sys, json; print(json.load(sys.stdin)['id'])") echo "[INFO] Host ID: $HOST_ID" # ----------------------------- # Add host to groups # ----------------------------- for G in $GROUP_OS $GROUP_ARCH $GROUP_VIRT $GROUP_CLOUD; do echo "[INFO] Adding host to group ID $G" api_post "/api/v2/groups/$G/hosts/" "{\"id\": $HOST_ID}" >/dev/null done echo "[SUCCESS] Host fully enrolled and auto-classified."