08d02d285a0e5aa0e0f179e1b249c450c61a8870
_get_vm_disk_and_boot() now returns a list of disk dicts (name, size_mb)
instead of a single total. Each disk entry is read from the VM config
via /qemu/{vmid}/config or /lxc/{vmid}/config. The onboot flag is also
read from the same config endpoint.
Both QEMU VMs and LXC containers are covered. The 'disks' and 'onboot'
keys are added to every entry in the vms_snapshot.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
napalm-proxmox
A NAPALM driver for Proxmox VE nodes.
It supports all three networking domains of Proxmox VE:
| Domain | Description |
|---|---|
| Classic Linux | /etc/network/interfaces, Linux bridges, VLANs |
| SDN | Zones (VLAN, QinQ, VXLAN, EVPN), VNets, subnets |
| OVS | Open vSwitch bridges, bonds, and internal ports |
Requirements
- Python ≥ 3.9
- NAPALM ≥ 5.0.0
- proxmoxer ≥ 2.0.0
- netaddr ≥ 0.9.0
- requests ≥ 2.31.0
Installation
pip install napalm-proxmox
Or directly from source:
git clone https://github.com/example/napalm-proxmox.git
cd napalm-proxmox
pip install -e .
Usage
Password authentication
from napalm import get_network_driver
driver = get_network_driver("proxmox")
device = driver(
hostname="pve1.example.com",
username="root",
password="secret",
optional_args={
"realm": "pam", # default: "pam"
"port": 8006, # default: 8006
"verify_ssl": True, # default: True
},
)
with device:
facts = device.get_facts()
print(facts)
# {'vendor': 'Proxmox Server Solutions GmbH', 'model': 'PowerEdge R640',
# 'hostname': 'pve1', 'os_version': 'Proxmox VE 8.2.4', ...}
interfaces = device.get_interfaces()
interfaces_ip = device.get_interfaces_ip()
vlans = device.get_vlans()
network_instances = device.get_network_instances()
API token authentication
device = driver(
hostname="pve1.example.com",
username="napalm",
password="",
optional_args={
"token_name": "napalm@pam!napalm-token",
"token_value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
},
)
Targeting a specific node
In a multi-node cluster the driver auto-detects the node by matching the hostname against the cluster's node list. You can also pin a specific node:
device = driver(
hostname="pve-cluster.example.com", # cluster VIP
username="root",
password="secret",
optional_args={"node": "pve2"},
)
Supported NAPALM methods
| Method | Notes |
|---|---|
open / close |
Password + API token auth |
is_alive |
Checks /api2/json/version |
get_facts |
vendor, model, hostname, os_version, uptime, interface_list, fqdn |
get_interfaces |
eth, bridge, OVS bridge/bond; speed, MTU, MAC, status |
get_interfaces_ip |
IPv4/IPv6 from classic ifaces + SDN subnet gateways |
get_interfaces_counters |
From node/netstat RRD data |
get_environment |
CPU %, memory (bytes), hardware temperature sensors |
get_arp_table |
Reads /proc/net/arp via exec endpoint |
get_mac_address_table |
bridge fdb show (Linux) + ovs-appctl fdb/show (OVS) |
get_vlans |
SDN VNet tags + bridge vlan show |
get_network_instances |
SDN zones (VLAN→L2VPN, EVPN→L3VRF) + default instance |
get_ntp_servers |
From node/ntp API |
get_ntp_stats |
Parses chronyc / ntpq -pn output |
get_snmp_information |
Parses /etc/snmp/snmpd.conf |
get_users |
Proxmox access/users API + local /etc/passwd |
get_config |
/etc/network/interfaces + SDN config; sanitize support |
load_merge_candidate / load_replace_candidate |
String or file |
compare_config |
Unified diff |
commit_config |
Writes /etc/network/interfaces + ifreload -a |
discard_config / rollback |
Revert candidate |
get_lldp_neighbors |
lldpcli show neighbors via exec |
get_lldp_neighbors_detail |
Full LLDP detail |
get_ipv6_neighbors_table |
ip -6 neigh show |
ping |
Linux ping via exec endpoint |
traceroute |
traceroute -n via exec endpoint |
cli |
Arbitrary command execution via exec endpoint |
get_route_to |
ip route show via exec endpoint |
Not implemented (raise NotImplementedError):
get_bgp_config, get_bgp_neighbors, get_bgp_neighbors_detail,
get_optics, get_probes_config, get_probes_results, get_firewall_policies
Optional arguments
| Argument | Type | Default | Description |
|---|---|---|---|
port |
int | 8006 |
Proxmox API port |
verify_ssl |
bool | True |
Verify TLS certificate |
realm |
str | "pam" |
PAM realm for password auth |
node |
str | auto | Override target node name |
token_name |
str | None |
API token identifier (user@realm!tokenid) |
token_value |
str | None |
API token secret |
Development
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Run tests with coverage
pytest --cov=napalm_proxmox --cov-report=term-missing
# Lint
ruff check napalm_proxmox
Architecture
napalm_proxmox/
├── __init__.py # Exports ProxmoxDriver
├── driver.py # ProxmoxDriver — all NAPALM methods
└── utils.py # MAC normalisation, CIDR parsing, ARP/OVS parsers
tests/
├── conftest.py # Shared fixtures and mock API payloads
├── test_connection.py # open / close / is_alive
├── test_get_facts.py # get_facts
├── test_interfaces.py # get_interfaces, get_interfaces_ip, get_interfaces_counters
├── test_environment.py # get_environment
├── test_sdn.py # get_vlans, get_network_instances
├── test_ovs_and_arp.py # get_arp_table, get_mac_address_table, ARP/OVS utils
├── test_misc.py # NTP, SNMP, users, config, ping, traceroute, CLI, LLDP
└── test_utils.py # Unit tests for napalm_proxmox.utils
License
Apache License 2.0 — see LICENSE.
Languages
Python
100%