Files
proxmox/scripts/list_vms_with_tunnels.py

160 lines
5.9 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
List Proxmox VMs using tunnel information from .env and tunnel configs.
This script attempts multiple connection methods:
1. Direct connection (if on same network)
2. Via Cloudflare tunnel URLs (for web access)
3. Via SSH tunnel (if SSH access available)
"""
import os
import sys
import json
import subprocess
from typing import Dict, List, Optional, Any
from proxmoxer import ProxmoxAPI
# Tunnel URL mappings from tunnel configs
TUNNEL_URLS = {
'192.168.11.10': 'ml110-01.d-bis.org',
'192.168.11.11': 'r630-01.d-bis.org',
'192.168.11.12': 'r630-02.d-bis.org',
}
def load_env_file(env_path: str = None) -> dict:
"""Load environment variables from .env file."""
if env_path is None:
env_path = os.path.expanduser('~/.env')
env_vars = {}
if os.path.exists(env_path):
try:
with open(env_path, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip().strip('"').strip("'")
env_vars[key] = value
except Exception as e:
print(f"Warning: Could not load {env_path}: {e}", file=sys.stderr)
return env_vars
def test_connection(host: str, port: int = 8006, timeout: int = 5) -> bool:
"""Test if host:port is reachable."""
try:
result = subprocess.run(
['timeout', str(timeout), 'bash', '-c', f'echo > /dev/tcp/{host}/{port}'],
capture_output=True,
timeout=timeout + 1
)
return result.returncode == 0
except:
return False
def get_proxmox_connection() -> Optional[ProxmoxAPI]:
"""Initialize Proxmox API connection with tunnel awareness."""
env_vars = load_env_file()
host = os.getenv('PROXMOX_HOST', env_vars.get('PROXMOX_HOST', '192.168.11.10'))
port = int(os.getenv('PROXMOX_PORT', env_vars.get('PROXMOX_PORT', '8006')))
user = os.getenv('PROXMOX_USER', env_vars.get('PROXMOX_USER', 'root@pam'))
token_name = os.getenv('PROXMOX_TOKEN_NAME', env_vars.get('PROXMOX_TOKEN_NAME', 'mcpserver'))
token_value = os.getenv('PROXMOX_TOKEN_VALUE', env_vars.get('PROXMOX_TOKEN_VALUE'))
password = os.getenv('PROXMOX_PASSWORD', env_vars.get('PROXMOX_PASSWORD'))
verify_ssl = os.getenv('PROXMOX_VERIFY_SSL', env_vars.get('PROXMOX_VERIFY_SSL', 'false')).lower() == 'true'
# Check tunnel URL for this host
tunnel_url = TUNNEL_URLS.get(host)
print(f"🔍 Connection Analysis", file=sys.stderr)
print(f" Target Host: {host}:{port}", file=sys.stderr)
if tunnel_url:
print(f" Tunnel URL: https://{tunnel_url}", file=sys.stderr)
print(f" User: {user}", file=sys.stderr)
print("", file=sys.stderr)
# Test direct connection
print(f"Testing direct connection to {host}:{port}...", file=sys.stderr)
if test_connection(host, port):
print(f"✅ Direct connection available", file=sys.stderr)
else:
print(f"❌ Direct connection failed", file=sys.stderr)
if tunnel_url:
print(f"💡 Tunnel available: https://{tunnel_url}", file=sys.stderr)
print(f" Note: Tunnel URLs work for web UI, not API", file=sys.stderr)
print("", file=sys.stderr)
print("Solutions:", file=sys.stderr)
print(" 1. Use SSH tunnel: ssh -L 8006:{host}:8006 user@{host}", file=sys.stderr)
print(" 2. Run script from Proxmox network (192.168.11.0/24)", file=sys.stderr)
print(" 3. Access web UI via tunnel: https://{tunnel_url}", file=sys.stderr)
return None
if not token_value and not password:
print("Error: PROXMOX_TOKEN_VALUE or PROXMOX_PASSWORD required", file=sys.stderr)
return None
try:
if token_value:
proxmox = ProxmoxAPI(
host=host,
port=port,
user=user,
token_name=token_name,
token_value=token_value,
verify_ssl=verify_ssl,
service='PVE'
)
else:
proxmox = ProxmoxAPI(
host=host,
port=port,
user=user,
password=password,
verify_ssl=verify_ssl,
service='PVE'
)
# Test connection
proxmox.version.get()
print(f"✅ Connected successfully!", file=sys.stderr)
return proxmox
except Exception as e:
error_msg = str(e)
if "ConnectTimeoutError" in error_msg or "timed out" in error_msg:
print(f"❌ Connection timeout", file=sys.stderr)
elif "401" in error_msg or "authentication" in error_msg.lower():
print(f"❌ Authentication failed", file=sys.stderr)
else:
print(f"❌ Connection error: {e}", file=sys.stderr)
return None
# Import the rest of the functions from list_vms.py
# For now, we'll just show the connection analysis
def main():
"""Main function."""
proxmox = get_proxmox_connection()
if not proxmox:
print("\n" + "="*60, file=sys.stderr)
print("Cannot establish API connection.", file=sys.stderr)
print("="*60, file=sys.stderr)
print("\nAlternative: Use the original list_vms.py script", file=sys.stderr)
print("from a machine on the Proxmox network (192.168.11.0/24)", file=sys.stderr)
sys.exit(1)
# If connection successful, import and use list_vms functions
try:
from list_vms import list_all_vms, print_vm_table
vms = list_all_vms(proxmox)
print_vm_table(vms)
except ImportError:
print("Error: Could not import list_vms functions", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()