From fc24495b83c5f55ad27497c6a77a5221156c7a8e Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Fri, 23 Oct 2026 08:34:55 +0200 Subject: [PATCH] fix: what bandit and the remaining lint rules found - The six except Exception: pass (REST logout, the extra-ports lookup, the per-port detail in get_interfaces, closing CLI and REST sessions) now log at debug level (B110), so a swallowed failure leaves a trace. - nosec for comparing a reported address with 0.0.0.0 (B104) and for the empty password field of get_users (B105, now a named constant); both are false positives. - A long error message is split into adjacent f-strings; the unused ARP entry type is named _entry_type. - tests: the failed-open test expects ConnectionException instead of any Exception; raise ... from exc. --- napalm_procurve/api_client.py | 7 ++++--- napalm_procurve/parsers.py | 10 +++++++--- napalm_procurve/procurve.py | 11 ++++++----- tests/unit/test_driver.py | 2 +- tests/unit/test_ssh_host_key.py | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/napalm_procurve/api_client.py b/napalm_procurve/api_client.py index 988badf..6a840b7 100644 --- a/napalm_procurve/api_client.py +++ b/napalm_procurve/api_client.py @@ -149,7 +149,7 @@ class ProcurveApiClient: try: self._session.delete(self._base_url + "login-sessions", timeout=self.timeout) except Exception: - pass + logger.debug("REST API logout: ignored", exc_info=True) if self._session: self._session.close() self._session = None @@ -283,7 +283,7 @@ class ProcurveApiClient: ) seen_ids.add(pid) except Exception: - pass + logger.debug("system/status/switch for missing ports: ignored", exc_info=True) for port in port_elements: pid = port.get("id", "") @@ -330,7 +330,8 @@ class ProcurveApiClient: for entry in ipv4_data.get("ipv4_element", []): addr = entry.get("address", "") mask = entry.get("mask", "") - if not addr or addr == "0.0.0.0": + # An unset address reported by the switch, not a bind address. + if not addr or addr == "0.0.0.0": # nosec B104 continue try: import netaddr diff --git a/napalm_procurve/parsers.py b/napalm_procurve/parsers.py index 119f9fc..0ac1a3a 100644 --- a/napalm_procurve/parsers.py +++ b/napalm_procurve/parsers.py @@ -9,6 +9,9 @@ backends. import re +#: get_users' password field: the switch never shows a password, so it stays empty. +_PASSWORD_NOT_SHOWN = "" # nosec B105 + # --------------------------------------------------------------------------- # MAC address helpers # --------------------------------------------------------------------------- @@ -330,7 +333,8 @@ def parse_ip_interfaces(output: str) -> dict[str, dict]: # Single VLAN output (no header): detect from "IP Address" line if re.search(r"IP\s+Address\s*:", line, re.I): ip = line.split(":", 1)[-1].strip() - if ip and ip not in ("0.0.0.0", ""): + # An unset address reported by the switch, not a bind address. + if ip and ip != "0.0.0.0": # nosec B104 current_ip = ip if not current_vlan: current_vlan = "VLAN1" @@ -375,7 +379,7 @@ def parse_arp_table(output: str) -> list[dict]: m = _ARP_RE.search(line) if not m: continue - ip, mac, entry_type, port = (m.group(1), m.group(2), m.group(3), m.group(4) or "") + ip, mac, _entry_type, port = (m.group(1), m.group(2), m.group(3), m.group(4) or "") table.append( { "interface": port, @@ -665,7 +669,7 @@ def parse_users(output: str) -> dict[str, dict]: priv = 1 users[uname] = { "level": priv, - "password": "", + "password": _PASSWORD_NOT_SHOWN, "sshkeys": [], } return users diff --git a/napalm_procurve/procurve.py b/napalm_procurve/procurve.py index 9ed2442..fdb9404 100644 --- a/napalm_procurve/procurve.py +++ b/napalm_procurve/procurve.py @@ -238,7 +238,7 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver): try: self._device.disconnect() except Exception: - pass + logger.debug("closing the CLI session: ignored", exc_info=True) self._device = None self._transport = None @@ -556,7 +556,7 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver): if detail.get("description"): ifaces[port]["description"] = detail["description"] except Exception: - pass + logger.debug("show interfaces %s: ignored", port, exc_info=True) # The CLI lists member ports only ("3-Trk3"); the trunk gets its own row. return add_lag_interfaces(ifaces) @@ -643,7 +643,7 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver): try: self._api._session.close() except Exception: - pass + logger.debug("closing the REST session: ignored", exc_info=True) running = self._get_config_via_ssh() return {"running": running, "startup": "", "candidate": ""} @@ -971,7 +971,8 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver): resp = self._api.put(f"ports/{interface}", json=patch) if not resp.ok: raise ConnectionException( - f"set_interface({interface}): ports PUT HTTP {resp.status_code} – {resp.text[:200]}" + f"set_interface({interface}): ports PUT HTTP {resp.status_code} – " + f"{resp.text[:200]}" ) mode = config.get("mode") if mode == "trunk": @@ -1286,7 +1287,7 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver): try: self._device.disconnect() except Exception: # noqa: BLE001 - closing a temporary session - pass + logger.debug("closing the temporary CLI session: ignored", exc_info=True) self._api, self._device, self._transport = old_api, old_device, old_transport def _snmp_configure_cli(self, settings: dict[str, Any]) -> dict[str, Any]: diff --git a/tests/unit/test_driver.py b/tests/unit/test_driver.py index f8f4818..95b0146 100644 --- a/tests/unit/test_driver.py +++ b/tests/unit/test_driver.py @@ -535,7 +535,7 @@ class TestDriverTransportDetection: with patch("napalm_procurve.procurve.ProcurveApiClient.probe", return_value=(None, None)): with patch("napalm_procurve.procurve.ConnectHandler", side_effect=Exception("no conn")): drv = ProcurveDriver("192.168.0.1", "manager", "secret") - with pytest.raises(Exception): + with pytest.raises(ConnectionException): drv.open() def test_auth_failure_names_why_earlier_transports_failed(self): diff --git a/tests/unit/test_ssh_host_key.py b/tests/unit/test_ssh_host_key.py index 1b6e1eb..9585b18 100644 --- a/tests/unit/test_ssh_host_key.py +++ b/tests/unit/test_ssh_host_key.py @@ -43,7 +43,7 @@ def _refuse(**kwargs): try: raise paramiko.BadHostKeyException("10.0.0.4", SERVER_KEY, OTHER_KEY) except paramiko.SSHException as exc: - raise NetmikoTimeoutException(f"A paramiko SSHException occurred: {exc}") + raise NetmikoTimeoutException(f"A paramiko SSHException occurred: {exc}") from exc def _driver(seen: list, known: dict | None = None, **extra) -> ProcurveDriver: