# napalm-proxmox A [NAPALM](https://napalm.readthedocs.io/) driver for [Proxmox VE](https://www.proxmox.com/en/proxmox-virtual-environment/overview) 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 ```bash pip install napalm-proxmox ``` Or directly from source: ```bash git clone https://github.com/example/napalm-proxmox.git cd napalm-proxmox pip install -e . ``` ## Usage ### Password authentication ```python 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 ```python 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: ```python 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 ```bash 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](LICENSE).