Files
proxmox/scripts/audit-npmplus-vm-mappings.sh.bak
defiQUG fbda1b4beb
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
docs: Ledger Live integration, contract deploy learnings, NEXT_STEPS updates
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands
- CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround
- CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check
- NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere
- MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates
- LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 15:46:57 -08:00

227 lines
8.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Comprehensive audit of NPMplus proxy host mappings against all Proxmox VMs
# Identifies inconsistencies, missing mappings, and incorrect routes
set -euo pipefail
PROXMOX_HOST="${1:-192.168.11.11}"
CONTAINER_ID="${2:-10233}"
# 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 "${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"; }
log_section() { echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; }
echo ""
log_section
echo "🔍 NPMplus VM Mapping Audit"
log_section
echo ""
# Step 1: Get all VMs from Proxmox
log_info "Step 1: Collecting all VMs from Proxmox..."
VM_LIST=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" "
for vmid in \$(pct list 2>/dev/null | awk 'NR>1 {print \$1}' | grep -E '^[0-9]+$'); do
status=\$(pct status \$vmid 2>&1 | head -1)
if echo \"\$status\" | grep -q 'running\|stopped'; then
hostname=\$(pct config \$vmid 2>/dev/null | grep '^hostname:' | awk '{print \$2}' || echo 'unknown')
# Extract IP, removing CIDR notation
ip=\$(pct config \$vmid 2>/dev/null | grep -E '^ip[0-9]+' | head -1 | awk -F'=' '{print \$2}' | awk '{print \$1}' | sed 's|/.*||' || echo '')
if [ -n \"\$ip\" ] && [ \"\$ip\" != \"\" ]; then
echo \"\$vmid|\$hostname|\$ip|\$status\"
fi
fi
done
" 2>&1)
# Step 2: Get all NPMplus proxy hosts
log_info "Step 2: Collecting NPMplus proxy host configurations..."
NPMPLUS_HOSTS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" "pct exec $CONTAINER_ID -- docker exec npmplus node -e \"
const Database = require('better-sqlite3');
const db = new Database('/data/npmplus/database.sqlite', { readonly: true });
const hosts = db.prepare('SELECT id, domain_names, forward_scheme, forward_host, forward_port, ssl_forced FROM proxy_host ORDER BY id').all();
console.log(JSON.stringify(hosts));
db.close();
\" 2>&1" || echo "[]")
# Step 3: Build VM IP to VMID mapping
log_info "Step 3: Building VM inventory..."
declare -A IP_TO_VMID
declare -A IP_TO_HOSTNAME
declare -A IP_TO_STATUS
while IFS='|' read -r vmid hostname ip status; do
if [ -n "$ip" ] && [ "$ip" != "" ]; then
IP_TO_VMID["$ip"]="$vmid"
IP_TO_HOSTNAME["$ip"]="$hostname"
IP_TO_STATUS["$ip"]="$status"
fi
done <<< "$VM_LIST"
# Step 4: Analyze NPMplus mappings
log_info "Step 4: Analyzing NPMplus mappings..."
echo ""
# Use temp files for arrays (bash limitation with subshells)
TMPDIR=$(mktemp -d)
INCONSISTENCIES_FILE="$TMPDIR/inconsistencies.txt"
MISSING_VMS_FILE="$TMPDIR/missing_vms.txt"
CORRECT_MAPPINGS_FILE="$TMPDIR/correct_mappings.txt"
IP_CONFLICTS_FILE="$TMPDIR/ip_conflicts.txt"
touch "$INCONSISTENCIES_FILE" "$MISSING_VMS_FILE" "$CORRECT_MAPPINGS_FILE" "$IP_CONFLICTS_FILE"
# Parse NPMplus hosts
echo "$NPMPLUS_HOSTS" | jq -r '.[] | "\(.id)|\(.domain_names)|\(.forward_host)|\(.forward_port)"' 2>/dev/null | while IFS='|' read -r host_id domains_json forward_host forward_port; do
domain=$(echo "$domains_json" | jq -r '.[0] // empty' 2>/dev/null || echo "$domains_json")
if [ -z "$forward_host" ] || [ "$forward_host" = "null" ]; then
continue
fi
# Check if IP maps to a VM - use associative array lookup
# Export the arrays by checking the VM_LIST directly
vmid=""
expected_hostname=""
status=""
# Search VM_LIST for matching IP
vm_match=$(echo "$VM_LIST" | grep "|$forward_host|" | head -1)
if [ -n "$vm_match" ]; then
IFS='|' read -r vmid expected_hostname ip_match status <<< "$vm_match"
fi
if [ -z "$vmid" ]; then
# IP not found in VM list - might be external or missing
echo "$domain|$forward_host|$forward_port|External or missing VM" >> "$MISSING_VMS_FILE"
else
# Check for IP conflicts (multiple VMs with same IP)
conflict_count=$(echo "$VM_LIST" | grep -c "|$forward_host|" || echo "0")
if [ "$conflict_count" -gt 1 ]; then
echo "$domain|$forward_host|Multiple VMs share this IP" >> "$IP_CONFLICTS_FILE"
fi
# Check if service is running
if echo "$status" | grep -q "stopped"; then
echo "$domain|$forward_host:$forward_port|VMID $vmid ($expected_hostname) is STOPPED" >> "$INCONSISTENCIES_FILE"
else
echo "$domain|$forward_host:$forward_port|VMID $vmid ($expected_hostname)" >> "$CORRECT_MAPPINGS_FILE"
fi
fi
done
# Step 5: Find VMs that might need NPMplus mappings
log_info "Step 5: Identifying VMs that might need NPMplus mappings..."
POTENTIAL_SERVICES_FILE="$TMPDIR/potential_services.txt"
touch "$POTENTIAL_SERVICES_FILE"
while IFS='|' read -r vmid hostname ip status; do
if [ -z "$ip" ] || [ "$ip" = "" ]; then
continue
fi
# Check if this VM is already in NPMplus
in_npmplus=$(echo "$NPMPLUS_HOSTS" | jq -r ".[] | select(.forward_host == \"$ip\") | .domain_names[0]" 2>/dev/null | head -1)
if [ -z "$in_npmplus" ] && echo "$status" | grep -q "running"; then
# Check if it's a web service (has ports 80, 443, 3000, 4000, 8080, etc.)
# This is a heuristic - you may need to adjust
if [[ "$hostname" =~ (portal|web|api|frontend|admin|dashboard|explorer|gitea|firefly) ]]; then
echo "$vmid|$hostname|$ip|Potential web service" >> "$POTENTIAL_SERVICES_FILE"
fi
fi
done <<< "$VM_LIST"
# Step 6: Generate report
log_section
echo "📊 Audit Report"
log_section
echo ""
CORRECT_COUNT=$(wc -l < "$CORRECT_MAPPINGS_FILE" | tr -d ' ')
INCONSISTENCY_COUNT=$(wc -l < "$INCONSISTENCIES_FILE" | tr -d ' ')
CONFLICT_COUNT=$(wc -l < "$IP_CONFLICTS_FILE" | tr -d ' ')
MISSING_COUNT=$(wc -l < "$MISSING_VMS_FILE" | tr -d ' ')
POTENTIAL_COUNT=$(wc -l < "$POTENTIAL_SERVICES_FILE" | tr -d ' ')
echo "✅ Correct Mappings ($CORRECT_COUNT):"
if [ "$CORRECT_COUNT" -eq 0 ]; then
log_warn " No correct mappings found (check script logic)"
else
while IFS='|' read -r domain target vm_info; do
printf " %-50s → %-25s (%s)\n" "$domain" "$target" "$vm_info"
done < "$CORRECT_MAPPINGS_FILE" | head -20
fi
echo ""
echo "⚠️ Inconsistencies ($INCONSISTENCY_COUNT):"
if [ "$INCONSISTENCY_COUNT" -eq 0 ]; then
log_success " No inconsistencies found"
else
while IFS='|' read -r domain target issue_desc; do
log_warn " $domain$target: $issue_desc"
done < "$INCONSISTENCIES_FILE"
fi
echo ""
echo "🔴 IP Conflicts ($CONFLICT_COUNT):"
if [ "$CONFLICT_COUNT" -eq 0 ]; then
log_success " No IP conflicts found"
else
while IFS='|' read -r domain ip issue_desc; do
log_error " $domain$ip: $issue_desc"
# Show which VMs share this IP
echo "$VM_LIST" | grep "|$ip|" | while IFS='|' read -r vmid hostname ip2 status; do
echo " - VMID $vmid: $hostname ($status)"
done
done < "$IP_CONFLICTS_FILE"
fi
echo ""
echo "❓ Missing/External IPs ($MISSING_COUNT):"
if [ "$MISSING_COUNT" -eq 0 ]; then
log_success " All IPs map to known VMs"
else
while IFS='|' read -r domain ip port reason; do
log_warn " $domain$ip:$port ($reason)"
done < "$MISSING_VMS_FILE"
fi
echo ""
echo "💡 Potential Services Not in NPMplus ($POTENTIAL_COUNT):"
if [ "$POTENTIAL_COUNT" -eq 0 ]; then
log_info " No obvious missing services"
else
while IFS='|' read -r vmid hostname ip reason; do
log_info " VMID $vmid: $hostname ($ip) - $reason"
done < "$POTENTIAL_SERVICES_FILE"
fi
echo ""
log_section
echo "📋 Summary"
log_section
echo "Total VMs found: $(echo "$VM_LIST" | wc -l)"
echo "NPMplus proxy hosts: $(echo "$NPMPLUS_HOSTS" | jq '. | length' 2>/dev/null || echo "0")"
echo "Correct mappings: $CORRECT_COUNT"
echo "Issues found: $((INCONSISTENCY_COUNT + CONFLICT_COUNT + MISSING_COUNT))"
echo ""
# Cleanup
rm -rf "$TMPDIR"
if [ $((INCONSISTENCY_COUNT + CONFLICT_COUNT)) -gt 0 ]; then
log_warn "⚠️ Action required: Review inconsistencies and IP conflicts above"
else
log_success "✅ No critical issues found"
fi