Commit Graph
20 Commits
Author SHA1 Message Date
Christian Manivong 4159612a33 fix: keep systemd's OSC 3008 shell context out of command output (#41)
driver / standard (pull_request) Failing after 17s
driver / lint (pull_request) Successful in 28s
driver / types (pull_request) Successful in 51s
driver / test (3.10) (pull_request) Successful in 1m3s
driver / test (3.11) (pull_request) Successful in 1m4s
driver / test (3.12) (pull_request) Successful in 1m58s
driver / test (3.13) (pull_request) Successful in 2m1s
driver / lowest (pull_request) Successful in 1m19s
driver / build (pull_request) Successful in 23s
driver / security (pull_request) Successful in 4m12s
CI / driver (pull_request) Failing after 8m24s
driver / publish (pull_request) Skipped
systemd 258 (Ubuntu 26.04) ships /etc/profile.d/80-systemd-osc-context.sh:
an interactive bash wraps every command in OSC 3008 sequences from PS0 and
PROMPT_COMMAND, each with a fresh UUID. They ended up in every value read
through netmiko's shell, and because the prompt never looked the same twice,
the prompt line stayed in the output too. os_version grew past 255
characters and netOrk could not store the poll.

The session now unsets PS0 and PROMPT_COMMAND right after switching the
history off and reads its prompt anew; _send() strips terminal codes from
what it returns.

Version 0.15.1.
2026-10-23 18:58:21 +02:00
Christian Manivong 9a4bc76dbf chore(release): 0.15.0
driver / standard (pull_request) Successful in 15s
driver / lint (pull_request) Successful in 12s
driver / types (pull_request) Successful in 54s
driver / test (3.10) (pull_request) Successful in 59s
driver / test (3.11) (pull_request) Successful in 58s
driver / lowest (pull_request) Successful in 29s
driver / test (3.12) (pull_request) Successful in 56s
driver / test (3.13) (pull_request) Successful in 52s
driver / build (pull_request) Successful in 26s
driver / security (pull_request) Successful in 58s
CI / driver (pull_request) Successful in 2m42s
driver / publish (pull_request) Skipped
2026-10-23 12:02:11 +02:00
Christian Manivong e0960085c7 Merge remote-tracking branch 'origin/master' into chore/driver-standard
driver / standard (pull_request) Successful in 14s
driver / lint (pull_request) Successful in 11s
driver / types (pull_request) Failing after 42s
driver / test (3.10) (pull_request) Failing after 38s
driver / test (3.11) (pull_request) Failing after 38s
driver / test (3.12) (pull_request) Failing after 33s
driver / test (3.13) (pull_request) Failing after 30s
driver / lowest (pull_request) Failing after 17s
driver / security (pull_request) Failing after 45s
driver / build (pull_request) Successful in 22s
CI / driver (pull_request) Failing after 4m51s
driver / publish (pull_request) Skipped
# Conflicts:
#	napalm_linux/linux.py
2026-10-23 08:29:05 +02:00
Christian Manivong 04f071afd0 feat: apt's proxy through AptProxyMixin (NetOrk/netork#1397)
CI / test (3.10) (push) Failing after 21s
CI / test (3.11) (push) Failing after 19s
CI / test (3.12) (push) Failing after 18s
CI / test (3.10) (pull_request) Failing after 19s
CI / test (3.11) (pull_request) Failing after 17s
CI / test (3.12) (pull_request) Failing after 16s
get_package_proxy() is what apt-config dump says, not 00proxy alone: a
proxy in 90curtin-aptproxy or /etc/apt/apt.conf wins over it and was
missed. The driver now supplies only the transports: reads on the exec
channel, root commands through _root_outcome, the file through the staged
_install_file_as_root. New: get_package_proxy_report() and
check_package_proxy(). configure_package_proxy() also comments out other
proxy lines, reads the result back and fetches through the proxy.

Requires napalm-device-types 4.22.0; version 0.14.0.
2026-10-22 19:16:40 +02:00
Christian Manivong 9b3ac3f3eb chore: adopt the NAPALM driver standard
driver / standard (pull_request) Successful in 56s
driver / lint (pull_request) Successful in 49s
driver / types (pull_request) Failing after 1m6s
driver / test (3.10) (pull_request) Failing after 5m48s
driver / test (3.11) (pull_request) Failing after 3m11s
driver / test (3.12) (pull_request) Successful in 2m48s
driver / test (3.13) (pull_request) Successful in 4m16s
driver / lowest (pull_request) Successful in 4m47s
driver / security (pull_request) Successful in 6m8s
driver / build (pull_request) Failing after 52s
CI / driver (pull_request) Failing after 30m42s
driver / publish (pull_request) Skipped
- CI moves to .gitea/workflows/ci.yml and calls the shared driver workflow
  of NAPALM/driver-standard; napalm-device-types comes from git until it is
  on PyPI.
