Files
proxmox/scripts/fix-all-infrastructure-issues.sh
defiQUG cb47cce074 Complete markdown files cleanup and organization
- Organized 252 files across project
- Root directory: 187 → 2 files (98.9% reduction)
- Moved configuration guides to docs/04-configuration/
- Moved troubleshooting guides to docs/09-troubleshooting/
- Moved quick start guides to docs/01-getting-started/
- Moved reports to reports/ directory
- Archived temporary files
- Generated comprehensive reports and documentation
- Created maintenance scripts and guides

All files organized according to established standards.
2026-01-06 01:46:25 -08:00

395 lines
15 KiB
Bash
Executable File

#!/usr/bin/env bash
# Fix All Infrastructure Issues
# Automates fixes for: DNS records, duplicate cleanup, tunnel configuration instructions
#
# Usage: ./scripts/fix-all-infrastructure-issues.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ENV_FILE="$PROJECT_ROOT/.env"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
log_error() { echo -e "${RED}[✗]${NC} $1"; }
# Tunnel ID from current configuration
TUNNEL_ID="10ab22da-8ea3-4e2e-a896-27ece2211a05"
TUNNEL_TARGET="${TUNNEL_ID}.cfargotunnel.com"
DOMAIN="d-bis.org"
CENTRAL_NGINX_IP="192.168.11.21"
CENTRAL_NGINX_PORT="80"
echo ""
log_info "═══════════════════════════════════════════════════════════"
log_info " FIXING ALL INFRASTRUCTURE ISSUES"
log_info "═══════════════════════════════════════════════════════════"
echo ""
# Check for .env file
if [ ! -f "$ENV_FILE" ]; then
log_error ".env file not found at: $ENV_FILE"
log_info "Please create .env file with Cloudflare credentials:"
log_info " CLOUDFLARE_API_TOKEN=your-token"
log_info " OR"
log_info " CLOUDFLARE_API_KEY=your-key"
log_info " CLOUDFLARE_EMAIL=your-email"
log_info ""
log_info "See: scripts/get-cloudflare-api-key.md for instructions"
exit 1
fi
# Source .env file
source "$ENV_FILE"
# Determine authentication method
AUTH_HEADERS=()
if [ -n "${CLOUDFLARE_API_TOKEN:-}" ]; then
AUTH_HEADERS=(-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN")
log_success "Using API Token authentication"
elif [ -n "${CLOUDFLARE_API_KEY:-}" ] && [ -n "${CLOUDFLARE_EMAIL:-}" ]; then
AUTH_HEADERS=(-H "X-Auth-Email: $CLOUDFLARE_EMAIL" -H "X-Auth-Key: $CLOUDFLARE_API_KEY")
log_success "Using API Key authentication"
else
log_error "No Cloudflare credentials found in .env"
exit 1
fi
# Get Zone ID
log_info "Getting Cloudflare Zone ID for $DOMAIN..."
ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \
"${AUTH_HEADERS[@]}" \
-H "Content-Type: application/json")
ZONE_ID=$(echo "$ZONE_RESPONSE" | jq -r '.result[0].id // empty' 2>/dev/null || echo "")
if [ -z "$ZONE_ID" ] || [ "$ZONE_ID" = "null" ]; then
log_error "Failed to get zone ID for $DOMAIN"
echo "$ZONE_RESPONSE" | jq '.' 2>/dev/null || echo "$ZONE_RESPONSE"
exit 1
fi
log_success "Zone ID: $ZONE_ID"
# Cloudflare API function
cloudflare_api() {
local method=$1
local endpoint=$2
local data=${3:-}
if [ -n "$data" ]; then
curl -s -X "$method" \
"https://api.cloudflare.com/client/v4/$endpoint" \
"${AUTH_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d "$data"
else
curl -s -X "$method" \
"https://api.cloudflare.com/client/v4/$endpoint" \
"${AUTH_HEADERS[@]}" \
-H "Content-Type: application/json"
fi
}
# Check if DNS record exists
record_exists() {
local record_type=$1
local record_name=$2
local response=$(cloudflare_api "GET" "zones/$ZONE_ID/dns_records?type=$record_type&name=$record_name")
echo "$response" | jq -e '.result | length > 0' > /dev/null 2>&1
}
# Get DNS record ID
get_record_id() {
local record_type=$1
local record_name=$2
local response=$(cloudflare_api "GET" "zones/$ZONE_ID/dns_records?type=$record_type&name=$record_name")
echo "$response" | jq -r '.result[0].id // empty'
}
# Get all record IDs for a name (for duplicates)
get_all_record_ids() {
local record_type=$1
local record_name=$2
local response=$(cloudflare_api "GET" "zones/$ZONE_ID/dns_records?type=$record_type&name=$record_name")
echo "$response" | jq -r '.result[].id'
}
# Create or update DNS record
create_or_update_dns() {
local record_type=$1
local record_name=$2
local record_content=$3
local proxied=${4:-true}
if record_exists "$record_type" "$record_name"; then
log_info "Updating DNS record: $record_name ($record_type) → $record_content"
local record_id=$(get_record_id "$record_type" "$record_name")
local data=$(jq -n \
--arg type "$record_type" \
--arg name "$record_name" \
--arg content "$record_content" \
--argjson proxied "$proxied" \
'{
type: $type,
name: $name,
content: $content,
ttl: 1,
proxied: $proxied
}')
local response=$(cloudflare_api "PUT" "zones/$ZONE_ID/dns_records/$record_id" "$data")
if echo "$response" | jq -e '.success' > /dev/null; then
log_success "DNS record updated: $record_name"
else
log_error "Failed to update DNS record: $record_name"
echo "$response" | jq -r '.errors[0].message' 2>/dev/null || echo "$response"
return 1
fi
else
log_info "Creating DNS record: $record_name ($record_type) → $record_content"
local data=$(jq -n \
--arg type "$record_type" \
--arg name "$record_name" \
--arg content "$record_content" \
--argjson proxied "$proxied" \
'{
type: $type,
name: $name,
content: $content,
ttl: 1,
proxied: $proxied
}')
local response=$(cloudflare_api "POST" "zones/$ZONE_ID/dns_records" "$data")
if echo "$response" | jq -e '.success' > /dev/null; then
log_success "DNS record created: $record_name"
else
log_error "Failed to create DNS record: $record_name"
echo "$response" | jq -r '.errors[0].message' 2>/dev/null || echo "$response"
return 1
fi
fi
}
# Delete DNS record
delete_dns_record() {
local record_id=$1
local record_name=$2
log_info "Deleting DNS record: $record_name (ID: $record_id)"
local response=$(cloudflare_api "DELETE" "zones/$ZONE_ID/dns_records/$record_id")
if echo "$response" | jq -e '.success' > /dev/null; then
log_success "DNS record deleted: $record_name"
else
log_error "Failed to delete DNS record: $record_name"
echo "$response" | jq -r '.errors[0].message' 2>/dev/null || echo "$response"
return 1
fi
}
# Remove duplicate A records (keep first, delete rest)
remove_duplicate_a_records() {
local record_name=$1
log_info "Checking for duplicate A records: $record_name"
local record_ids=($(get_all_record_ids "A" "$record_name"))
if [ ${#record_ids[@]} -gt 1 ]; then
log_warn "Found ${#record_ids[@]} A records for $record_name"
# Get all records to see which IP to keep
local response=$(cloudflare_api "GET" "zones/$ZONE_ID/dns_records?type=A&name=$record_name")
local records=$(echo "$response" | jq -r '.result[] | "\(.id)|\(.content)"')
# Keep the first record, delete the rest
local first=true
while IFS='|' read -r record_id content; do
if [ "$first" = true ]; then
log_info "Keeping A record: $record_name$content (ID: $record_id)"
first=false
else
delete_dns_record "$record_id" "$record_name$content"
fi
done <<< "$records"
else
log_success "No duplicates found for $record_name"
fi
}
echo ""
log_info "═══════════════════════════════════════════════════════════"
log_info " STEP 1: CREATE MISSING DNS CNAME RECORDS"
log_info "═══════════════════════════════════════════════════════════"
echo ""
# Missing DNS CNAME records to create
declare -a MISSING_DNS=(
"rpc-http-pub.d-bis.org"
"rpc-ws-pub.d-bis.org"
"rpc-http-prv.d-bis.org"
"rpc-ws-prv.d-bis.org"
"dbis-admin.d-bis.org"
"dbis-api.d-bis.org"
"dbis-api-2.d-bis.org"
"mim4u.org"
"www.mim4u.org"
)
for domain in "${MISSING_DNS[@]}"; do
create_or_update_dns "CNAME" "$domain" "$TUNNEL_TARGET" true
sleep 0.5 # Rate limiting
done
echo ""
log_info "═══════════════════════════════════════════════════════════"
log_info " STEP 2: REMOVE DUPLICATE DNS A RECORDS"
log_info "═══════════════════════════════════════════════════════════"
echo ""
# Domains with duplicate A records
declare -a DUPLICATE_DOMAINS=(
"besu.d-bis.org"
"blockscout.d-bis.org"
"explorer.d-bis.org"
"d-bis.org"
)
for domain in "${DUPLICATE_DOMAINS[@]}"; do
remove_duplicate_a_records "$domain"
sleep 0.5 # Rate limiting
done
echo ""
log_info "═══════════════════════════════════════════════════════════"
log_info " STEP 3: TUNNEL CONFIGURATION INSTRUCTIONS"
log_info "═══════════════════════════════════════════════════════════"
echo ""
log_warn "Tunnel configuration must be done manually in Cloudflare dashboard"
log_info ""
log_info "Tunnel: rpc-http-pub.d-bis.org (ID: $TUNNEL_ID)"
log_info "Status: Currently DOWN - needs configuration"
log_info ""
log_info "Action Required:"
log_info "1. Go to: https://one.dash.cloudflare.com/"
log_info "2. Navigate to: Zero Trust → Networks → Tunnels"
log_info "3. Click on: rpc-http-pub.d-bis.org"
log_info "4. Click: Configure → Public Hostnames"
log_info "5. Update all HTTP endpoints to route to: http://${CENTRAL_NGINX_IP}:${CENTRAL_NGINX_PORT}"
log_info ""
log_info "HTTP Endpoints (route to central Nginx):"
for domain in "explorer.d-bis.org" "rpc-http-pub.d-bis.org" "rpc-http-prv.d-bis.org" \
"dbis-admin.d-bis.org" "dbis-api.d-bis.org" "dbis-api-2.d-bis.org" \
"mim4u.org" "www.mim4u.org"; do
log_info " - $domain → http://${CENTRAL_NGINX_IP}:${CENTRAL_NGINX_PORT}"
done
log_info ""
log_info "WebSocket Endpoints (keep direct routing):"
log_info " - rpc-ws-pub.d-bis.org → https://192.168.11.252:443"
log_info " - rpc-ws-prv.d-bis.org → https://192.168.11.251:443"
log_info ""
echo ""
log_info "═══════════════════════════════════════════════════════════"
log_info " STEP 4: VERIFY NETWORK CONNECTIVITY"
log_info "═══════════════════════════════════════════════════════════"
echo ""
# Test connectivity
log_info "Testing network connectivity..."
# Test pve2 → ml110
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "ping -c 1 -W 2 192.168.11.10 >/dev/null 2>&1"; then
log_success "Network: pve2 (192.168.11.12) → ml110 (192.168.11.10) ✓"
else
log_error "Network: pve2 (192.168.11.12) → ml110 (192.168.11.10) ✗"
fi
# Test central Nginx → RPC nodes
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 http://192.168.11.250:443/health >/dev/null 2>&1 || pct exec 105 -- curl -s -m 2 -k https://192.168.11.250:443/health >/dev/null 2>&1"; then
log_success "Network: Central Nginx → RPC-1 (192.168.11.250) ✓"
else
log_warn "Network: Central Nginx → RPC-1 (192.168.11.250) - May need verification"
fi
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 -k https://192.168.11.251:443/health >/dev/null 2>&1"; then
log_success "Network: Central Nginx → RPC-2 (192.168.11.251) ✓"
else
log_warn "Network: Central Nginx → RPC-2 (192.168.11.251) - May need verification"
fi
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 -k https://192.168.11.252:443/health >/dev/null 2>&1"; then
log_success "Network: Central Nginx → RPC-3 (192.168.11.252) ✓"
else
log_warn "Network: Central Nginx → RPC-3 (192.168.11.252) - May need verification"
fi
# Test central Nginx → DBIS services
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 http://192.168.11.130:80 >/dev/null 2>&1"; then
log_success "Network: Central Nginx → DBIS Frontend (192.168.11.130) ✓"
else
log_warn "Network: Central Nginx → DBIS Frontend (192.168.11.130) - May need verification"
fi
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 http://192.168.11.150:3000/health >/dev/null 2>&1"; then
log_success "Network: Central Nginx → DBIS API (192.168.11.150) ✓"
else
log_warn "Network: Central Nginx → DBIS API (192.168.11.150) - May need verification"
fi
# Test central Nginx → Blockscout
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 http://192.168.11.140:80/health >/dev/null 2>&1"; then
log_success "Network: Central Nginx → Blockscout (192.168.11.140) ✓"
else
log_warn "Network: Central Nginx → Blockscout (192.168.11.140) - May need verification"
fi
# Test central Nginx → MIM
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.12 "pct exec 105 -- curl -s -m 2 http://192.168.11.19:80 >/dev/null 2>&1"; then
log_success "Network: Central Nginx → MIM (192.168.11.19) ✓"
else
log_warn "Network: Central Nginx → MIM (192.168.11.19) - May need verification"
fi
echo ""
log_info "═══════════════════════════════════════════════════════════"
log_info " SUMMARY"
log_info "═══════════════════════════════════════════════════════════"
echo ""
log_success "DNS CNAME records created/updated: ${#MISSING_DNS[@]}"
log_success "Duplicate A records cleaned: ${#DUPLICATE_DOMAINS[@]}"
log_warn "Tunnel configuration: Manual action required (see instructions above)"
echo ""
log_info "Next Steps:"
log_info "1. ✅ DNS records updated"
log_info "2. ⏳ Update Cloudflare tunnel configuration (manual)"
log_info "3. ⏳ Wait 1-2 minutes for DNS propagation"
log_info "4. ⏳ Test all endpoints"
echo ""
log_info "Test commands:"
log_info " curl https://rpc-http-pub.d-bis.org -X POST -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":1}'"
log_info " curl https://explorer.d-bis.org/api/v2/stats"
log_info " curl https://dbis-admin.d-bis.org"
log_info " curl https://mim4u.org"
echo ""