ansible/auto-fallback.sh
ilia de49b34cdc
Some checks failed
CI / skip-ci-check (pull_request) Successful in 6s
CI / lint-and-test (pull_request) Failing after 9s
CI / ansible-validation (pull_request) Failing after 6s
CI / secret-scanning (pull_request) Successful in 5s
CI / dependency-scan (pull_request) Successful in 8s
CI / sast-scan (pull_request) Failing after 5s
CI / license-check (pull_request) Successful in 11s
CI / vault-check (pull_request) Failing after 6s
CI / playbook-test (pull_request) Failing after 6s
CI / container-scan (pull_request) Failing after 6s
CI / sonar-analysis (pull_request) Failing after 2s
CI / workflow-summary (pull_request) Successful in 4s
Add homelab monitoring, portfolio site, and vault tooling.
Document pve10 static IPs, monitoring stack, and site LXCs; add portfolio
to inventory; Mailcow mailbox automation; vault import/export scripts;
security audit guides and UniFi DHCP reference.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 16:25:07 -04:00

119 lines
3.9 KiB
Bash
Executable File

#!/bin/bash
# Automatically switch to fallback IPs when primary IPs fail
HOSTS_FILE="inventories/production/hosts"
TIMEOUT=3
CHANGED=false
UNAME_S="$(uname -s)"
# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}Auto-fallback: Testing and switching to fallback IPs when needed...${NC}"
echo "=================================================================="
# Function to test IP connectivity
test_ip() {
local ip="$1"
if [[ "$UNAME_S" == "Darwin" ]]; then
# macOS: -W is wait time in milliseconds
ping -c 1 -W $((TIMEOUT * 1000)) "$ip" >/dev/null 2>&1
else
# Linux: -W is timeout in seconds
ping -c 1 -W "$TIMEOUT" "$ip" >/dev/null 2>&1
fi
}
# Function to test SSH connectivity
test_ssh() {
local host="$1"
local ip="$2"
local user="$3"
if ssh -o ConnectTimeout=3 -o BatchMode=yes "$user@$ip" exit >/dev/null 2>&1; then
return 0
else
return 1
fi
}
# Function to switch to fallback IP
switch_to_fallback() {
local hostname="$1"
local primary_ip="$2"
local fallback_ip="$3"
echo -e " ${YELLOW}→ Switching $hostname to fallback IP: $fallback_ip${NC}"
# Use sed to replace the primary IP with fallback IP (BSD/GNU compatible)
if [[ "$UNAME_S" == "Darwin" ]]; then
sed -i '' "s/$hostname ansible_host=$primary_ip/$hostname ansible_host=$fallback_ip/" "$HOSTS_FILE"
sed -i '' "s/ ansible_host_fallback=$fallback_ip//" "$HOSTS_FILE"
else
sed -i "s/$hostname ansible_host=$primary_ip/$hostname ansible_host=$fallback_ip/" "$HOSTS_FILE"
sed -i "s/ ansible_host_fallback=$fallback_ip//" "$HOSTS_FILE"
fi
CHANGED=true
}
# Parse hosts file and test connectivity
while IFS= read -r line; do
# Skip empty lines and comments
[[ -z "$line" || "$line" =~ ^# ]] && continue
# Skip group headers
[[ "$line" =~ ^\[.*\]$ ]] && continue
# Parse host entry
if [[ "$line" =~ ansible_host= ]]; then
hostname=$(echo "$line" | awk '{print $1}')
primary_ip=$(echo "$line" | sed -n 's/.*ansible_host=\([^[:space:]]*\).*/\1/p')
fallback_ip=$(echo "$line" | sed -n 's/.*ansible_host_fallback=\([^[:space:]]*\).*/\1/p')
user=$(echo "$line" | sed -n 's/.*ansible_user=\([^[:space:]]*\).*/\1/p')
[[ -z "$user" ]] && user="root"
echo -n "Testing $hostname ($primary_ip)... "
# Test primary IP
if test_ip "$primary_ip"; then
# Test SSH on primary IP
if test_ssh "$hostname" "$primary_ip" "$user"; then
echo -e "${GREEN}✓ OK${NC}"
else
echo -e "${YELLOW}⚠ Ping OK, SSH failed${NC}"
if [[ -n "$fallback_ip" ]]; then
echo -e " ${BLUE}→ Trying fallback IP...${NC}"
if test_ip "$fallback_ip" && test_ssh "$hostname" "$fallback_ip" "$user"; then
switch_to_fallback "$hostname" "$primary_ip" "$fallback_ip"
else
echo -e " ${RED}✗ Fallback also failed${NC}"
fi
fi
fi
else
echo -e "${RED}✗ Primary IP failed${NC}"
if [[ -n "$fallback_ip" ]]; then
echo -e " ${BLUE}→ Trying fallback IP...${NC}"
if test_ip "$fallback_ip" && test_ssh "$hostname" "$fallback_ip" "$user"; then
switch_to_fallback "$hostname" "$primary_ip" "$fallback_ip"
else
echo -e " ${RED}✗ Fallback also failed${NC}"
fi
fi
fi
fi
done < "$HOSTS_FILE"
echo ""
if [[ "$CHANGED" == "true" ]]; then
echo -e "${GREEN}✓ Hosts file updated with working IPs!${NC}"
echo -e "${BLUE}You can now run your Ansible commands.${NC}"
else
echo -e "${GREEN}✓ All primary IPs are working - no changes needed.${NC}"
fi