From 5732a4494eb046ed3abb4ca54c4894473e14fa6c Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Wed, 10 Jun 2026 08:34:18 +0200 Subject: [PATCH] feat: detect missing lldpd and add install_lldpd action get_device_warnings() now reports lldpd_not_installed (action install_lldpd) when lldpd is absent, matching the existing OpenWrt pattern. run_device_action("install_lldpd") installs and enables lldpd via apt/systemd so LLDP topology links to directly connected switches can be discovered. Co-Authored-By: Claude Sonnet 4.6 --- napalm_proxmox/driver.py | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/napalm_proxmox/driver.py b/napalm_proxmox/driver.py index 09d9c7c..8cc8bbe 100644 --- a/napalm_proxmox/driver.py +++ b/napalm_proxmox/driver.py @@ -1763,11 +1763,24 @@ class ProxmoxDriver(HypervisorDriver): """Return warnings for the Proxmox node. Currently detects: + - lldpd not installed (LLDP neighbor discovery unavailable) - Available package updates (via Proxmox APT API) - Missing / invalid subscription """ warnings: list[_JsonDict] = [] + # 0. LLDP daemon + try: + lldpd_path = self._exec_ssh_command("command -v lldpd 2>/dev/null").strip() + if not lldpd_path: + warnings.append({ + "code": "lldpd_not_installed", + "severity": "warning", + "action": "install_lldpd", + }) + except Exception: + pass + # 1. Available package updates try: updates = self._api.nodes(self._node_name).apt.update.get() @@ -2217,8 +2230,39 @@ class ProxmoxDriver(HypervisorDriver): """Execute a named administrative action on the Proxmox node.""" if action == "fix_snmp": return self._action_fix_snmp() + if action == "install_lldpd": + return self._action_install_lldpd() raise NotImplementedError(f"Unknown action: {action!r}") + def _action_install_lldpd(self) -> dict: + """Install, enable and start lldpd on the Proxmox node. + + Proxmox runs Debian/Linux underneath, so this is a plain apt install + followed by enabling the systemd service. lldpd's defaults (listen on + all interfaces) are sufficient to discover the directly-connected + switch via the management bridge (e.g. vmbr0). + """ + lines: list[str] = [] + + install_out = self._exec_ssh_command( + "DEBIAN_FRONTEND=noninteractive apt-get install -y lldpd 2>&1 | tail -5" + ) + lines.append(f"[install] {install_out.strip()[-200:]}") + + enable_out = self._exec_ssh_command( + "systemctl enable --now lldpd 2>&1 || service lldpd start 2>&1 || true" + ) + lines.append(f"[service] {enable_out.strip()[-200:]}") + + verify = self._exec_ssh_command("command -v lldpd 2>/dev/null").strip() + success = bool(verify) + if success: + lines.append("[ok] lldpd installed. Neighbors will appear after a short warm-up period.") + else: + lines.append("[warn] lldpd does not appear to be installed after the attempt.") + + return {"success": success, "output": "\n".join(lines)} + def _action_fix_snmp(self) -> dict: """Install, configure and start snmpd on the Proxmox node.