feat: report what listens, and which procd service it is
Mixes in napalm-device-types' ListeningSocketsMixin (2.5.0): without ss the shared command reads busybox netstat, and each process's cgroup names its procd service. The driver only carries the command across. Over an SSH exec channel of its own, not the interactive shell: busybox ash cuts a typed line at 512 characters, the command is longer, and the cut line left the shell waiting for a closing quote. OpenWrt logs in as root; a login other than root cannot become root, so its reading says it is not attributed. Checked against a real OpenWrt 25.12.2 access point. For netOrk#673.
This commit is contained in:
@@ -27,6 +27,7 @@ from netmiko import ConnectHandler
|
||||
from netmiko.exceptions import NetmikoTimeoutException, NetmikoAuthenticationException
|
||||
|
||||
from napalm_device_types import AccessPointDriver, FingerprintRule
|
||||
from napalm_device_types.listening import ListeningSocketsMixin
|
||||
from napalm.base.exceptions import (
|
||||
ConnectionException,
|
||||
ConnectionClosedException,
|
||||
@@ -52,6 +53,7 @@ class OpenWrtDriver(
|
||||
OpenWrtSystemMixin,
|
||||
OpenWrtPackageMixin,
|
||||
OpenWrtRoutingMixin,
|
||||
ListeningSocketsMixin,
|
||||
AccessPointDriver,
|
||||
):
|
||||
"""NAPALM driver for OpenWrt routers and access-points."""
|
||||
@@ -161,6 +163,22 @@ class OpenWrtDriver(
|
||||
except (socket.error, EOFError) as exc:
|
||||
raise ConnectionClosedException(str(exc)) from exc
|
||||
|
||||
def _run_listening_sockets_command(self, command: str, *, privileged: bool) -> str:
|
||||
"""Run the listening-socket command for ``ListeningSocketsMixin``.
|
||||
|
||||
Over an SSH exec channel of its own, not the interactive shell: busybox
|
||||
ash cuts a typed line at 512 characters, and the command is longer. As
|
||||
root it names every socket's process; a login other than root has no way
|
||||
to become root here, so a privileged reading comes back empty and the
|
||||
mixin reads again without attributing.
|
||||
"""
|
||||
if privileged and self.username != "root":
|
||||
return ""
|
||||
_stdin, stdout, _stderr = self.device.remote_conn_pre.exec_command(
|
||||
command, timeout=self.timeout
|
||||
)
|
||||
return stdout.read().decode("utf-8", "replace")
|
||||
|
||||
@staticmethod
|
||||
def _parse_openwrt_release(output: str) -> dict[str, str]:
|
||||
"""Parse ``/etc/openwrt_release`` key=value pairs."""
|
||||
|
||||
Reference in New Issue
Block a user