#!/usr/bin/env python3 """ Scan all containers across all Proxmox hosts Outputs: VMID, name, host, IP config, current IP, status """ import subprocess import sys from datetime import datetime import re HOSTS = [ ("192.168.11.10", "ml110"), ("192.168.11.11", "r630-01"), ("192.168.11.12", "r630-02"), ] def ssh_command(host, command): """Execute SSH command and return output""" try: result = subprocess.run( ["ssh", "-o", "ConnectTimeout=10", f"root@{host}", command], capture_output=True, text=True, timeout=30 ) return result.stdout.strip() if result.returncode == 0 else "" except Exception as e: print(f" Error executing command on {host}: {e}", file=sys.stderr) return "" def get_container_info(host, vmid): """Get all info for a container in one call""" script = f""" name=$(pct config {vmid} 2>/dev/null | grep '^name:' | cut -d: -f2 | tr -d ' ' || echo 'unnamed') hostname_vm=$(pct config {vmid} 2>/dev/null | grep '^hostname:' | cut -d: -f2 | tr -d ' ' || echo 'N/A') status=$(pct status {vmid} 2>/dev/null | grep 'status:' | awk '{{print $2}}' || echo 'unknown') net_config=$(pct config {vmid} 2>/dev/null | grep '^net0:' || echo '') ip_config='N/A' current_ip='N/A' if echo "$net_config" | grep -q 'ip='; then ip_config=$(echo "$net_config" | grep -oE 'ip=[^,]+' | cut -d= -f2) if [ "$ip_config" = 'dhcp' ] || [ "$ip_config" = 'auto' ]; then if [ "$status" = 'running' ]; then current_ip=$(pct exec {vmid} -- hostname -I 2>/dev/null | awk '{{print $1}}' || echo 'N/A') fi else current_ip=$(echo "$ip_config" | cut -d'/' -f1) fi fi echo "$name|$hostname_vm|$status|$ip_config|$current_ip" """ output = ssh_command(host, script) if output: parts = output.split('|') if len(parts) == 5: return { 'name': parts[0], 'hostname': parts[1], 'status': parts[2], 'ip_config': parts[3], 'current_ip': parts[4] } return None def main(): timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_file = f"/home/intlc/projects/proxmox/CONTAINER_INVENTORY_{timestamp}.md" csv_file = f"/home/intlc/projects/proxmox/container_inventory_{timestamp}.csv" print("=== Scanning All Containers Across All Hosts ===\n") # Create output files with open(output_file, 'w') as f: f.write(f"""# Container Inventory - Complete Scan **Generated**: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} **Purpose**: Complete inventory of all containers across all Proxmox hosts --- ## All Containers | VMID | Name | Host | Status | IP Config | Current IP | Hostname | |------|------|------|--------|----------|------------|----------| """) with open(csv_file, 'w') as f: f.write("VMID,Name,Host,Status,IP_Config,Current_IP,Hostname\n") dhcp_count = 0 static_count = 0 total_count = 0 for host_ip, hostname in HOSTS: print(f"Scanning {hostname} ({host_ip})...") # Get all VMIDs vmids_output = ssh_command(host_ip, "pct list 2>/dev/null | tail -n +2 | awk '{print $1}'") if not vmids_output: print(f" No containers found on {hostname}") continue vmids = [vmid.strip() for vmid in vmids_output.split('\n') if vmid.strip()] for vmid in vmids: info = get_container_info(host_ip, vmid) if not info: continue total_count += 1 # Count by type if info['ip_config'] in ['dhcp', 'auto']: dhcp_count += 1 elif info['ip_config'] != 'N/A' and info['ip_config']: static_count += 1 # Write to files with open(output_file, 'a') as f: f.write(f"| {vmid} | {info['name']} | {hostname} | {info['status']} | {info['ip_config']} | {info['current_ip']} | {info['hostname']} |\n") with open(csv_file, 'a') as f: f.write(f"{vmid},\"{info['name']}\",{hostname},{info['status']},{info['ip_config']},{info['current_ip']},{info['hostname']}\n") print(f"\n=== Scan Complete ===") print(f"Total containers scanned: {total_count}") print(f"Output files:") print(f" - {output_file}") print(f" - {csv_file}") print(f"\n=== Summary by IP Configuration ===") print(f"DHCP containers: {dhcp_count}") print(f"Static IP containers: {static_count}") print(f"Total containers: {total_count}") if __name__ == "__main__": main()