refactor: WireGuard tunnels are read in their own module (#32)
driver / lint (pull_request) Successful in 13s
driver / standard (pull_request) Successful in 14s
driver / test (3.10) (pull_request) Failing after 6s
driver / types (pull_request) Successful in 1m2s
driver / test (3.11) (pull_request) Successful in 1m5s
driver / test (3.12) (pull_request) Successful in 1m5s
driver / lowest (pull_request) Successful in 33s
driver / test (3.13) (pull_request) Successful in 59s
driver / build (pull_request) Successful in 27s
driver / security (pull_request) Successful in 1m1s
CI / driver (pull_request) Failing after 2m25s
driver / publish (pull_request) Skipped

get_vpn_tunnels() grew past the quality baseline with the key fix. The
WireGuard part is pure parsing of /api/wireguard/service/show, like the
listen ports in listening.py, so it moves to wireguard.py and the driver
calls it. opnsense.py shrinks from 3125 to 3082 lines.
This commit is contained in:
Christian Manivong committed 2026-10-27 10:03:30 +01:00
1 parent 9f45952605
commit eaafa540e5
3 files changed
+78 -70

No files matched your search

+2 -67
View File
@@ -69,6 +69,7 @@ from napalm_opnsense.ping_mixin import OPNsensePingMixin
from napalm_opnsense.port_forwards import alias_index, port_forwards, wan_interfaces
from napalm_opnsense.resolver_mixin import OPNsenseResolverMixin
from napalm_opnsense.virtual_ips import carp_addresses
from napalm_opnsense.wireguard import wireguard_tunnels
logger = logging.getLogger(__name__)
@@ -93,28 +94,6 @@ def _carp_master(entry: dict[str, Any]) -> bool:
return str(entry.get("status") or "").strip().upper() == "MASTER"
#: How much of a public key names a peer, the same length as napalm-linux uses.
_WG_KEY_PREFIX = 8
def _wireguard_key(row: dict[str, Any], position: int, taken: dict[str, Any]) -> str:
"""A WireGuard peer's tunnel key: its interface and the start of its public key.
Not its position: a peer added ahead of another would renumber it, and
whatever a consumer keeps per key would move to a different peer (#32). The
base64 is made URL-safe because the key is used as a path segment. Two peers
sharing a prefix get the whole key; one without a key keeps its position.
"""
public_key = (row.get("public-key") or "").strip()
if not public_key:
return f"wireguard-{position}"
safe = public_key.rstrip("=").replace("+", "-").replace("/", "_")
key = f"wireguard-{row.get('if') or 'wg'}-{safe[:_WG_KEY_PREFIX]}"
if key in taken:
key = f"wireguard-{row.get('if') or 'wg'}-{safe}"
return key
class OPNsenseDriver(
OPNsensePingMixin,
ConfigSyncMixin,
@@ -2189,51 +2168,7 @@ class OPNsenseDriver(
# ── WireGuard ──────────────────────────────────────────────────────
try:
# /api/wireguard/service/show returns structured JSON:
# {"total": N, "rows": [
# {"if":"wg0", "type":"interface", ...},
# {"if":"wg0", "type":"peer", "public-key":"...",
# "endpoint":"1.2.3.4:51820", "transfer-rx":N, "transfer-tx":N,
# "name":"office", "peer-status":"online",
# "latest-handshake-age":45, "ifname":"office"}, ...
# ]}
data = self._get("/api/wireguard/service/show")
rows = data.get("rows", []) if isinstance(data, dict) else []
wg_idx = 0
for row in rows:
if row.get("type") != "peer":
continue
wg_idx += 1
endpoint = (row.get("endpoint") or "").strip()
if endpoint and endpoint != "(none)":
remote_ip = endpoint.rsplit(":", 1)[0].strip("[]")
else:
remote_ip = ""
is_up = row.get("peer-status") == "online"
bytes_in = int(row.get("transfer-rx") or 0)
bytes_out = int(row.get("transfer-tx") or 0)
hs_age = row.get("latest-handshake-age")
uptime = int(hs_age) if hs_age else 0
description = (
(row.get("name") or "").strip()
or (row.get("ifname") or "").strip()
or f"wg-peer-{wg_idx}"
)
tunnels[_wireguard_key(row, wg_idx, tunnels)] = {
"type": "WireGuard",
"local_endpoint": "",
"remote_endpoint": remote_ip,
"is_up": is_up,
"uptime": uptime,
"bytes_in": bytes_in,
"bytes_out": bytes_out,
"description": description,
}
tunnels.update(wireguard_tunnels(self._get("/api/wireguard/service/show")))
except Exception as exc:
logger.debug("WireGuard status fetch failed (plugin not installed?): %s", exc)