81 lines
2.7 KiB
Python
Executable File
81 lines
2.7 KiB
Python
Executable File
#!/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()
|