import os
from proxmoxer import ProxmoxAPI
import yaml
from openpyxl import Workbook
# --- Proxmox 접속 정보 (API 토큰 방식) ---
PROXMOX_HOST = 'changeme' # IP를 입력
PROXMOX_TOKEN_ID = 'changeme' # Token ID
PROXMOX_TOKEN_SECRET = 'changeme' # Secret 값
# SSL 인증서 경고를 무시
VERIFY_SSL = False
def get_guest_ip(proxmox, node, vmid, guest_type):
"""QEMU Guest Agent를 통해 게스트의 IP 주소를 가져옵니다."""
try:
if guest_type == 'qemu':
interfaces = proxmox.nodes(node).qemu(vmid).agent.get('network-get-interfaces')['result']
else: # lxc
interfaces = proxmox.nodes(node).lxc(vmid).agent.get('network-get-interfaces')['result']
for iface in interfaces:
if 'ip-addresses' not in iface:
continue
for ip in iface['ip-addresses']:
if ip.get('ip-address-type') == 'ipv4' and not ip.get('ip-address', '').startswith('127.'):
return ip['ip-address']
except Exception:
pass
return 'N/A'
def collect_proxmox_data():
"""Proxmox 서버에서 VM 및 컨테이너 정보를 수집합니다."""
try:
proxmox = ProxmoxAPI(
PROXMOX_HOST,
user='root@pam',
token_name=PROXMOX_TOKEN_ID.split('!')[1],
token_value=PROXMOX_TOKEN_SECRET,
verify_ssl=VERIFY_SSL
)
except Exception as e:
print(f"Error connecting to Proxmox: {e}")
return None
all_guests_info = []
print("Successfully connected to Proxmox. Collecting guest information...")
for node in proxmox.nodes.get():
node_name = node['node']
print(f"Scanning node: {node_name}")
# 가상머신(VM) 정보 수집
for vm_summary in proxmox.nodes(node_name).qemu.get():
vmid = vm_summary['vmid']
vm_config = proxmox.nodes(node_name).qemu(vmid).config.get()
vm_info = {
'id': vmid,
'node': node_name,
'hostname': vm_summary['name'],
'ip': get_guest_ip(proxmox, node_name, vmid, 'qemu'),
'vcpu': vm_summary['cpus'],
'ram_gb': round(vm_summary['maxmem'] / (1024**3), 2),
'disk_gb': round(vm_summary.get('maxdisk', 0) / (1024**3), 2),
'note': vm_config.get('description', '').replace('\n', ' ')
}
all_guests_info.append(vm_info)
# 컨테이너(LXC) 정보 수집
for lxc_summary in proxmox.nodes(node_name).lxc.get():
vmid = lxc_summary['vmid']
lxc_config = proxmox.nodes(node_name).lxc(vmid).config.get()
lxc_info = {
'id': vmid,
'node': node_name,
'hostname': lxc_summary['name'],
'ip': get_guest_ip(proxmox, node_name, vmid, 'lxc'),
'vcpu': lxc_summary['cpus'],
'ram_gb': round(lxc_summary['maxmem'] / (1024**3), 2),
'disk_gb': round(lxc_summary.get('maxdisk', 0) / (1024**3), 2),
'note': lxc_config.get('description', '').replace('\n', ' ')
}
all_guests_info.append(lxc_info)
return sorted(all_guests_info, key=lambda x: x['id'])
def save_to_yaml(data, filename='proxmox_inventory.yml'):
with open(filename, 'w', encoding='utf-8') as f:
yaml.dump(data, f, allow_unicode=True, default_flow_style=False, sort_keys=False)
print(f"✅ Data successfully saved to {filename}")
def save_to_excel(data, filename='proxmox_inventory.xlsx'):
if not data: return
wb = Workbook()
ws = wb.active
ws.title = "Proxmox Inventory"
headers = list(data[0].keys())
ws.append(headers)
for item in data:
ws.append(list(item.values()))
for col in ws.columns:
max_length = 0
column = col[0].column_letter
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(cell.value)
except: pass
adjusted_width = (max_length + 2)
ws.column_dimensions[column].width = adjusted_width
wb.save(filename)
print(f"✅ Data successfully saved to {filename}")
if __name__ == "__main__":
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir: os.chdir(script_dir)
print("Attempting to collect data from Proxmox using API Token...")
inventory_data = collect_proxmox_data()
if inventory_data:
print(f"Successfully collected data for {len(inventory_data)} guests.")
save_to_yaml(inventory_data)
save_to_excel(inventory_data)
else:
print("Could not collect any data. Please check API Token, host, and permissions.")