- Login.vue: no prefilled default creds; no anonymous entity enumeration on mount - deploy.sh: readiness polling (0.5s/30s cap) replaces fixed sleep 3; login smoke reads same-source 600 secret file, missing file = explicit abort - 19 verify/check/gen_report scripts: shared _admin_creds() loader (CMA_ADMIN_ENV -> ops .secrets -> profile copy); no hardcoded creds - tests: single TEST_USER_PASSWORD fixture constant; docs: pointer to 600 secret file; removed 4 legacy .bak + pycache residue
108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
#!/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])
|