--- name: wg_status kind: function lang: bash domain: infra version: "1.0.0" purity: impure signature: "wg_status([interface_name]) -> json" description: "Parsea `wg show dump` a JSON estructurado con peers, handshake age, status (online/stale/never), bytes rx/tx. Resuelve device_id desde comentarios en wg0.conf. Para dashboards (agents_dashboard Mesh panel)." tags: [wireguard, status, observability, json, infra] params: - name: interface_name desc: "Nombre de la interface WireGuard (default wg0)" output: "JSON con interface info + array de peers. Cada peer incluye public_key, device_id (de comentario # DeviceID: en wg0.conf), endpoint, allowed_ips, latest_handshake_unix, latest_handshake_ago_s, rx_bytes, tx_bytes, persistent_keepalive, status (online/stale/never)." uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] tested: true tests: - "interface con 2 peers online y stale" - "interface sin peers devuelve array vacio" - "interface inexistente devuelve error JSON" - "WG_FAKE_DUMP carga dump de archivo" test_file_path: "bash/functions/infra/wg_status_test.sh" file_path: "bash/functions/infra/wg_status.sh" --- ## Ejemplo ```bash # Estado real de wg0 source bash/functions/infra/wg_status.sh wg_status | jq . # Interface distinta wg_status wg1 | jq .peers[].status # Sin sudo real (testing / CI) WG_FAKE_DUMP=bash/functions/infra/wg_status_test_dump.tsv wg_status wg0 | jq . ``` Salida representativa: ```json { "interface": "wg0", "public_key": "abcXYZ123...", "listen_port": "51820", "peers": [ { "public_key": "peerKey1...", "device_id": "pc-aurgi", "endpoint": "1.2.3.4:54321", "allowed_ips": ["10.42.0.10/32"], "latest_handshake_unix": 1716000000, "latest_handshake_ago_s": 42, "rx_bytes": 12345, "tx_bytes": 67890, "persistent_keepalive": 25, "status": "online" } ] } ``` ## Cuando usarla Cuando necesites saber el estado del mesh WireGuard desde un script, dashboard o agente. Usa antes de mostrar el panel Mesh en `agents_dashboard`. Llama cada N segundos para polling ligero desde shell sin depender de la API de WireGuard. ## Gotchas - Requiere `CAP_NET_ADMIN` / root: `wg show` falla sin permisos. En produccion ejecutar via `sudo -n wg show wg0 dump` o dar permiso al binario. Para tests sin sudo: `WG_FAKE_DUMP=` carga el dump desde archivo. - `listen_port` se devuelve como string (tal como lo emite `wg show dump`). El campo es `"0"` si wg no esta activo pero la interface existe. - `device_id` queda `""` si no hay comentario `# DeviceID:` antes del `[Peer]` correspondiente en `/etc/wireguard/.conf`. - Status `stale` cubre desde 180s hasta cualquier valor mayor. No hay distincion entre "hace 5 min" y "hace 3 dias" — ambos son `stale`. Para un threshold mas fino, usar `latest_handshake_ago_s` directamente. - Si `/etc/wireguard/.conf` no existe o no es legible, `device_id` sera `""` para todos los peers (la funcion no falla, solo omite el lookup).