Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Made-with: Cursor
213 lines
7.9 KiB
Bash
Executable File
213 lines
7.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# IP Conflict Resolution Script
|
|
# Resolves IP conflicts on r630-01 (Sankofa vs Order vs vault CTs).
|
|
# 2026-03-25: VMID 7804 (gov-portals) owns 192.168.11.54. VMID 10070 (order-legal) must use IP_ORDER_LEGAL (default 192.168.11.87), not .54.
|
|
# Original date: 2026-01-20
|
|
|
|
set -euo pipefail
|
|
|
|
# Load IP configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
|
|
|
|
|
PROXMOX_HOST="${PROXMOX_HOST_R630_01}"
|
|
LOG_FILE="/tmp/ip-conflict-resolution-$(date +%Y%m%d-%H%M%S).log"
|
|
|
|
log() {
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
log_error() {
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
verify_ip_available() {
|
|
local ip=$1
|
|
local vmid_if_mine=$2
|
|
log "Verifying IP $ip is available..."
|
|
if ping -c 1 -W 1 "$ip" > /dev/null 2>&1; then
|
|
if [ -n "${vmid_if_mine:-}" ]; then
|
|
local cur
|
|
cur=$(ssh root@$PROXMOX_HOST "pct config $vmid_if_mine 2>/dev/null | grep -oE 'ip=[0-9.]+' | head -1 | cut -d= -f2" | tr -d '\r')
|
|
if [ "$cur" = "$ip" ]; then
|
|
log "IP $ip already assigned to VMID $vmid_if_mine (ok) ✓"
|
|
return 0
|
|
fi
|
|
fi
|
|
log_error "IP $ip is already in use!"
|
|
return 1
|
|
fi
|
|
log "IP $ip is available ✓"
|
|
return 0
|
|
}
|
|
|
|
resolve_conflict() {
|
|
local vmid=$1
|
|
local old_ip=$2
|
|
local new_ip=$3
|
|
local name=$4
|
|
|
|
log "=== Resolving conflict for VMID $vmid ($name) ==="
|
|
log "Current IP: $old_ip"
|
|
log "New IP: $new_ip"
|
|
|
|
# Verify new IP is available (or already ours on this VMID)
|
|
if ! verify_ip_available "$new_ip" "$vmid"; then
|
|
log_error "Cannot proceed - IP $new_ip is in use"
|
|
return 1
|
|
fi
|
|
|
|
# Stop container
|
|
log "Stopping container $vmid..."
|
|
ssh root@$PROXMOX_HOST "pct stop $vmid" || {
|
|
log_error "Failed to stop container $vmid"
|
|
return 1
|
|
}
|
|
|
|
# Wait for stop
|
|
sleep 2
|
|
|
|
# Get current network configuration
|
|
log "Getting current network configuration..."
|
|
local current_net=$(ssh root@$PROXMOX_HOST "pct config $vmid | grep '^net0:' | cut -d' ' -f2-")
|
|
|
|
# Extract network parameters
|
|
local bridge=$(echo "$current_net" | grep -oP 'bridge=\K[^,]+' || echo "vmbr0")
|
|
local gw=$(echo "$current_net" | grep -oP 'gw=\K[^,]+' || echo "${PROXMOX_HOST_R630_01:-192.168.11.11}")
|
|
local hwaddr=$(echo "$current_net" | grep -oP 'hwaddr=\K[^,]+' || echo "")
|
|
local type=$(echo "$current_net" | grep -oP 'type=\K[^,]+' || echo "veth")
|
|
|
|
# Build new network configuration
|
|
local new_net="name=eth0,bridge=$bridge,gw=$gw,ip=$new_ip/24,type=$type"
|
|
if [ -n "$hwaddr" ]; then
|
|
new_net="$new_net,hwaddr=$hwaddr"
|
|
fi
|
|
|
|
# Update network configuration
|
|
log "Updating network configuration..."
|
|
ssh root@$PROXMOX_HOST "pct set $vmid --net0 '$new_net'" || {
|
|
log_error "Failed to update network configuration"
|
|
log "Attempting to start container with old configuration..."
|
|
ssh root@$PROXMOX_HOST "pct start $vmid" || true
|
|
return 1
|
|
}
|
|
|
|
# Start container
|
|
log "Starting container $vmid..."
|
|
ssh root@$PROXMOX_HOST "pct start $vmid" || {
|
|
log_error "Failed to start container $vmid"
|
|
return 1
|
|
}
|
|
|
|
# Wait for startup
|
|
sleep 3
|
|
|
|
# Verify new IP
|
|
log "Verifying new IP assignment..."
|
|
local actual_ip=$(ssh root@$PROXMOX_HOST "pct exec $vmid -- hostname -I 2>/dev/null | awk '{print \$1}'" || echo "")
|
|
if [ "$actual_ip" = "$new_ip" ]; then
|
|
log "✓ IP conflict resolved successfully!"
|
|
log " VMID $vmid ($name): $old_ip → $new_ip"
|
|
return 0
|
|
else
|
|
log_error "IP verification failed. Actual IP: $actual_ip, Expected: $new_ip"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
log "=== IP Conflict Resolution Script ==="
|
|
log "Host: $PROXMOX_HOST"
|
|
log "Log file: $LOG_FILE"
|
|
log ""
|
|
|
|
# Check if running in dry-run mode
|
|
if [ "${DRY_RUN:-false}" = "true" ]; then
|
|
log "DRY RUN MODE - No changes will be made"
|
|
log ""
|
|
fi
|
|
|
|
# Verify SSH access
|
|
log "Verifying SSH access..."
|
|
if ! ssh -o ConnectTimeout=5 root@$PROXMOX_HOST "echo 'SSH OK'" > /dev/null 2>&1; then
|
|
log_error "Cannot connect to $PROXMOX_HOST"
|
|
exit 1
|
|
fi
|
|
log "SSH access verified ✓"
|
|
log ""
|
|
|
|
# Verify target IPs are free (ping) — not .54 (in use by gov-portals 7804)
|
|
log "=== Step 1: Verifying IP Availability ==="
|
|
for ip in ${IP_SERVICE_55:-192.168.11.55} ${IP_SERVICE_56:-192.168.11.56}; do
|
|
if ! verify_ip_available "$ip"; then
|
|
log_error "Required IP $ip is not available. Cannot proceed."
|
|
exit 1
|
|
fi
|
|
done
|
|
log ""
|
|
|
|
if [ "${DRY_RUN:-false}" = "true" ]; then
|
|
log "DRY RUN - Would resolve conflicts:"
|
|
log " VMID 10070 (order-legal): if still on ${IP_GOV_PORTALS_DEV:-192.168.11.54} → $IP_ORDER_LEGAL"
|
|
log " VMID 10230 (order-vault): ${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-192.168.11.51}}}}}} → ${IP_SERVICE_55:-${IP_SERVICE_55:-192.168.11.55}}"
|
|
log " VMID 10232 (CT10232): ${IP_SERVICE_52:-${IP_SERVICE_52:-192.168.11.52}} → ${IP_SERVICE_56:-${IP_SERVICE_56:-192.168.11.56}}"
|
|
exit 0
|
|
fi
|
|
|
|
# Resolve conflicts
|
|
log "=== Step 2: Resolving IP Conflicts ==="
|
|
log ""
|
|
|
|
# Conflict 1: VMID 10070 (order-legal) must not share IP with VMID 7804 (gov-portals on .54)
|
|
IP_GOV="${IP_GOV_PORTALS_DEV:-192.168.11.54}"
|
|
IP_ORDER_LEGAL="${IP_ORDER_LEGAL:-192.168.11.87}"
|
|
CURRENT_LEGAL=$(ssh root@$PROXMOX_HOST "pct config 10070 2>/dev/null | grep -oE 'ip=[0-9.]+' | head -1 | cut -d= -f2" | tr -d '\r' || echo "")
|
|
result1=0
|
|
if [ "$CURRENT_LEGAL" = "$IP_GOV" ]; then
|
|
log "VMID 10070 shares gov-portals IP $IP_GOV — moving to $IP_ORDER_LEGAL"
|
|
resolve_conflict 10070 "$IP_GOV" "$IP_ORDER_LEGAL" "order-legal"
|
|
result1=$?
|
|
elif [ "$CURRENT_LEGAL" = "$IP_ORDER_LEGAL" ]; then
|
|
log "VMID 10070 already on $IP_ORDER_LEGAL — skip"
|
|
result1=0
|
|
else
|
|
log "VMID 10070 is $CURRENT_LEGAL (expected $IP_ORDER_LEGAL or conflict with $IP_GOV); no automatic change"
|
|
result1=0
|
|
fi
|
|
log ""
|
|
|
|
# Conflict 2: VMID 10230 (order-vault)
|
|
resolve_conflict 10230 "${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-192.168.11.51}}}}}}" "${IP_SERVICE_55:-${IP_SERVICE_55:-192.168.11.55}}" "order-vault"
|
|
local result2=$?
|
|
log ""
|
|
|
|
# Conflict 3: VMID 10232 (CT10232)
|
|
resolve_conflict 10232 "${IP_SERVICE_52:-${IP_SERVICE_52:-192.168.11.52}}" "${IP_SERVICE_56:-${IP_SERVICE_56:-192.168.11.56}}" "CT10232"
|
|
local result3=$?
|
|
log ""
|
|
|
|
# Summary
|
|
log "=== Resolution Summary ==="
|
|
if [ $result1 -eq 0 ] && [ $result2 -eq 0 ] && [ $result3 -eq 0 ]; then
|
|
log "✓ All IP conflicts resolved successfully!"
|
|
log ""
|
|
log "Verification:"
|
|
log " ${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-192.168.11.50}}}}}} → VMID 7800 (sankofa-api-1) only"
|
|
log " ${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-192.168.11.51}}}}}} → VMID 7801 (sankofa-portal-1) only"
|
|
log " ${IP_SERVICE_52:-${IP_SERVICE_52:-192.168.11.52}} → VMID 7802 (sankofa-keycloak-1) only"
|
|
log " ${IP_GOV_PORTALS_DEV:-192.168.11.54} → VMID 7804 (gov-portals-dev) only"
|
|
log " ${IP_ORDER_LEGAL:-192.168.11.87} → VMID 10070 (order-legal)"
|
|
log " ${IP_SERVICE_55:-${IP_SERVICE_55:-192.168.11.55}} → VMID 10230 (order-vault)"
|
|
log " ${IP_SERVICE_56:-${IP_SERVICE_56:-192.168.11.56}} → VMID 10232 (CT10232)"
|
|
exit 0
|
|
else
|
|
log_error "Some conflicts could not be resolved. Check log file: $LOG_FILE"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
main "$@"
|