- requires-python >=3.10 (napalm-device-types needs it), LICENSE file,
  py.typed, SPDX license string, links to git.netork.io.
- mypy strict for the package; napalm_linux.linux is exempt for now (21
  errors), recorded in the quality baseline with its long functions and
  the 2200-line module. Coverage floor 58 % (measured 58.23 %).
2026-10-22 19:11:50 +02:00
Christian Manivong 19b86d103d feat: get_host_firewall, the host's own netfilter rules (NetOrk/netork#1344)
CI / test (3.10) (push) Failing after 15s
CI / test (3.11) (push) Failing after 14s
CI / test (3.12) (push) Failing after 21s
CI / test (3.10) (pull_request) Failing after 15s
CI / test (3.11) (pull_request) Failing after 17s
CI / test (3.12) (pull_request) Failing after 16s
Mixes in napalm-device-types' HostFirewallMixin. The transport runs the shared
read-only command as root on an exec channel: nft prints the whole ruleset as
one line of JSON, longer than the PTY takes reliably, and both nft and
iptables-save need CAP_NET_ADMIN. Requires napalm-device-types 4.21.0;
version 0.13.0.
2026-10-21 23:10:48 +02:00
Christian Manivong a2bfa709f9 feat: get_service_packages, which packages a systemd service is (NetOrk/netork#1236)
CI / test (3.10) (pull_request) Successful in 41s
CI / test (3.11) (pull_request) Successful in 40s
CI / test (3.12) (pull_request) Successful in 32s
CI / test (3.10) (push) Successful in 29s
CI / test (3.11) (push) Successful in 27s
CI / test (3.12) (push) Successful in 34s
Mixes in napalm-device-types' ServicePackagesMixin. The transport runs the
shared read-only command on an exec channel under sh, without sudo: it is
about 1 kB, past what the PTY takes reliably, and written for sh whatever
the login shell. Requires napalm-device-types 4.20.0; version 0.12.0.
2026-10-19 17:40:06 +02:00
Christian Manivong 4b17e2f3f8 fix(ssh): verify the host key netOrk expects, report the one seen (NetOrk/netork#1167)
CI / test (3.10) (push) Successful in 30s
CI / test (3.11) (push) Successful in 31s
CI / test (3.12) (push) Successful in 36s
CI / test (3.10) (pull_request) Successful in 40s
CI / test (3.11) (pull_request) Successful in 31s
CI / test (3.12) (pull_request) Successful in 33s
The driver accepted any SSH host key. It now verifies through
napalm-device-types' HostKeyCheck (>= 4.19.0): with a known key in
optional_args["ssh_host_keys"] any other key is refused before login, and
every key seen is reported to optional_args["ssh_host_key_observer"].
Without either argument it connects as before (first use).
2026-10-18 21:23:39 +02:00
Christian Manivong decd64b876 feat!: report the package proxy as a fact; no warnings of its own (0.9.0)
CI / test (3.10) (push) Successful in 34s
CI / test (3.11) (push) Successful in 32s
CI / test (3.12) (push) Successful in 29s
CI / test (3.10) (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 23s
CI / test (3.12) (pull_request) Successful in 25s
get_device_warnings decided two things for the application: that any
pending update is a warning (it re-read the updates for that), and
whether apt's proxy is the one the application's setting wants, which
it was handed as optional_args["apt_proxy_url"].

The driver reports facts instead (napalm-device-types 4.14):
get_package_proxy() says which proxy apt fetches through, None for none
or on a non-apt host; the updates are get_available_updates() as
before. get_device_warnings and the apt_proxy_url argument go.

BREAKING CHANGE: get_device_warnings and optional_args["apt_proxy_url"]
are removed. Requires napalm-device-types 4.14.

Closes #28
2026-10-17 09:20:28 +02:00
Christian Manivong fc968fab44 chore: require napalm-device-types 4.13, where the fix templates landed
CI / test (3.10) (push) Successful in 28s
CI / test (3.11) (push) Successful in 28s
CI / test (3.12) (push) Successful in 33s
CI / test (3.10) (pull_request) Successful in 34s
CI / test (3.11) (pull_request) Successful in 30s
CI / test (3.12) (pull_request) Successful in 34s
2026-10-17 01:07:05 +02:00
Christian Manivong 1bc54b66e8 chore: release 0.8.0 (napalm-device-types 4.12)
CI / test (3.10) (push) Failing after 18s
CI / test (3.11) (push) Failing after 15s
CI / test (3.12) (push) Failing after 18s
CI / test (3.10) (pull_request) Failing after 16s
CI / test (3.11) (pull_request) Failing after 15s
CI / test (3.12) (pull_request) Failing after 19s
2026-10-16 12:08:55 +02:00
christianmanivong c98dd928e6 feat: get_system_identity for matching a host to its BMC (0.7.0)
CI / test (3.10) (push) Successful in 38s
CI / test (3.11) (push) Successful in 37s
CI / test (3.12) (push) Successful in 41s
Mixes in napalm-device-types 4.9's SystemIdentityMixin: the host's
SMBIOS system UUID, product serial and board serial, read as root on an
exec channel, vendor placeholders empty. netOrk links a server's BMC to
the host on these.
2026-10-13 12:20:12 +02:00
christianmanivong 350e3a6d6e fix: adapt to napalm-device-types 4.7
CI / test (3.10) (push) Successful in 38s
CI / test (3.11) (push) Successful in 37s
CI / test (3.12) (push) Successful in 39s
napalm-device-types 4.7 changed three things this driver depends on:

- parse_dnf_security needs the "__DNF_RC=<status>" line that
  DNF_SECURITY_COMMAND prints and raises ValueError without it or when dnf
  failed. The yum security query had no such line, so listing updates on
  any yum host raised. _YUM_SECURITY_COMMAND now prints the marker the same
  way ("{ ...; echo __DNF_RC=$?; } | cat"). _rpm_security_names checks
  __DNF_RC itself and turns a failed query, or output cut short before the
  marker, into None (security unknown) rather than "no advisories" or an
  exception.
- OSDriver.get_users was renamed to get_os_users, since NAPALM's own
  get_users has another shape. LinuxDriver.get_users is now get_os_users
  with the same return value.
- run_on_transport reads an exec channel to EOF after its exit status
  arrives; the tests' fake channels gain recv/recv_stderr for that.

Require napalm-device-types>=4.7.1 and bump the version to 0.6.0.
2026-10-13 06:25:17 +00:00
Christian Manivong 108f6fb3ca fix: stage root writes in a mktemp file, never at a fixed /tmp path
CI / test (3.10) (push) Successful in 46s
CI / test (3.11) (push) Successful in 39s
CI / test (3.12) (push) Successful in 53s
CI / test (3.10) (pull_request) Successful in 44s
CI / test (3.11) (pull_request) Successful in 47s
CI / test (3.12) (pull_request) Successful in 47s
Now that a whole _sudo line runs as root, `mv /tmp/netork_snmpd.conf
/etc/snmp/snmpd.conf && chown root:root … && chmod 644 …` would have let a
local user plant a symlink at the fixed /tmp path and have root's chown and
chmod follow it (e.g. to /etc/shadow). The same held for 00proxy.

_install_file_as_root stages the content unprivileged in a fresh mktemp file
(umask 077), checks the path it got back, and root installs it as a new
regular file next to the target and renames it over: nothing root runs
follows a symlink or changes the owner or mode of an existing path. Nothing
runs as root when staging failed.

get_vpn_tunnels always reads `wg show all dump` from the exec channel; the
predictable /tmp/.netork_wg_<hash> file holding the private keys is gone.
2026-10-12 22:56:06 +02:00
Christian Manivong cf8ee38a90 fix: run privileged commands on the exec channel, never typed into the shell
CI / test (3.10) (push) Successful in 56s
CI / test (3.11) (push) Successful in 50s
CI / test (3.12) (push) Successful in 44s
CI / test (3.10) (pull_request) Successful in 42s
CI / test (3.11) (pull_request) Successful in 44s
CI / test (3.12) (pull_request) Successful in 53s
_sudo typed `echo '<password>' | sudo -S -p "" <command>` into netmiko's
interactive shell. bash kept it in its history, so every poll wrote the sudo
password into the login user's ~/.bash_history, and while the command ran it
was in the process list for every local user (NetOrk/netork#1039).

_sudo, _sudo_status and _run_privileged with a password now run on an exec
channel like run_command(privileged=True): the password reaches sudo -S on
stdin, there is no PTY to echo it, and the script starts with
`exec </dev/null` so a non-prompting sudo leaves it unread. The whole
command runs as root in one sh -c - before, only the part up to the first
`;`, `&&` or `|` did. The exit status comes from the channel.

The interactive session switches its history off before its first command.
get_vpn_tunnels with a password reads `wg show all dump` from the exec
channel instead of a temp file that held the private keys.
2026-10-12 22:51:07 +02:00
Christian Manivong 647e058b8a fix: refuse stdin to a privileged command while a sudo password is set
CI / test (3.10) (push) Successful in 1m2s
CI / test (3.11) (push) Successful in 47s
CI / test (3.12) (push) Successful in 42s
CI / test (3.10) (pull_request) Successful in 43s
CI / test (3.11) (pull_request) Successful in 46s
CI / test (3.12) (pull_request) Successful in 51s
run_command(privileged=True, stdin=data) sent `sudo -S` with stdin =
<sudo password>\n + data. A sudo that does not prompt (NOPASSWD, a cached
timestamp) leaves the password line on stdin, and the command reads it as
the first line of the data - `cat > file` wrote it into the file
(NetOrk/netork#1029).

run_command now raises ValueError for that combination before opening a
channel. Stdin still reaches the command under `sudo -n` (no password set),
for a root login, and for unprivileged commands. Callers stage the data
without privilege and have root install the file. open_stream documents the
same caveat.
2026-10-12 20:41:06 +02:00
Christian Manivong a78daccb56 feat: report the virtual IPs vip-manager and keepalived declare
CI / test (3.10) (pull_request) Successful in 43s
CI / test (3.11) (pull_request) Successful in 53s
CI / test (3.12) (pull_request) Successful in 53s
CI / test (3.10) (push) Successful in 44s
CI / test (3.11) (push) Successful in 40s
CI / test (3.12) (push) Successful in 38s
LinuxDriver mixes in napalm-device-types' VirtualIpsMixin (4.2.0) and
carries its command on the exec channel: with the awk filter it is about
4 kB, past the line the PTY netmiko holds reliably takes. Root first,
then without it (NetOrk/netork#829).

Version 0.4.0.
2026-10-08 12:38:03 +02:00
Christian Manivong 3333d8e8f5 refactor!: drop the Docker CLI methods
CI / test (3.10) (push) Successful in 41s
CI / test (3.11) (push) Successful in 37s
CI / test (3.12) (push) Successful in 38s
CI / test (3.10) (pull_request) Successful in 37s
CI / test (3.11) (pull_request) Successful in 36s
CI / test (3.12) (pull_request) Successful in 38s
get_docker_info(), get_docker_outdated(), reconstruct_docker_run() and
the _docker_bin() hook go, with the image-ID helpers. netOrk reads and
handles containers over the Engine API through open_container_engine()
since NetOrk/netork#765 and no longer calls them (phase 9). The
fix_docker_permissions action stays: it is an OS action.

Version 0.3.0.
2026-10-08 08:29:52 +02:00
Christian Manivong 51ee33eebe feat: run commands and streams on an exec channel, reach the container engine
CI / test (3.10) (push) Failing after 16s
CI / test (3.11) (push) Failing after 16s
CI / test (3.12) (push) Successful in 39s
CI / test (3.10) (pull_request) Successful in 38s
CI / test (3.11) (pull_request) Successful in 36s
CI / test (3.12) (pull_request) Successful in 38s
netOrk drove this driver's shell through the private `_send` (an
interactive PTY, stdout and stderr merged, no exit code) and opened its
own paramiko connections for Docker. napalm-device-types 2.6.0 makes the
channel public; this implements it (NetOrk/netork#765):

- `run_command()` and `open_stream()` open an exec channel on the SSH
  transport netmiko already holds: no second login, no PTY, a real exit
  status.
- `privileged=True` follows the driver's existing rules: as root the
  command runs directly; with a sudo password it goes through
  `sudo -S -p ''` and the password is written to stdin, never onto the
  command line; without one `sudo -n` fails at once instead of hanging.
- `ContainerEngineMixin` is mixed in, so `open_container_engine("docker")`
  streams the Engine API over `docker system dial-stdio`.

The existing Docker methods are unchanged. Version 0.2.0, requires
napalm-device-types >= 2.6.0.

Refs NAPALM/napalm-device-types#17
2026-10-07 17:59:32 +02:00
Christian ManivongandClaude Sonnet 4.6 2712389818 feat: add get_route_to() via ip route show; family-Feld für IPv4/IPv6
Initial commit mit bestehendem Code inkl. neuem get_route_to():
- Parsed ip -4 route show und ip -6 route show
- Protokoll-Map: kernel/dhcp/ra/boot→connected, static→static, ospf→ospf, bgp→bgp
- family-Feld aus Netzadresse oder Next-Hop (: = ipv6)
- default/default6 → 0.0.0.0/0 / ::/0; Host-Routen ohne Prefix bekommen /32

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 15:50:02 +02:00