#!/usr/bin/env python3 """VPN login session smoke: start -> state polling -> optional action -> stop.""" import json import os import sys import time from urllib import request API_BASE = os.environ.get("API_URL", "http://127.0.0.1:8080") TIMEOUT = int(os.environ.get("VPN_FLOW_TIMEOUT_SEC", "20")) def call(method, path, data=None, timeout=10): url = f"{API_BASE}{path}" payload = json.dumps(data).encode("utf-8") if data is not None else None req = request.Request(url, data=payload, method=method) if payload is not None: req.add_header("Content-Type", "application/json") try: with request.urlopen(req, timeout=timeout) as resp: body = resp.read() except Exception as err: print(f"[vpn] request {path} failed: {err}", file=sys.stderr) sys.exit(1) try: return json.loads(body) except json.JSONDecodeError: print(f"[vpn] non-json response for {path}: {body[:200]!r}", file=sys.stderr) sys.exit(1) def main(): print(f"[vpn] API_BASE={API_BASE}") start = call("POST", "/api/v1/vpn/login/session/start") if "ok" not in start or "phase" not in start or "level" not in start: print(f"[vpn] invalid start payload: {start}", file=sys.stderr) sys.exit(1) print(f"[vpn] start phase={start.get('phase')} ok={start.get('ok')}") cursor = 0 saw_state = False tried_action = False deadline = time.time() + TIMEOUT while time.time() < deadline: state = call("GET", f"/api/v1/vpn/login/session/state?since={cursor}") saw_state = True if "cursor" in state: cursor = int(state["cursor"]) phase = state.get("phase") alive = bool(state.get("alive")) can_check = bool(state.get("can_check")) print(f"[vpn] state phase={phase} alive={alive} cursor={cursor}") if can_check and alive and not tried_action: action = call("POST", "/api/v1/vpn/login/session/action", {"action": "check"}) if not action.get("ok", False): print(f"[vpn] action check failed: {action}", file=sys.stderr) sys.exit(1) tried_action = True print("[vpn] action=check sent") if phase in ("success", "already_logged", "failed", "cancelled"): break time.sleep(1) if not saw_state: print("[vpn] no state response received", file=sys.stderr) sys.exit(1) stop = call("POST", "/api/v1/vpn/login/session/stop") if not stop.get("ok", False): print(f"[vpn] stop failed: {stop}", file=sys.stderr) sys.exit(1) print("[vpn] flow smoke passed") if __name__ == "__main__": main()