Skip to content

API - Get VMs

import requests
import urllib3
import re

# Suppress warnings for unverified HTTPS requests
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

BASE_URL = "https://10.10.2.12:8006/api2/json"
USERNAME = "root@pam"
PASSWORD = "GetTheLatestPasswordFromBitwarden"
IGNORE = ['finwell']
GRATIS = 200

def login_to_proxmox(base_url, username, password):
    """Login to Proxmox API and return the ticket and CSRF token."""
    response = requests.post(
        f"{base_url}/access/ticket",
        data={"username": username, "password": password},
        verify=False
    )
    response.raise_for_status()
    data = response.json()["data"]
    return data["ticket"], data["CSRFPreventionToken"]

def extract_disk_size(disk_string):
    """
    Extracts the integer size of a disk in GB.
    Handles sizes in G (GB) and M (MB).
    """
    match = re.search(r'size=([0-9]+)([A-Z]?)', disk_string)
    if match:
        size, unit = int(match.group(1)), match.group(2)
        if unit == "M":
            return size // 1024  # Convert MB to GB
        return size  # GB assumed
    return None  # Size not found

def get_vm_config(node, vmid, headers):
    """Retrieve the configuration for a specific VM."""
    response = requests.get(
        f"{BASE_URL}/nodes/{node}/qemu/{vmid}/config",
        headers=headers,
        verify=False
    )
    response.raise_for_status()
    return response.json()["data"]

def get_bundled_capacity(cores,memory):
    if cores == 2 and memory == 4:
        return 50
    elif cores == 2 and memory == 8:
        return 50
    elif cores == 4 and memory == 8:
        return 100
    elif cores == 4 and memory == 16:
        return 150
    elif cores == 8 and memory == 32:
        return 200
    elif cores == 8 and memory == 64:
        return 500
    elif cores == 16 and memory == 128:
        return 1000
    elif cores == 24 and memory == 64:
        return 1000
    elif cores == 32 and memory == 256:
        return 2000
    # NON-STANDARD BOLLOCKS!!!
    elif cores == 12 and memory == 32:
        return 200
    elif cores == 8 and memory == 16:
        return 200
    elif cores == 1 and memory == 1:
        return 50
    else:
        print ("------------> NOT A T-SHIRT SIZE !!!")

def process_vm(vm, headers):
    """Process and display VM details including disk sizes."""
    vmid = vm["vmid"]
    node = vm["node"]
    vm_config = get_vm_config(node, vmid, headers)


    cores = vm_config['cores'] * vm_config['sockets']
    memory = int(int(vm_config['memory']) / 1024)

    # Iterate over disks (scsi0, scsi1, scsi2, etc.)
    for ignore_name in IGNORE:
        if ignore_name in vm_config['name']:
            print (f" [x] Skipping {ignore_name}")
            return 0
    drv_string = ""
    billed_capacity = 0
    for key, value in vm_config.items():
        if key.startswith("scsi"):
            total_size = extract_disk_size(value)
            if total_size is not None:
                if key == 'scsi0':
                    default_size = get_bundled_capacity(cores=cores,memory=memory)
                    if default_size != total_size:
                        print(" [x] Non-standard disk size detected")
                    drv_string += (f" DRV{key[-1]}: {total_size - default_size} GB" )
                else:
                    drv_string +=  (f" DRV{key[-1]}: {total_size} GB")
                    billed_capacity += total_size
    if drv_string != "":
        print(f"VM: {vm_config['name']} [{vmid}]")
        print(f" CPU: {cores} MEM: {memory} GB")
        print(f" {drv_string}")
    return billed_capacity

def main():
    """Main execution function."""
    ticket, csrf_token = login_to_proxmox(BASE_URL, USERNAME, PASSWORD)
    headers = {
        "Cookie": f"PVEAuthCookie={ticket}",
        "CSRFPreventionToken": csrf_token
    }
    global total_capacity
    total_capacity = 0
    # Get VMs in the resource pool
    pool_id = "Teleforge"
    response = requests.get(
        f"{BASE_URL}/pools/{pool_id}",
        headers=headers,
        verify=False
    )
    response.raise_for_status()
    pool_vms = response.json()["data"]["members"]
    for vm in pool_vms:
        if vm["type"] == "qemu":
            total_capacity += process_vm(vm, headers)
    print("--------------------------\n")
    print(f"Total Capacity: {total_capacity} GB")

if __name__ == "__main__":
    main()