fix: adapt to napalm-device-types 4.7
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.
This commit is contained in:
1 parent
81b2df9d71
commit
350e3a6d6e
8 files changed
+141
-15
No files matched your search
+88
-8
@@ -4,7 +4,12 @@ import re
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from napalm_linux.linux import LinuxDriver, _arm_vendor_from_model, _split_status
|
||||
from napalm_linux.linux import (
|
||||
_YUM_SECURITY_COMMAND,
|
||||
LinuxDriver,
|
||||
_arm_vendor_from_model,
|
||||
_split_status,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -93,6 +98,9 @@ class _AnsweringChannel:
|
||||
def recv_stderr_ready(self):
|
||||
return False
|
||||
|
||||
def recv_stderr(self, size):
|
||||
return b""
|
||||
|
||||
def exit_status_ready(self):
|
||||
return not self._out
|
||||
|
||||
@@ -309,7 +317,7 @@ def test_get_available_updates_apt(driver):
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# get_users
|
||||
# get_os_users
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -326,9 +334,9 @@ GROUP_OUT = (
|
||||
)
|
||||
|
||||
|
||||
def test_get_users(driver):
|
||||
def test_get_os_users(driver):
|
||||
with patch.object(driver, "_send", side_effect=[PASSWD_OUT, GROUP_OUT]):
|
||||
users = driver.get_users()
|
||||
users = driver.get_os_users()
|
||||
|
||||
admin = next(u for u in users if u["username"] == "admin")
|
||||
assert admin["uid"] == 1000
|
||||
@@ -338,6 +346,14 @@ def test_get_users(driver):
|
||||
assert set(admin["groups"]) == {"sudo", "docker", "adm"}
|
||||
|
||||
|
||||
def test_get_users_is_left_to_napalm(driver):
|
||||
"""napalm-device-types 4.7 renamed OSDriver.get_users to get_os_users:
|
||||
NAPALM's own get_users has another shape, and this driver does not implement it."""
|
||||
assert LinuxDriver.get_users is not LinuxDriver.get_os_users
|
||||
with pytest.raises(NotImplementedError):
|
||||
driver.get_users()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ping parsing
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -1460,9 +1476,12 @@ class TestAvailableUpdates:
|
||||
driver._pkg_manager = "dnf"
|
||||
driver._device.send_command.side_effect = [
|
||||
"0", # id -u
|
||||
"openssl-libs.x86_64 1:3.1.4-2.fc40 updates\n"
|
||||
"vim-enhanced.x86_64 2:9.1.083-1.fc40 updates\n__NETORK_RC=100",
|
||||
"FEDORA-2024-1a2b3c4d5e Important/Sec. openssl-libs-1:3.1.4-2.fc40.x86_64\n__NETORK_RC=0",
|
||||
("openssl-libs.x86_64 1:3.1.4-2.fc40 updates\n"
|
||||
"vim-enhanced.x86_64 2:9.1.083-1.fc40 updates\n__NETORK_RC=100"),
|
||||
# DNF_SECURITY_COMMAND pipes through cat: the outer status is cat's, dnf's own
|
||||
# is in the __DNF_RC marker.
|
||||
("FEDORA-2024-1a2b3c4d5e Important/Sec. openssl-libs-1:3.1.4-2.fc40.x86_64\n"
|
||||
"__DNF_RC=0\n__NETORK_RC=0"),
|
||||
]
|
||||
|
||||
updates = {u["name"]: u for u in driver.get_available_updates()}
|
||||
@@ -1475,7 +1494,62 @@ class TestAvailableUpdates:
|
||||
driver._device.send_command.side_effect = [
|
||||
"0",
|
||||
"vim-enhanced.x86_64 2:9.1.083-1.fc40 updates\n__NETORK_RC=100",
|
||||
"Error: updateinfo metadata missing\n__NETORK_RC=1",
|
||||
"Error: updateinfo metadata missing\n__DNF_RC=1\n__NETORK_RC=0",
|
||||
]
|
||||
|
||||
assert driver.get_available_updates()[0]["security"] is None
|
||||
|
||||
def test_yum_security_command_reports_its_own_exit_status(self):
|
||||
# parse_dnf_security (napalm-device-types 4.7) needs the __DNF_RC marker, and
|
||||
# behind "| cat" the outer status no longer says whether yum failed.
|
||||
assert "echo __DNF_RC=$?" in _YUM_SECURITY_COMMAND
|
||||
assert "yum updateinfo list security" in _YUM_SECURITY_COMMAND
|
||||
|
||||
def test_yum_marks_what_a_security_advisory_covers(self, driver):
|
||||
driver._pkg_manager = "yum"
|
||||
driver._device.send_command.side_effect = [
|
||||
"0", # id -u
|
||||
("openssl-libs.x86_64 1:1.0.2k-26.el7_9 updates\n"
|
||||
"vim-enhanced.x86_64 2:7.4.629-8.el7_9 updates\n__NETORK_RC=100"),
|
||||
("RHSA-2023:3556 Important/Sec. openssl-libs-1:1.0.2k-26.el7_9.x86_64\n"
|
||||
"__DNF_RC=0\n__NETORK_RC=0"),
|
||||
]
|
||||
|
||||
updates = {u["name"]: u for u in driver.get_available_updates()}
|
||||
|
||||
assert driver._device.send_command.call_count == 3
|
||||
assert "echo __DNF_RC=$?" in driver._device.send_command.call_args_list[2][0][0]
|
||||
assert updates["openssl-libs"]["security"] is True
|
||||
assert updates["vim-enhanced"]["security"] is False
|
||||
|
||||
def test_yum_with_no_advisories_marks_nothing_as_security(self, driver):
|
||||
driver._pkg_manager = "yum"
|
||||
driver._device.send_command.side_effect = [
|
||||
"0",
|
||||
"vim-enhanced.x86_64 2:7.4.629-8.el7_9 updates\n__NETORK_RC=100",
|
||||
"__DNF_RC=0\n__NETORK_RC=0",
|
||||
]
|
||||
|
||||
assert driver.get_available_updates()[0]["security"] is False
|
||||
|
||||
def test_yum_that_failed_leaves_security_unknown(self, driver):
|
||||
# A failed yum prints nothing on stdout (2>/dev/null): read as "no advisories",
|
||||
# every update would be marked as not a security fix.
|
||||
driver._pkg_manager = "yum"
|
||||
driver._device.send_command.side_effect = [
|
||||
"0",
|
||||
"vim-enhanced.x86_64 2:7.4.629-8.el7_9 updates\n__NETORK_RC=100",
|
||||
"__DNF_RC=1\n__NETORK_RC=0",
|
||||
]
|
||||
|
||||
assert driver.get_available_updates()[0]["security"] is None
|
||||
|
||||
def test_yum_without_its_exit_status_leaves_security_unknown(self, driver):
|
||||
driver._pkg_manager = "yum"
|
||||
driver._device.send_command.side_effect = [
|
||||
"0",
|
||||
"vim-enhanced.x86_64 2:7.4.629-8.el7_9 updates\n__NETORK_RC=100",
|
||||
"RHSA-2023:3556 Important/Sec. vim-enhanced-2:7.4.629-8.el7_9.x86_64\n__NETORK_RC=0",
|
||||
]
|
||||
|
||||
assert driver.get_available_updates()[0]["security"] is None
|
||||
@@ -1725,9 +1799,15 @@ class TestGetVirtualIps:
|
||||
def recv_ready(self):
|
||||
return False
|
||||
|
||||
def recv(self, size):
|
||||
return b""
|
||||
|
||||
def recv_stderr_ready(self):
|
||||
return False
|
||||
|
||||
def recv_stderr(self, size):
|
||||
return b""
|
||||
|
||||
def exit_status_ready(self):
|
||||
return True
|
||||
|
||||
|
||||
Reference in new issue
Block a user