Files
napalm-bsd/README.md
T
christianmanivong e8468a292a
CI / test (3.10) (push) Successful in 26s
CI / test (3.11) (push) Successful in 24s
CI / test (3.12) (push) Successful in 26s
CI / test (3.10) (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 24s
CI / test (3.12) (pull_request) Successful in 25s
feat: packages, services and updates
The write side NetOrk/netork#799 needs, on both drivers.

- Packages: get_packages (FreeBSD `pkg query` with the repository as
  source, nothing on a classic system without pkg; OpenBSD `pkg_info`),
  install_package / uninstall_package as root (`pkg install`/`pkg
  delete`, `pkg_add -I`/`pkg_delete`), names checked before anything is
  sent, a failure raised with what the tool printed.
- Updates: get_available_updates. FreeBSD `pkg upgrade -n`, with
  `security` from VuXML (`pkg audit`: True for a listed package, False for
  any other, None when the audit could not run); OpenBSD `pkg_add -u -n
  -v` (no security verdict). Base-system patches are one `base-system`
  entry, as decided in #799: OpenBSD's `syspatch -c`, and on a classic
  FreeBSD what `freebsd-update` has fetched; on pkgbase the base system is
  packages from FreeBSD-base.
- Services: get_services lists the enabled ones (FreeBSD `service ...
  status` as root, as root-only pidfiles hide daemons otherwise, without
  root when sudo refuses; OpenBSD `rcctl check`), manage_service runs
  start/stop/restart/enable/disable as root and returns success and
  output.

Fixtures recorded on the FreeBSD 15.1 and OpenBSD 7.9 VMs with genuinely
outdated packages (FreeBSD pointed at the latest branch, an OpenBSD
package taken back to its release build). Checked live on both, including
a service restart and installing and removing a package.
2026-10-08 09:59:04 +02:00

78 lines
4.0 KiB
Markdown

# napalm-bsd
NAPALM drivers for **FreeBSD** (`freebsd`) and **OpenBSD** (`openbsd`) hosts,
over SSH, built on [napalm-device-types](https://git.netork.io/NAPALM/napalm-device-types)'
`OSDriver`. Written for netOrk, which provisions and manages BSD VMs
(NetOrk/netork#792).
## Design
- One shared `BsdDriver` (`napalm_bsd/base.py`) holds the SSH layer and every
reader whose tools agree between the BSDs. `FreeBSDDriver` and
`OpenBSDDriver` name only the commands that differ (hostname, release,
kernel, hardware, `netstat -rnW` vs `-rn`).
- Every command runs on its own SSH **exec channel** (`run_on_transport` from
napalm-device-types): no PTY to parse a prompt from, stdout and stderr apart,
a real exit status. `run_command()` / `open_stream()` are public
(`CommandChannelMixin`).
- Root comes from `sudo -S` with the sudo password on stdin (never on a command
line), or `sudo -n` without one, as in napalm-linux. netOrk provisions `sudo`
on BSD VMs for that reason; `doas` cannot read a password from stdin.
- Parsing is in `napalm_bsd/parse.py`, pure functions tested on output recorded
from real systems (`tests/fixtures/`, each directory's `COMMANDS.txt` lists
what produced it).
## Supported getters
| Getter | FreeBSD | OpenBSD | Source |
|---|---|---|---|
| `get_facts` | ✓ | ✓ | `kern.hostname`/`hostname`, `freebsd-version`/`uname`, `kenv smbios.*`/`hw.*`, `kern.boottime` |
| `get_interfaces`, `get_interfaces_ip` | ✓ | ✓ | `ifconfig -a` |
| `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_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` |
| `get_services`, `manage_service` | ✓ | ✓ | `service -e` + `service … status` / `service … <action>`; `rcctl ls on` + `rcctl check` / `rcctl <action>` |
`get_listening_sockets` has the shape of napalm-device-types'
`ListeningSocketsMixin` (whose `ss`/cgroup reading is Linux's) and its rule:
read as root first, without root when that brings nothing back
(`attributed: False`). FreeBSD's `sockstat` sees every socket either way;
OpenBSD's `fstat` shows a user only their own processes, so without root the
sockets come from `netstat -an`, unnamed.
There is deliberately no `get_kernel_facts`: `KernelFactsMixin` reports a
Linux kernel's modules and `CONFIG_*` options, which a BSD kernel does not
have, and `hasattr(driver, "get_kernel_facts")` has to stay truthful.
**Updates.** `security` on FreeBSD comes from VuXML (`pkg audit`): True for a
package it lists as vulnerable, False for one it does not, None when the audit
could not run. OpenBSD's tools do not say, so it is None there. Base-system
patches are one entry, `base-system` (NetOrk/netork#799): OpenBSD's
`syspatch` applies its patches together and in order; a classic FreeBSD base
reports what `freebsd-update` has fetched (`updatesready`). On FreeBSD with
pkgbase the base system is packages from the `FreeBSD-base` repository and
needs no extra entry.
**Services** are the enabled ones. FreeBSD reads their status as root, as
root-only pidfiles hide a daemon from anyone else, and without root when sudo
refuses; OpenBSD's `rcctl check` needs no root. Actions run as root.
SNMP (#800) follows.
## Connection arguments
`optional_args`: `port` (22), `key_file`, `sudo_password`, `allow_agent`,
`look_for_keys` (both off by default).
## Development
```bash
pip install "napalm-device-types @ git+https://git.netork.io/NAPALM/napalm-device-types.git"
pip install -e ".[dev]"
pytest
```