Dotfiles/setup/modules/auto-enroll-ansible.sh

189 lines
5.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
set -e
if [ $# -ne 3 ]; then
echo "Usage: $0 <controller-url> <api-token> <inventory-name>"
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 autoclassified."