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 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-06-10 08:34:18 +02:00
co-authored by Claude Sonnet 4.6
parent 90d6592159
commit 5732a4494e
+44
View File
@@ -1763,11 +1763,24 @@ class ProxmoxDriver(HypervisorDriver):
"""Return warnings for the Proxmox node. """Return warnings for the Proxmox node.
Currently detects: Currently detects:
- lldpd not installed (LLDP neighbor discovery unavailable)
- Available package updates (via Proxmox APT API) - Available package updates (via Proxmox APT API)
- Missing / invalid subscription - Missing / invalid subscription
""" """
warnings: list[_JsonDict] = [] 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 # 1. Available package updates
try: try:
updates = self._api.nodes(self._node_name).apt.update.get() 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.""" """Execute a named administrative action on the Proxmox node."""
if action == "fix_snmp": if action == "fix_snmp":
return self._action_fix_snmp() return self._action_fix_snmp()
if action == "install_lldpd":
return self._action_install_lldpd()
raise NotImplementedError(f"Unknown action: {action!r}") 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: def _action_fix_snmp(self) -> dict:
"""Install, configure and start snmpd on the Proxmox node. """Install, configure and start snmpd on the Proxmox node.