From 1921a3f044876de54e97dca77ac7cae52326b309 Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Tue, 13 Oct 2026 06:20:00 +0000 Subject: [PATCH] fix: rename get_users to get_os_users for napalm-device-types 4.7 napalm-device-types 4.7 renamed OSDriver.get_users to get_os_users: NAPALM's own get_users has another shape and a stub on every driver, so hasattr could not tell the two apart. BsdDriver now implements get_os_users with the same return shape and leaves NAPALM's get_users alone. Require napalm-device-types>=4.7.1 and bump the version to 0.2.0. --- CHANGELOG.md | 10 ++++++++++ README.md | 2 +- napalm_bsd/base.py | 2 +- pyproject.toml | 4 ++-- tests/test_drivers.py | 13 ++++++++++--- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a864994..1d70753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.0] - 2026-10-13 + +### Changed +- `get_users` is now `get_os_users`, as napalm-device-types 4.7 names it on + `OSDriver`; the return shape is unchanged. NAPALM's own `get_users` has + another shape and a stub on every driver, so a poll asking `hasattr` could + not tell the two apart. Requires napalm-device-types 4.7.1 or later. + +## [0.1.0] + ### Added - `FreeBSDDriver` (`freebsd`) and `OpenBSDDriver` (`openbsd`) on a shared `BsdDriver`: SSH over exec channels (no PTY, real exit codes), root through diff --git a/README.md b/README.md index 42ff87f..ab5ee87 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ over SSH, built on [napalm-device-types](https://git.netork.io/NAPALM/napalm-dev | `get_route_to` | ✓ | ✓ | `netstat -rnW` / `netstat -rn` | | `get_arp_table` | ✓ | ✓ | `arp -an` | | `get_lldp_neighbors` | `{}` | `{}` | no LLDP daemon in either base system | -| `get_users`, `get_processes`, `get_cron_jobs` | ✓ | ✓ | `/etc/passwd`+`/etc/group`, `ps … lstart`, system crontab + `crontab -l` | +| `get_os_users`, `get_processes`, `get_cron_jobs` | ✓ | ✓ | `/etc/passwd`+`/etc/group`, `ps … lstart`, system crontab + `crontab -l` | | `get_listening_sockets` | ✓ | ✓ | `sockstat -46lq` / `fstat -n` as root, `netstat -an` without | | `get_packages`, `install_package`, `uninstall_package` | ✓ | ✓ | `pkg query` / `pkg install`, `pkg delete`; `pkg_info` / `pkg_add -I`, `pkg_delete` | | `get_available_updates` | ✓ | ✓ | `pkg upgrade -n` + `pkg audit` (VuXML); `pkg_add -u -n -v` + `syspatch -c` | diff --git a/napalm_bsd/base.py b/napalm_bsd/base.py index 810d7b0..65a5acc 100644 --- a/napalm_bsd/base.py +++ b/napalm_bsd/base.py @@ -460,7 +460,7 @@ class BsdDriver(HostStatusMixin, OSDriver): # -- accounts, processes, cron ----------------------------------------------- - def get_users(self) -> list[dict[str, Any]]: + def get_os_users(self) -> list[dict[str, Any]]: return parse.users(self._out("cat /etc/passwd"), self._out("cat /etc/group")) def get_processes(self) -> list[dict[str, Any]]: diff --git a/pyproject.toml b/pyproject.toml index 8111622..7a9a632 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "napalm-bsd" -version = "0.1.0" +version = "0.2.0" description = "NAPALM drivers for FreeBSD and OpenBSD hosts via SSH" readme = "README.md" requires-python = ">=3.10" @@ -26,7 +26,7 @@ classifiers = [ ] dependencies = [ "napalm>=4.0", - "napalm-device-types>=2.6.0", # channel.run_on_transport + "napalm-device-types>=4.7.1", # channel.run_on_transport; OSDriver.get_os_users "paramiko>=5.0.0", # CVE-2026-44405 ] diff --git a/tests/test_drivers.py b/tests/test_drivers.py index 91e0359..0cf7eb3 100644 --- a/tests/test_drivers.py +++ b/tests/test_drivers.py @@ -96,7 +96,7 @@ class TestIdentity: "get_route_to", "get_arp_table", "get_lldp_neighbors", - "get_users", + "get_os_users", "get_processes", "get_cron_jobs", ], @@ -104,6 +104,13 @@ class TestIdentity: def test_implements_what_the_poll_reads(self, cls, getter): """netOrk asks whether a getter is overridden, not merely present.""" assert getattr(cls, getter) is not getattr(NetworkDriver, getter, None) + assert getattr(cls, getter) is not getattr(OSDriver, getter, None) + + @pytest.mark.parametrize("cls", [FreeBSDDriver, OpenBSDDriver]) + def test_leaves_napalms_get_users_alone(self, cls): + """NAPALM's get_users is a different getter; the host's accounts are get_os_users.""" + assert "get_users" not in vars(BsdDriver) + assert "get_users" not in vars(cls) class TestFacts: @@ -177,8 +184,8 @@ class TestRoutesAndNeighbours: class TestAccountsAndProcesses: - def test_users(self): - users = _freebsd_host().get_users() + def test_os_users(self): + users = _freebsd_host().get_os_users() assert next(u for u in users if u["username"] == "root")["groups"] == ["wheel", "operator"] def test_processes(self):