From 9631275d6bb4e9ca3f2b677d37871ce7b1054cb8 Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Mon, 22 Jun 2026 20:03:14 +0200 Subject: [PATCH] fix: get_facts() reads physical hardware info from DMI sysfs via SSH vendor, model and serial_number now come from /sys/class/dmi/id/ (sys_vendor, product_name, product_serial) via SSH, reflecting the actual physical server rather than the Proxmox software layer. Falls back to "Proxmox Server Solutions GmbH" / status.model if SSH or DMI files are unavailable (e.g. bare-metal without SSH creds). Co-Authored-By: Claude Sonnet 4.6 --- napalm_proxmox/driver.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/napalm_proxmox/driver.py b/napalm_proxmox/driver.py index 9bba641..64a058c 100644 --- a/napalm_proxmox/driver.py +++ b/napalm_proxmox/driver.py @@ -332,14 +332,18 @@ class ProxmoxDriver( # ------------------------------------------------------------------ # def get_facts(self) -> _JsonDict: - """Return basic facts about the Proxmox node.""" + """Return basic facts about the Proxmox node. + + Hardware vendor, model and serial are read from the Linux DMI sysfs + entries (``/sys/class/dmi/id/``) via SSH so they reflect the physical + machine, not the Proxmox software layer. + """ status = self._get_node_status() version = self._get_version_info() network = self._get_node_network() dns = self._get_node_dns() uptime = float(status.get("uptime", 0)) - model = status.get("model", "") dns_search = dns.get("search", "") hostname = self._node_name fqdn = f"{self._node_name}.{dns_search}" if dns_search else self.hostname @@ -352,14 +356,34 @@ class ProxmoxDriver( release = version.get("release", "") os_version = f"Proxmox VE {pve_version}" if pve_version else f"Proxmox VE {release}" + # Physical hardware info from Linux DMI sysfs + vendor = "" + model = "" + serial = "" + try: + dmi_cmd = ( + "printf '%s\\t%s\\t%s' " + "\"$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null)\" " + "\"$(cat /sys/class/dmi/id/product_name 2>/dev/null)\" " + "\"$(cat /sys/class/dmi/id/product_serial 2>/dev/null)\"" + ) + raw = self._exec_ssh_command(dmi_cmd).strip() + parts = raw.split("\t") + if len(parts) >= 3: + vendor = parts[0].strip() + model = parts[1].strip() + serial = parts[2].strip() + except Exception as exc: + logger.debug("Failed to read DMI info via SSH: %s", exc) + return { "uptime": uptime, - "vendor": "Proxmox Server Solutions GmbH", - "model": model or "Proxmox VE Node", + "vendor": vendor or "Proxmox Server Solutions GmbH", + "model": model or status.get("model") or "Proxmox VE Node", "hostname": self._node_name, "fqdn": fqdn or self.hostname, "os_version": os_version, - "serial_number": "", + "serial_number": serial, "interface_list": iface_list, }