#!/usr/bin/env python3 """ Verify that clinic_credentials.json and grafana_storage_state.json are valid and that the Clinic API credentials actually work. Default paths (same directory as this script): clinic_credentials.json → ./clinic_credentials.json grafana_storage_state.json → ./grafana_storage_state.json Usage: uv run python verify.py uv run python verify.py --clinic /path/to/clinic_credentials.json uv run python verify.py --grafana /path/to/grafana_storage_state.json """ import argparse import json import sys import urllib.error import urllib.request from pathlib import Path HERE = Path(__file__).parent DEFAULT_CLINIC = (HERE / "clinic_credentials.json").resolve() DEFAULT_GRAFANA = (HERE / "grafana_storage_state.json").resolve() CLINIC_API_URL = ( "https://clinic.pingcap.com/clinic/api/v1/dashboard/clusters2" "?limit=1&page=1&show_deleted=false" ) OK = "\033[32m✓\033[0m" FAIL = "\033[31m✗\033[0m" def check(label: str, passed: bool, detail: str = "") -> bool: icon = OK if passed else FAIL suffix = f" ({detail})" if detail else "" print(f" {icon} {label}{suffix}") return passed def load_json(path: Path, label: str): if not path.exists(): check(f"{label} exists", False, str(path)) return None check(f"{label} file exists", True, str(path)) try: with open(path) as f: data = json.load(f) check(f"{label} is valid JSON", True) return data except json.JSONDecodeError as e: check(f"{label} is valid JSON", False, str(e)) return None def verify_clinic(path: Path) -> bool: print("\n[clinic_credentials.json]") data = load_json(path, "file") if data is None: return False clinic = data.get("clinic", {}) cookie = clinic.get("CLINIC_COOKIE", "") csrf = clinic.get("CLINIC_CSRF_TOKEN", "") preview_cookie = (cookie[:60] + "...") if len(cookie) > 60 else cookie preview_csrf = (csrf[:30] + "...") if len(csrf) > 30 else csrf ok_cookie = check("has CLINIC_COOKIE", bool(cookie), preview_cookie) ok_csrf = check("has CLINIC_CSRF_TOKEN", bool(csrf), preview_csrf) if not ok_cookie or not ok_csrf: return False # Live HTTP verification against the Clinic API print(f" → Testing Clinic API credentials...") req = urllib.request.Request( CLINIC_API_URL, headers={ "Cookie": cookie, "X-CSRF-Token": csrf, }, ) try: with urllib.request.urlopen(req, timeout=15) as resp: body = json.loads(resp.read()) total = body.get("total", "?") check( f"Clinic API authentication (HTTP {resp.status})", resp.status == 200, f"total clusters visible: {total}", ) return resp.status == 200 except urllib.error.HTTPError as e: check( "Clinic API authentication", False, f"HTTP {e.code} — credentials may be invalid or expired", ) return False except Exception as e: check("Clinic API reachable", False, str(e)) return False def verify_grafana(path: Path, clinic_cookie: str = "", clinic_csrf: str = "") -> bool: print("\n[grafana_storage_state.json]") data = load_json(path, "file") if data is None: return False cookies = data.get("cookies", []) origins = data.get("origins", []) check( "has 'cookies' list", isinstance(cookies, list) and len(cookies) > 0, f"{len(cookies)} cookie(s)", ) check( "has 'origins' list", isinstance(origins, list) and len(origins) > 0, f"{len(origins)} origin(s)", ) session_cookies = [c for c in cookies if c.get("name") == "clinic.session_id"] check("clinic.session_id cookie present", bool(session_cookies)) ls_entries = sum(len(o.get("localStorage", [])) for o in origins) check( "localStorage entries present", ls_entries > 0, f"{ls_entries} entry(ies)", ) if not session_cookies: return False # Extract CSRF token from localStorage (stored as clinic.auth.csrf_token). csrf_from_storage = "" for origin in origins: for entry in origin.get("localStorage", []): if entry.get("name") == "clinic.auth.csrf_token": csrf_from_storage = entry.get("value", "").strip('"') break check( "has clinic.auth.csrf_token in localStorage", bool(csrf_from_storage), csrf_from_storage[:20] + "..." if len(csrf_from_storage) > 20 else csrf_from_storage, ) # Live check: verify that the clinic.session_id stored in the Playwright state # is still valid by calling the Clinic API. The Grafana instance at # clinic.pingcap.com uses the same clinic.session_id for auth; if the session # is valid here, Playwright will be able to open Grafana dashboards with this # storage state. (The Grafana /api/user endpoint is not accessible over plain # HTTP with cookie auth from outside the browser context.) session_value = session_cookies[0]["value"] csrf = ( csrf_from_storage or clinic_csrf ) # prefer storage-state CSRF; fall back to fresh print(" → Testing clinic.session_id from storage state against Clinic API...") req = urllib.request.Request( CLINIC_API_URL, headers={ "Cookie": f"clinic.session_id={session_value}", "X-CSRF-Token": csrf, }, ) try: with urllib.request.urlopen(req, timeout=15) as resp: body = json.loads(resp.read()) total = body.get("total", "?") ok = resp.status == 200 check( f"storage-state session valid (Clinic API HTTP {resp.status})", ok, f"total clusters visible: {total}", ) except urllib.error.HTTPError as e: check( "storage-state session valid", False, f"HTTP {e.code} — clinic.session_id in storage state may be expired", ) return False except Exception as e: check("Clinic API reachable", False, str(e)) return False # Also verify the Grafana dashboard URL is reachable and renders a dashboard # (not a login redirect). The page returns 200 with HTML when authenticated; # when unauthenticated the response body contains a redirect to /grafana/login. GRAFANA_DASHBOARD = ( "https://clinic.pingcap.com/grafana/d/fJNOYXc7k/coredns?orgId=1&refresh=10s" ) all_site_cookies = "; ".join( f"{c['name']}={c['value']}" for c in cookies if c.get("domain") == "clinic.pingcap.com" ) print(f" → Testing Grafana dashboard accessibility...") req2 = urllib.request.Request( GRAFANA_DASHBOARD, headers={ "Cookie": all_site_cookies, "X-CSRF-Token": csrf, # Mimic a browser request so the server returns the SPA shell. "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "User-Agent": "Mozilla/5.0 (verify.py)", }, ) try: with urllib.request.urlopen(req2, timeout=15) as resp: body_html = resp.read().decode("utf-8", errors="replace") final_url = resp.url # Authenticated: final URL still contains /grafana/d/ # Unauthenticated: redirected to /grafana/login is_login = ( "/grafana/login" in final_url or "/grafana/login" in body_html[:2000] ) ok2 = resp.status == 200 and not is_login detail = ( f"final URL: {final_url}" if not ok2 else f"HTTP {resp.status}, dashboard rendered" ) check("Grafana dashboard accessible (not redirected to login)", ok2, detail) return ok2 except urllib.error.HTTPError as e: check( "Grafana dashboard accessible", False, f"HTTP {e.code}", ) return False except Exception as e: check("Grafana dashboard reachable", False, str(e)) return False def main(): parser = argparse.ArgumentParser( description="Verify Clinic/Grafana credentials downloaded by get_credentials.js" ) parser.add_argument( "--clinic", default=str(DEFAULT_CLINIC), metavar="PATH", help=f"path to clinic_credentials.json (default: {DEFAULT_CLINIC})", ) parser.add_argument( "--grafana", default=str(DEFAULT_GRAFANA), metavar="PATH", help=f"path to grafana_storage_state.json (default: {DEFAULT_GRAFANA})", ) args = parser.parse_args() clinic_path = Path(args.clinic).expanduser().resolve() grafana_path = Path(args.grafana).expanduser().resolve() # Extract the fresh clinic.session_id cookie to inject into the Grafana live test. # grafana_storage_state.json is a Playwright browser dump whose clinic.session_id # may be older/expired; clinic_credentials.json is always freshly obtained. clinic_cookie_for_grafana = "" clinic_csrf_for_grafana = "" try: with open(clinic_path) as f: clinic_section = json.load(f).get("clinic", {}) clinic_cookie_for_grafana = clinic_section.get("CLINIC_COOKIE", "") clinic_csrf_for_grafana = clinic_section.get("CLINIC_CSRF_TOKEN", "") except Exception: pass clinic_ok = verify_clinic(clinic_path) grafana_ok = verify_grafana( grafana_path, clinic_cookie_for_grafana, clinic_csrf_for_grafana ) print() if clinic_ok and grafana_ok: print(f" {OK} All checks passed — credentials are ready to use") sys.exit(0) else: print(f" {FAIL} Some checks failed — see above for details") sys.exit(1) if __name__ == "__main__": main()