#!/bin/bash source ~/.bashrc # Create All Service VMs via Proxmox API # Attempts to create VMs using available templates or provides detailed instructions set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_step() { echo -e "${BLUE}[STEP]${NC} $1" } # Load environment variables if [ -f .env ]; then set -a source <(grep -v '^#' .env | grep -v '^$' | sed 's/#.*$//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep '=') set +a else log_error ".env file not found!" exit 1 fi PVE_USERNAME="${PVE_USERNAME:-root@pam}" PVE_PASSWORD="${PVE_ROOT_PASS:-}" PROXMOX_HOST="${1:-192.168.1.206}" PROXMOX_URL="https://${PROXMOX_HOST}:8006" PROXMOX_NODE="${2:-pve}" # Get authentication ticket get_ticket() { local response=$(curl -k -s -d "username=$PVE_USERNAME&password=$PVE_PASSWORD" \ "$PROXMOX_URL/api2/json/access/ticket") local ticket=$(echo "$response" | grep -o '"ticket":"[^"]*' | cut -d'"' -f4) local csrf=$(echo "$response" | grep -o '"CSRFPreventionToken":"[^"]*' | cut -d'"' -f4) if [ -z "$ticket" ] || [ -z "$csrf" ]; then log_error "Failed to authenticate with Proxmox" return 1 fi echo "$ticket|$csrf" } # List available templates list_templates() { local auth=$1 local ticket=$(echo "$auth" | cut -d'|' -f1) local csrf=$(echo "$auth" | cut -d'|' -f2) local response=$(curl -k -s -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf" \ "$PROXMOX_URL/api2/json/nodes/$PROXMOX_NODE/qemu") echo "$response" | python3 -c " import sys, json data = json.load(sys.stdin) templates = [v for v in data.get('data', []) if v.get('template') == 1] if templates: print('Available Templates:') for t in templates: print(f\" - {t.get('name', 'unknown')} (ID: {t.get('vmid', 'N/A')})\") else: print('No templates found') " 2>/dev/null || echo "Could not retrieve templates" } # List available ISOs list_isos() { local auth=$1 local ticket=$(echo "$auth" | cut -d'|' -f1) local csrf=$(echo "$auth" | cut -d'|' -f2) local response=$(curl -k -s -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf" \ "$PROXMOX_URL/api2/json/nodes/$PROXMOX_NODE/storage/local/content") echo "$response" | python3 -c " import sys, json data = json.load(sys.stdin) isos = [f for f in data.get('data', []) if f.get('content') == 'iso'] if isos: print('Available ISO Images:') for iso in isos[:10]: print(f\" - {iso.get('volid', 'unknown')}\") else: print('No ISO images found') " 2>/dev/null || echo "Could not retrieve ISO images" } # Check if VM exists vm_exists() { local auth=$1 local vmid=$2 local ticket=$(echo "$auth" | cut -d'|' -f1) local csrf=$(echo "$auth" | cut -d'|' -f2) local response=$(curl -k -s -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf" \ "$PROXMOX_URL/api2/json/cluster/resources?type=vm") echo "$response" | python3 -c " import sys, json data = json.load(sys.stdin) vms = [v for v in data.get('data', []) if v.get('type') == 'qemu' and str(v.get('vmid')) == '$vmid'] print('true' if vms else 'false') " 2>/dev/null || echo "false" } # Create VM via API (requires template or ISO) create_vm_api() { local auth=$1 local vmid=$2 local name=$3 local cores=$4 local memory=$5 local disk_size=$6 local template_or_iso=$7 local ticket=$(echo "$auth" | cut -d'|' -f1) local csrf=$(echo "$auth" | cut -d'|' -f2) log_info "Creating VM $name (ID: $vmid) via API..." # Check if template exists if [ "$(vm_exists "$auth" "$template_or_iso")" = "true" ]; then # Clone from template log_info "Cloning from template $template_or_iso..." curl -k -X POST \ -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf" \ -d "newid=$vmid" \ -d "name=$name" \ "$PROXMOX_URL/api2/json/nodes/$PROXMOX_NODE/qemu/$template_or_iso/clone" 2>/dev/null # Update VM configuration curl -k -X PUT \ -H "Cookie: PVEAuthCookie=$ticket" \ -H "CSRFPreventionToken: $csrf" \ -d "cores=$cores" \ -d "memory=$memory" \ "$PROXMOX_URL/api2/json/nodes/$PROXMOX_NODE/qemu/$vmid/config" 2>/dev/null log_info "✓ VM $name created from template" return 0 else log_warn "Template/ISO $template_or_iso not found. Cannot create VM via API." return 1 fi } # VM configurations declare -A VMS=( ["100"]="cloudflare-tunnel:2:4096:40" ["101"]="k3s-master:4:8192:80" ["102"]="git-server:4:8192:100" ["103"]="observability:4:8192:200" ) main() { echo "=========================================" echo "Create All Service VMs" echo "=========================================" echo "" if [ -z "$PVE_PASSWORD" ]; then log_error "PVE_ROOT_PASS not set in .env" exit 1 fi log_info "Connecting to Proxmox: $PROXMOX_URL" # Authenticate auth=$(get_ticket) if [ $? -ne 0 ]; then exit 1 fi log_info "Authentication successful" echo "" # Check available resources log_step "Checking available resources..." list_templates "$auth" echo "" list_isos "$auth" echo "" # Check existing VMs log_step "Checking existing VMs..." for vmid in "${!VMS[@]}"; do IFS=':' read -r name cores memory disk <<< "${VMS[$vmid]}" if [ "$(vm_exists "$auth" "$vmid")" = "true" ]; then log_warn "VM $name (ID: $vmid) already exists" else log_info "VM $name (ID: $vmid) - Ready to create" fi done echo "" log_warn "VM creation via API requires templates or ISOs." log_info "Generating Proxmox Web UI creation guide..." echo "" # Generate creation instructions cat > /tmp/vm-creation-instructions.txt <> /tmp/vm-creation-instructions.txt <