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:
co-authored by
Claude Sonnet 4.6
parent
90d6592159
commit
5732a4494e
@@ -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.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user