FreeBSDDriver (`freebsd`) and OpenBSDDriver (`openbsd`) on a shared BsdDriver, for the BSD VMs netOrk provisions and BSD hosts added by hand (NetOrk/netork#798). - SSH over exec channels (napalm-device-types' run_on_transport): no PTY, stdout and stderr apart, real exit codes; run_command()/open_stream() are public. Root through `sudo -S` with the password on stdin, or `sudo -n` without one. - Facts: hostname, release and running kernel (freebsd-version / uname), hardware from SMBIOS (kenv) or hw.* sysctls, uptime from kern.boottime. - Interfaces and addresses (ifconfig -a: ether/lladdr, hex netmasks, scoped IPv6), routes (netstat -rn, OpenBSD's abbreviated networks written out, host/broadcast/loopback entries left out), ARP (FreeBSD's sentences, OpenBSD's table), users and groups, processes (lstart read as one five-word field), cron jobs (system crontab and the login user's). - Parsers are pure functions, tested on output recorded from FreeBSD 15.1 (hand-installed and cloud image) and OpenBSD 7.9 (NetOrk/netork#793), with internal addresses replaced by documentation ranges.
39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
"""FreeBSD: kenv for the hardware, freebsd-version for base and kernel."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from napalm_device_types import FingerprintRule
|
|
|
|
from napalm_bsd.base import BsdDriver
|
|
|
|
|
|
class FreeBSDDriver(BsdDriver):
|
|
"""NAPALM driver for FreeBSD hosts, over SSH."""
|
|
|
|
TYPE_LABEL = "FreeBSD"
|
|
VENDOR = "FreeBSD"
|
|
DRIVER_NAME = "freebsd"
|
|
SNMP_FINGERPRINT = [FingerprintRule("freebsd", weight=5.0)]
|
|
# OpenSSH in FreeBSD's base names it in its banner ("OpenSSH_9.9 FreeBSD-20250219").
|
|
SSH_FINGERPRINT = [FingerprintRule("freebsd", weight=3.0)]
|
|
|
|
HOSTNAME_COMMAND = "sysctl -n kern.hostname"
|
|
# Userland and running kernel; both carry the patch level (15.1-RELEASE-p4).
|
|
OS_VERSION_COMMAND = "freebsd-version -u"
|
|
KERNEL_COMMAND = "freebsd-version -r"
|
|
# kenv takes one variable per call, and a missing one fails the call.
|
|
PLATFORM_COMMAND = (
|
|
"for k in maker product serial; do "
|
|
'printf "%s=%s\\n" "$k" "$(kenv -q smbios.system.$k)"; done'
|
|
)
|
|
# -W: FreeBSD cuts long destinations to the column width otherwise.
|
|
ROUTES_COMMAND = "netstat -rnW"
|
|
|
|
def _os_version(self) -> str:
|
|
version = super()._os_version()
|
|
return f"FreeBSD {version}" if version else ""
|
|
|
|
def _hardware(self) -> tuple[str, str, str]:
|
|
smbios = self._platform()
|
|
return smbios.get("maker", ""), smbios.get("product", ""), smbios.get("serial", "")
|