from __future__ import annotations import argparse import json import sys import urllib.request from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parents[1] DEFAULT_BASE_URL = "http://docker-gpu.cin.su:8011" DEFAULT_REPORT = ROOT / "reports" / "1c-access" / "upo_test-access-snapshot-bsp.json" def rpc(base_url: str, method: str, payload: dict[str, Any], *, timeout: int) -> dict[str, Any]: body = json.dumps({"method": method, "payload": payload}, ensure_ascii=False).encode("utf-8") request = urllib.request.Request( base_url.rstrip("/") + "/rpc", data=body, headers={"Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(request, timeout=timeout) as response: data = json.loads(response.read().decode("utf-8")) if not isinstance(data, dict): return {"status": "error", "error": "response_not_object", "response": data} return data def main() -> int: parser = argparse.ArgumentParser(description="Smoke-check 1C access snapshot extraction.") parser.add_argument("--adapter-url", default=DEFAULT_BASE_URL) parser.add_argument("--base-id", default="upo_test") parser.add_argument("--preset", default="bsp", choices=["bsp"]) parser.add_argument("--no-preset", action="store_true", help="Do not send preset; verifies the adapter default extractor path.") parser.add_argument("--limit", type=int, default=5000) parser.add_argument("--max-effective-per-user", type=int, default=5000) parser.add_argument("--timeout", type=int, default=120) parser.add_argument("--report", type=Path, default=DEFAULT_REPORT) parser.add_argument("--json", action="store_true", help="Print full JSON response.") args = parser.parse_args() payload = { "base_id": args.base_id, "limit": args.limit, "timeout_seconds": args.timeout, "max_effective_permissions_per_user": args.max_effective_per_user, } if not args.no_preset: payload["preset"] = args.preset result = rpc(args.adapter_url, "access.snapshot.extract", payload, timeout=args.timeout + 10) args.report.parent.mkdir(parents=True, exist_ok=True) args.report.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8") if args.json: print(json.dumps(result, ensure_ascii=False, indent=2)) else: print( json.dumps( { "status": result.get("status"), "base_id": result.get("base_id"), "preset": result.get("preset"), "counts": result.get("counts"), "effective_permission_truncation": { "users": (result.get("counts") or {}).get("effective_users_permissions_truncated") if isinstance(result.get("counts"), dict) else None, "returned": (result.get("counts") or {}).get("effective_permissions_returned") if isinstance(result.get("counts"), dict) else None, "total": (result.get("counts") or {}).get("effective_permissions_total") if isinstance(result.get("counts"), dict) else None, }, "report": str(args.report), }, ensure_ascii=False, indent=2, ) ) if result.get("status") != "ok": return 1 counts = result.get("counts") if isinstance(result.get("counts"), dict) else {} return 0 if int(counts.get("effective_users") or 0) > 0 else 2 if __name__ == "__main__": raise SystemExit(main())