fix: what bandit and the remaining lint rules found

- Long shell command lines are split into adjacent string literals.
- get_os_users: a first loop over /etc/group filled a map nobody read;
  it is gone, the output is unchanged.
- The five except Exception: pass now log at debug level (B110), so a
  swallowed failure leaves a trace.
- nosec for the staging path on the device (B108) and the sudo hint
  message (B105); both are false positives.
- tests: raise ... from exc, unused loop variable.
This commit is contained in:
Christian Manivong committed 2026-10-22 19:10:26 +02:00
1 parent 38391891ec
commit 933f81bd44
3 files changed
+23 -30

No files matched your search

+21 -28
View File
@@ -171,15 +171,16 @@ _NO_STDIN = "exec </dev/null; "
#: Where ``_install_file_as_root`` stages content: a fresh file from ``mktemp``
#: under ``umask 077``, never a fixed name another user could create first.
_STAGE_TEMPLATE = "/tmp/netork-stage.XXXXXX"
#: The path is on the device, not a local temp file.
_STAGE_TEMPLATE = "/tmp/netork-stage.XXXXXX" # nosec B108
_STAGE_PREFIX = _STAGE_TEMPLATE[: -len("XXXXXX")]
_STAGE = (
f"umask 077 && t=$(mktemp {_STAGE_TEMPLATE}) && "
'{ cat > "$t" && printf %s "$t" || { s=$?; rm -f -- "$t"; exit $s; }; }'
)
#: What to do when sudo wants a password netOrk does not have.
_SUDO_PASSWORD_HINT = (
#: What to do when sudo wants a password netOrk does not have (a message, not a password).
_SUDO_PASSWORD_HINT = ( # nosec B105
"sudo requires a password on this host and no sudo password was given: pass one, "
"or allow this user passwordless sudo (NOPASSWD)."
)
@@ -274,7 +275,10 @@ def _arm_vendor_from_model(model: str) -> str:
#: Where net-snmp reads its configuration, and how each package manager installs it.
_SNMPD_CONF = "/etc/snmp/snmpd.conf"
_SNMP_INSTALL = {
"apt": "apt-get update -y >/dev/null 2>&1; DEBIAN_FRONTEND=noninteractive apt-get install -y snmpd snmp 2>&1",
"apt": (
"apt-get update -y >/dev/null 2>&1; "
"DEBIAN_FRONTEND=noninteractive apt-get install -y snmpd snmp 2>&1"
),
"dnf": "dnf install -y net-snmp net-snmp-utils 2>&1",
"yum": "yum install -y net-snmp net-snmp-utils 2>&1",
"apk": "apk add --no-cache net-snmp net-snmp-tools 2>&1",
@@ -425,7 +429,7 @@ class LinuxDriver(
"stty cols 10000 2>/dev/null || true", expect_string=r"[#$>]\s*$"
)
except Exception:
pass
logger.debug("%s: ignored", self.hostname, exc_info=True)
self._pkg_manager = self._forced_pkg_manager or self._detect_pkg_manager()
logger.debug("Connected to %s, pkg_manager=%s", self.hostname, self._pkg_manager)
@@ -436,7 +440,7 @@ class LinuxDriver(
try:
self._device.disconnect()
except Exception:
pass
logger.debug("%s: ignored", self.hostname, exc_info=True)
self._device = None
self._pkg_manager = None
@@ -668,8 +672,10 @@ class LinuxDriver(
"u=$(cat /sys/class/dmi/id/product_uuid 2>/dev/null); "
"d=$(systemd-detect-virt 2>/dev/null); d=${d:-none}; "
"dt=$(tr -d '\\0' </sys/firmware/devicetree/base/model 2>/dev/null); "
"cs=$(grep '^Serial' /proc/cpuinfo 2>/dev/null | head -1 | cut -d: -f2 | xargs 2>/dev/null); "
"cm=$(grep '^Model' /proc/cpuinfo 2>/dev/null | head -1 | cut -d: -f2 | xargs 2>/dev/null); "
"cs=$(grep '^Serial' /proc/cpuinfo 2>/dev/null | head -1 | cut -d: -f2 "
"| xargs 2>/dev/null); "
"cm=$(grep '^Model' /proc/cpuinfo 2>/dev/null | head -1 | cut -d: -f2 "
"| xargs 2>/dev/null); "
# DMIBEGIN sentinel: _send() strips leading blank lines (ARM has no DMI
# files, so fields 0-4 are empty). The sentinel anchors the output so
# splitlines()[start+N] always maps to the correct field index.
@@ -1075,7 +1081,7 @@ class LinuxDriver(
_make_entry(mapped_proto, nexthop, iface, metric, prefix)
)
except Exception:
pass
logger.debug("%s: ignored", self.hostname, exc_info=True)
return routes
@@ -1324,7 +1330,8 @@ class LinuxDriver(
def _get_packages_rpm(self) -> list[PackageDict]:
out = self._send(
"rpm -qa --queryformat '%{NAME}\\t%{VERSION}-%{RELEASE}\\t%{SIZE}\\t%{SUMMARY}\\n' 2>/dev/null"
"rpm -qa --queryformat "
"'%{NAME}\\t%{VERSION}-%{RELEASE}\\t%{SIZE}\\t%{SUMMARY}\\n' 2>/dev/null"
)
packages: list[PackageDict] = []
for line in out.splitlines():
@@ -1863,19 +1870,7 @@ class LinuxDriver(
passwd_out = self._send("getent passwd 2>/dev/null || cat /etc/passwd")
groups_out = self._send("getent group 2>/dev/null || cat /etc/group")
# Build uid→[group] map from /etc/group
uid_to_groups: dict[int, list[str]] = {}
for line in groups_out.splitlines():
parts = line.split(":")
if len(parts) < 4:
continue
gname = parts[0]
members = [m.strip() for m in parts[3].split(",") if m.strip()]
for member in members:
# We'll convert username→uid below; collect by username first
uid_to_groups.setdefault(-1, []) # placeholder
# Simpler: collect username→groups, then join with passwd
# username → supplementary groups, joined with passwd below
username_to_groups: dict[str, list[str]] = {}
for line in groups_out.splitlines():
parts = line.split(":")
@@ -1994,9 +1989,7 @@ class LinuxDriver(
return jobs
@staticmethod
def _parse_cron_line(
line: str, source_user: str, has_user_field: bool
) -> CronJobDict | None:
def _parse_cron_line(line: str, source_user: str, has_user_field: bool) -> CronJobDict | None:
"""Parse a single crontab line; returns ``None`` for comments/blanks."""
stripped = line.strip()
# Remove trailing comment
@@ -2064,7 +2057,7 @@ class LinuxDriver(
community = parts[3]
break
except Exception:
pass
logger.debug("%s: ignored", self.hostname, exc_info=True)
# Detect port override
try:
@@ -2076,7 +2069,7 @@ class LinuxDriver(
if m:
port = int(m.group(1))
except Exception:
pass
logger.debug("%s: ignored", self.hostname, exc_info=True)
return SNMPConfigDict(running=True, community=community, port=port, version="2c")
except Exception as exc:
+1 -1
View File
@@ -188,7 +188,7 @@ def test_every_annotation_resolves():
import inspect
import typing
for name, member in inspect.getmembers(LinuxDriver, inspect.isfunction):
for _name, member in inspect.getmembers(LinuxDriver, inspect.isfunction):
if member.__module__ == "napalm_linux.linux":
typing.get_type_hints(member)
+1 -1
View File
@@ -78,7 +78,7 @@ def test_a_changed_key_is_refused():
try:
raise paramiko.BadHostKeyException("10.0.0.8", SERVER_KEY, OTHER_KEY)
except paramiko.SSHException as exc: # what netmiko does with it
raise NetmikoTimeoutException(f"A paramiko SSHException occurred: {exc}")
raise NetmikoTimeoutException(f"A paramiko SSHException occurred: {exc}") from exc
driver = _driver(seen, SshHostKey.of(OTHER_KEY))
with patch("napalm_linux.linux.ConnectHandler", side_effect=refuse):