"""WireGuard peers as VPN tunnels. Pure: no I/O. ``/api/wireguard/service/show`` lists every WireGuard interface and peer:: {"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"}, ... ]} **The key is the peer, not its place.** It used to be a running counter, so a peer added ahead of another renumbered it, and whatever a consumer keeps per key (netOrk's site link, its tunnel check) moved to a different peer (#32). Now it is the interface and the start of the public key, as napalm-linux does it, with the base64 made URL-safe because the key is used as a path segment. Two peers sharing the prefix get the whole key; a row without a public key keeps its position. """ from __future__ import annotations from typing import Any #: How much of a public key names a peer, the same length as napalm-linux uses. _KEY_PREFIX = 8 def _key(row: dict[str, Any], position: int, taken: dict[str, Any]) -> str: 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[:_KEY_PREFIX]}" if key in taken: key = f"wireguard-{row.get('if') or 'wg'}-{safe}" return key def _remote_ip(row: dict[str, Any]) -> str: endpoint = (row.get("endpoint") or "").strip() if not endpoint or endpoint == "(none)": return "" return endpoint.rsplit(":", 1)[0].strip("[]") def _tunnel(row: dict[str, Any], position: int) -> dict[str, Any]: handshake_age = row.get("latest-handshake-age") return { "type": "WireGuard", "local_endpoint": "", "remote_endpoint": _remote_ip(row), "is_up": row.get("peer-status") == "online", "uptime": int(handshake_age) if handshake_age else 0, "bytes_in": int(row.get("transfer-rx") or 0), "bytes_out": int(row.get("transfer-tx") or 0), "description": ( (row.get("name") or "").strip() or (row.get("ifname") or "").strip() or f"wg-peer-{position}" ), } def wireguard_tunnels(show: Any) -> dict[str, dict[str, Any]]: """One ``VPNTunnelDict`` per peer in ``/api/wireguard/service/show``, by tunnel key.""" rows = show.get("rows", []) if isinstance(show, dict) else [] tunnels: dict[str, dict[str, Any]] = {} peers = [row for row in rows if isinstance(row, dict) and row.get("type") == "peer"] for position, row in enumerate(peers, start=1): tunnels[_key(row, position, tunnels)] = _tunnel(row, position) return tunnels