Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
This commit is contained in:
231
scripts/create-proxmox-cluster.sh
Executable file
231
scripts/create-proxmox-cluster.sh
Executable file
@@ -0,0 +1,231 @@
|
||||
#!/bin/bash
|
||||
# create-proxmox-cluster.sh
|
||||
# Creates a Proxmox cluster between two instances
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load environment variables
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -f "${SCRIPT_DIR}/../.env" ]; then
|
||||
set -a
|
||||
source <(grep -v '^#' "${SCRIPT_DIR}/../.env" | grep -v '^$' | sed 's/^/export /')
|
||||
set +a
|
||||
fi
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Configuration
|
||||
CLUSTER_NAME="${CLUSTER_NAME:-sankofa-cluster}"
|
||||
NODE1_IP="192.168.11.10"
|
||||
NODE1_NAME="ML110-01"
|
||||
NODE1_TOKEN="${PROXMOX_TOKEN_ML110_01:-}"
|
||||
NODE2_IP="192.168.11.11"
|
||||
NODE2_NAME="R630-01"
|
||||
NODE2_TOKEN="${PROXMOX_TOKEN_R630_01:-}"
|
||||
|
||||
log() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
check_prerequisites() {
|
||||
if [ -z "$NODE1_TOKEN" ] || [ -z "$NODE2_TOKEN" ]; then
|
||||
error "Proxmox API tokens not found in .env file"
|
||||
fi
|
||||
|
||||
log "Prerequisites check passed"
|
||||
}
|
||||
|
||||
check_cluster_status() {
|
||||
log "Checking current cluster status..."
|
||||
|
||||
local node1_cluster=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
|
||||
"https://${NODE1_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | jq -r '.data // null')
|
||||
|
||||
local node2_cluster=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE2_TOKEN}" \
|
||||
"https://${NODE2_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | jq -r '.data // null')
|
||||
|
||||
if [ "$node1_cluster" != "null" ] && [ -n "$node1_cluster" ]; then
|
||||
warn "Node 1 is already in a cluster"
|
||||
echo "$node1_cluster" | jq '.'
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$node2_cluster" != "null" ] && [ -n "$node2_cluster" ]; then
|
||||
warn "Node 2 is already in a cluster"
|
||||
echo "$node2_cluster" | jq '.'
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Both nodes are standalone - ready for clustering"
|
||||
return 0
|
||||
}
|
||||
|
||||
create_cluster_on_node1() {
|
||||
log "Creating cluster '${CLUSTER_NAME}' on ${NODE1_NAME}..."
|
||||
|
||||
# Create cluster via API
|
||||
local response=$(curl -k -s -X POST \
|
||||
-H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${NODE1_IP}:8006/api2/json/cluster/config" \
|
||||
-d "{\"clustername\":\"${CLUSTER_NAME}\",\"link0\":\"${NODE1_IP}\"}" 2>/dev/null)
|
||||
|
||||
local success=$(echo "$response" | jq -r '.data // null')
|
||||
|
||||
if [ "$success" != "null" ] && [ -n "$success" ]; then
|
||||
log "✓ Cluster created on ${NODE1_NAME}"
|
||||
return 0
|
||||
else
|
||||
local error_msg=$(echo "$response" | jq -r '.errors[0].message // "Unknown error"')
|
||||
error "Failed to create cluster: ${error_msg}"
|
||||
fi
|
||||
}
|
||||
|
||||
get_cluster_fingerprint() {
|
||||
log "Getting cluster fingerprint from ${NODE1_NAME}..."
|
||||
|
||||
local fingerprint=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
|
||||
"https://${NODE1_IP}:8006/api2/json/cluster/config/totem" 2>/dev/null | \
|
||||
jq -r '.data.fingerprint // empty')
|
||||
|
||||
if [ -n "$fingerprint" ]; then
|
||||
echo "$fingerprint"
|
||||
return 0
|
||||
else
|
||||
warn "Could not get cluster fingerprint"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
add_node2_to_cluster() {
|
||||
log "Adding ${NODE2_NAME} to cluster..."
|
||||
|
||||
# Get cluster fingerprint
|
||||
local fingerprint=$(get_cluster_fingerprint)
|
||||
|
||||
if [ -z "$fingerprint" ]; then
|
||||
warn "Fingerprint not available, trying without it"
|
||||
fi
|
||||
|
||||
# Add node to cluster
|
||||
local response=$(curl -k -s -X POST \
|
||||
-H "Authorization: PVEAPIToken ${NODE2_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${NODE2_IP}:8006/api2/json/cluster/config/nodes" \
|
||||
-d "{\"hostname\":\"${NODE1_NAME}\",\"nodeid\":1,\"votes\":1,\"link0\":\"${NODE1_IP}\"}" 2>/dev/null)
|
||||
|
||||
local success=$(echo "$response" | jq -r '.data // null')
|
||||
|
||||
if [ "$success" != "null" ] && [ -n "$success" ]; then
|
||||
log "✓ ${NODE2_NAME} added to cluster"
|
||||
return 0
|
||||
else
|
||||
local error_msg=$(echo "$response" | jq -r '.errors[0].message // "Unknown error"')
|
||||
warn "API method failed: ${error_msg}"
|
||||
warn "Cluster creation may require SSH access or manual setup"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_cluster() {
|
||||
log "Verifying cluster status..."
|
||||
|
||||
sleep 5 # Wait for cluster to stabilize
|
||||
|
||||
local node1_nodes=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
|
||||
"https://${NODE1_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | \
|
||||
jq -r '.data | length // 0')
|
||||
|
||||
local node2_nodes=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE2_TOKEN}" \
|
||||
"https://${NODE2_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | \
|
||||
jq -r '.data | length // 0')
|
||||
|
||||
if [ "$node1_nodes" -ge 2 ] && [ "$node2_nodes" -ge 2 ]; then
|
||||
log "✓ Cluster verified - both nodes see 2+ members"
|
||||
return 0
|
||||
else
|
||||
warn "Cluster verification incomplete"
|
||||
warn "Node 1 sees ${node1_nodes} members"
|
||||
warn "Node 2 sees ${node2_nodes} members"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||||
echo "║ Proxmox Cluster Creation ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
check_prerequisites
|
||||
echo ""
|
||||
|
||||
if ! check_cluster_status; then
|
||||
error "One or both nodes are already in a cluster"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
info "Cluster Configuration:"
|
||||
echo " Cluster Name: ${CLUSTER_NAME}"
|
||||
echo " Node 1: ${NODE1_NAME} (${NODE1_IP})"
|
||||
echo " Node 2: ${NODE2_NAME} (${NODE2_IP})"
|
||||
echo ""
|
||||
|
||||
read -p "Create cluster? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log "Cluster creation cancelled"
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Try API-based cluster creation
|
||||
if create_cluster_on_node1; then
|
||||
log "Cluster created on ${NODE1_NAME}"
|
||||
else
|
||||
error "Failed to create cluster via API"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Try to add second node
|
||||
if add_node2_to_cluster; then
|
||||
log "Node 2 added to cluster"
|
||||
else
|
||||
warn "Could not add node 2 via API"
|
||||
warn "You may need to add it manually via SSH or web UI"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Verify cluster
|
||||
verify_cluster
|
||||
echo ""
|
||||
|
||||
log "Cluster creation process complete!"
|
||||
echo ""
|
||||
info "Next steps:"
|
||||
info "1. Verify cluster: Check both nodes in Proxmox web UI"
|
||||
info "2. Test cluster: Create a VM and verify it's visible on both nodes"
|
||||
info "3. Configure quorum: For 2-node cluster, set expected votes: pvecm expected 2"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user