Files
proxmox/scripts/get-npmplus-mappings.py
defiQUG 875454f449
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
scripts: deployment, NPM, verify, validation, env loader, operator helpers
Made-with: Cursor
2026-03-27 18:51:02 -07:00

239 lines
7.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Get all NPMplus proxy host mappings with VMID, Service, IP, Port, and FQDN
"""
import os
import sys
import json
import subprocess
from pathlib import Path
# IP to VMID mapping
IP_TO_VMID = {
"192.168.11.26": "105",
"192.168.11.27": "130",
"192.168.11.30": "103",
"192.168.11.31": "104",
"192.168.11.32": "100",
"192.168.11.33": "101",
"192.168.11.35": "6200",
"192.168.11.36": "7811",
"192.168.11.37": "7810",
"192.168.11.50": "7800",
"192.168.11.51": "7801",
"192.168.11.52": "7802",
"192.168.11.53": "7803",
"192.168.11.57": "6201",
"192.168.11.64": "6400",
"192.168.11.65": "6000",
"192.168.11.100": "1000",
"192.168.11.101": "1001",
"192.168.11.102": "1002",
"192.168.11.103": "1003",
"192.168.11.104": "1004",
"192.168.11.105": "10100",
"192.168.11.106": "10101",
"192.168.11.110": "106",
"192.168.11.111": "107",
"192.168.11.112": "108",
"192.168.11.125": "10120",
"192.168.11.130": "10130",
"192.168.11.140": "5000",
"192.168.11.150": "1500",
"192.168.11.151": "1501",
"192.168.11.152": "1502",
"192.168.11.153": "1503",
"192.168.11.154": "1504",
"192.168.11.155": "10150",
"192.168.11.156": "10151",
"192.168.11.166": "10233",
"192.168.11.167": "10234",
"192.168.11.211": "2101",
"192.168.11.221": "2201",
"192.168.11.232": "2301",
"192.168.11.233": "2303",
"192.168.11.234": "2304",
"192.168.11.235": "2305",
"192.168.11.236": "2306",
"192.168.11.237": "2307",
"192.168.11.238": "2308",
"192.168.11.240": "2400",
"192.168.11.241": "2401",
"192.168.11.242": "2402",
"192.168.11.243": "2403",
}
# IP to hostname mapping (from documentation)
IP_TO_HOSTNAME = {
"192.168.11.26": "nginxproxymanager",
"192.168.11.27": "monitoring-1",
"192.168.11.30": "omada",
"192.168.11.31": "gitea",
"192.168.11.32": "proxmox-mail-gateway",
"192.168.11.33": "proxmox-datacenter-manager",
"192.168.11.35": "firefly-1",
"192.168.11.36": "mim-api-1",
"192.168.11.37": "mim-web-1",
"192.168.11.50": "sankofa-api-1",
"192.168.11.51": "sankofa-portal-1",
"192.168.11.52": "sankofa-keycloak-1",
"192.168.11.53": "sankofa-postgres-1",
"192.168.11.57": "firefly-ali-1",
"192.168.11.64": "indy-1",
"192.168.11.65": "fabric-1",
"192.168.11.100": "besu-validator-1",
"192.168.11.101": "besu-validator-2",
"192.168.11.102": "besu-validator-3",
"192.168.11.103": "besu-validator-4",
"192.168.11.104": "besu-validator-5",
"192.168.11.105": "dbis-postgres-primary",
"192.168.11.106": "dbis-postgres-replica-1",
"192.168.11.110": "redis-rpc-translator",
"192.168.11.111": "web3signer-rpc-translator",
"192.168.11.112": "vault-rpc-translator",
"192.168.11.125": "dbis-redis",
"192.168.11.130": "dbis-frontend",
"192.168.11.140": "blockscout-1",
"192.168.11.150": "besu-sentry-1",
"192.168.11.151": "besu-sentry-2",
"192.168.11.152": "besu-sentry-3",
"192.168.11.153": "besu-sentry-4",
"192.168.11.154": "besu-sentry-ali",
"192.168.11.155": "dbis-api-primary",
"192.168.11.156": "dbis-api-secondary",
"192.168.11.166": "npmplus",
"192.168.11.167": "npmplus-secondary",
"192.168.11.211": "besu-rpc-core-1",
"192.168.11.221": "besu-rpc-public-1",
"192.168.11.232": "besu-rpc-private-1",
"192.168.11.233": "besu-rpc-ali-0x8a",
"192.168.11.234": "besu-rpc-ali-0x1",
"192.168.11.235": "besu-rpc-luis-0x8a",
"192.168.11.236": "besu-rpc-luis-0x1",
"192.168.11.237": "besu-rpc-putu-0x8a",
"192.168.11.238": "besu-rpc-putu-0x1",
"192.168.11.240": "thirdweb-rpc-1",
"192.168.11.241": "besu-rpc-thirdweb-0x8a-1",
"192.168.11.242": "besu-rpc-thirdweb-0x8a-2",
"192.168.11.243": "besu-rpc-thirdweb-0x8a-3",
}
def get_hostname_from_proxmox(ip, vmid):
"""Try to get hostname from Proxmox"""
try:
result = subprocess.run(
["ssh", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=2",
"root@192.168.11.11", f"pct config {vmid} 2>/dev/null | grep '^hostname:' | awk '{{print $2}}'"],
capture_output=True,
text=True,
timeout=3
)
if result.returncode == 0 and result.stdout.strip():
return result.stdout.strip()
except:
pass
return IP_TO_HOSTNAME.get(ip, f"VMID-{vmid}")
def main():
project_root = Path(__file__).parent.parent
# Load .env
env_file = project_root / ".env"
npm_email = None
npm_password = None
if env_file.exists():
with open(env_file) as f:
for line in f:
if line.startswith("NPM_EMAIL="):
npm_email = line.split("=", 1)[1].strip().strip('"').strip("'")
elif line.startswith("NPM_PASSWORD="):
npm_password = line.split("=", 1)[1].strip().strip('"').strip("'")
if not npm_email or not npm_password:
print("Error: NPM_EMAIL and NPM_PASSWORD must be set in .env", file=sys.stderr)
sys.exit(1)
npm_url = "https://192.168.11.166:81"
# Authenticate
import urllib.request
import urllib.parse
auth_data = json.dumps({
"identity": npm_email,
"secret": npm_password
}).encode()
try:
req = urllib.request.Request(
f"{npm_url}/api/tokens",
data=auth_data,
headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req, context=None) as response:
token_response = json.loads(response.read().decode())
token = token_response.get("token")
except Exception as e:
print(f"Error authenticating: {e}", file=sys.stderr)
sys.exit(1)
if not token:
print("Error: Authentication failed", file=sys.stderr)
sys.exit(1)
# Get proxy hosts
try:
req = urllib.request.Request(
f"{npm_url}/api/nginx/proxy-hosts",
headers={"Authorization": f"Bearer {token}"}
)
with urllib.request.urlopen(req, context=None) as response:
proxy_hosts = json.loads(response.read().decode())
except Exception as e:
print(f"Error fetching proxy hosts: {e}", file=sys.stderr)
sys.exit(1)
# Format output
rows = []
for host in proxy_hosts:
host_id = host.get("id")
domain_names = host.get("domain_names", [])
forward_host = host.get("forward_host", "")
forward_port = host.get("forward_port", "")
forward_scheme = host.get("forward_scheme", "http")
if not domain_names:
continue
fqdn = domain_names[0] if isinstance(domain_names, list) else str(domain_names)
vmid = IP_TO_VMID.get(forward_host, "N/A")
if vmid != "N/A":
service = get_hostname_from_proxmox(forward_host, vmid)
else:
service = f"External/{forward_host}"
rows.append({
"vmid": vmid,
"service": service,
"ip": forward_host,
"port": forward_port,
"fqdn": fqdn,
"scheme": forward_scheme
})
# Sort by VMID
rows.sort(key=lambda x: (int(x["vmid"]) if x["vmid"].isdigit() else 999999, x["fqdn"]))
# Print table
print(f"{'VMID':<8} {'Service/Hostname':<40} {'IP Address':<18} {'Port':<6} {'FQDN':<60}")
print(f"{'-'*8} {'-'*40} {'-'*18} {'-'*6} {'-'*60}")
for row in rows:
print(f"{row['vmid']:<8} {row['service']:<40} {row['ip']:<18} {row['port']:<6} {row['fqdn']:<60}")
if __name__ == "__main__":
main()