#!/usr/bin/env python3 """查看原始API返回的key和样本数据""" import json, urllib.request import os # noqa: E402 (凭据加载器需要) # ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)---- # 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。 # 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。 def _admin_creds(): """返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)""" for p in (os.environ.get("CMA_ADMIN_ENV"), "/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env", "/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"): if p and os.path.isfile(p): kv = {} for line in open(p, encoding="utf-8"): line = line.strip() if "=" in line and not line.startswith("#"): k, v = line.split("=", 1) kv[k.strip()] = v.strip().strip('"').strip("'") if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"): return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 " ".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)") ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds() print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)") BASE = "http://127.0.0.1:8010" def login(): data = json.dumps({"username":ADMIN_USER,"password":ADMIN_PASS}).encode() req = urllib.request.Request(BASE + "/api/cma/auth/login", data=data, headers={"Content-Type":"application/json"}, method="POST") resp = json.loads(urllib.request.urlopen(req).read()) return resp["token"] def api(path, token): auth = "Bearer " + token req = urllib.request.Request(BASE + path, headers={"Authorization": auth}) resp = json.loads(urllib.request.urlopen(req).read()) return resp token = login() # 看KPI完整结构 - 第一个元素 print("="*60) print("KPI - 第一个元素完整keys") print("="*60) data = api("/api/cma/kpis", token) items = data.get("data", data) if items and isinstance(items, list): first = items[0] for k, v in first.items(): print(" %-25s: %s" % (k, str(v)[:80])) # 看用户结构 print() print("="*60) print("Users - 原始结构") print("="*60) data = api("/api/cma/users", token) print(" type: %s" % type(data)) print(" keys: %s" % list(data.keys()) if isinstance(data, dict) else "list") if isinstance(data, dict): for k, v in list(data.items())[:3]: if isinstance(v, dict): print(" [%s] keys: %s" % (k, list(v.keys()))) for k2, v2 in v.items(): print(" %-20s: %s" % (k2, str(v2)[:60])) else: print(" [%s] = %s" % (k, str(v)[:80])) # 预警规则 print() print("="*60) print("预警规则 - 第一个元素") print("="*60) data = api("/api/cma/alert-rules", token) items = data.get("data", []) if isinstance(data, dict) else data if items and isinstance(items, list): first = items[0] print(" type: %s, keys: %s" % (type(first), list(first.keys()))) for k, v in first.items(): print(" %-25s: %s" % (k, str(v)[:80])) # 预警记录 print() print("="*60) print("预警记录 - 第一个元素") print("="*60) data = api("/api/cma/alerts", token) items = data.get("data", []) if isinstance(data, dict) else data if items and isinstance(items, list): first = items[0] print(" keys: %s" % list(first.keys())) for k, v in first.items(): print(" %-25s: %s" % (k, str(v)[:80])) # Dashboard summary完整 print() print("="*60) print("Dashboard Summary 完整结构") print("="*60) data = api("/api/cma/dashboard/summary", token) print(json.dumps(data, indent=2, ensure_ascii=False)[:1000])