feat(compute): 引擎用户对账同步(用户=平台总用户)

- compute_client.ensure_user(幂等建号, 存在不抛)
- 新增 POST /admin/compute/sync-users: 遍历平台全部用户→建引擎账号(幂等)+缺令牌签PAT, 保证 engine用户=平台用户
- 解决已有平台用户未回填导致引擎≠平台(此前仅新用户同步)
This commit is contained in:
Pine
2026-08-25 15:31:32 +08:00
parent e5e9d265bf
commit 2675e3776a
2 changed files with 39 additions and 0 deletions
+31
View File
@@ -214,6 +214,37 @@ async def compute_provision(
)
@router.post("/compute/sync-users", summary="同步引擎用户=平台总用户(对账)")
async def sync_compute_users(
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_roles("operator")),
):
"""把平台全部用户对账到引擎:建号(幂等) + 缺令牌则签一枚 PAT,保证 engine 用户 = 平台用户。"""
users = await db.users.list()
created = pats = 0
for u in users:
uname = u.get("username")
if not uname:
continue
try:
await compute_client.ensure_user(uname)
created += 1
except Exception: # noqa: BLE001
pass
try:
toks = await compute_client.list_user_tokens(uname)
if not toks:
await compute_client.issue_pat(uname)
pats += 1
except Exception: # noqa: BLE001
pass
await write_audit(db, action="compute.sync_users", resource="compute",
resource_id="__all__", detail=f"users={len(users)}",
user=actor, request=request)
return {"total": len(users), "synced": created, "pat_issued": pats}
@router.api_route(
"/compute/proxy/{path:path}",
methods=["GET", "POST", "PUT", "DELETE", "PATCH"],
+8
View File
@@ -119,6 +119,14 @@ async def issue_user_token(username: str, name: str = "") -> dict:
return data.get("data") or {}
async def ensure_user(username: str) -> dict:
"""幂等建引擎用户:已存在(409/4xx)视为成功,不抛。"""
try:
return await create_user(username)
except ComputeError:
return {"username": username, "already": True}
async def list_models(status: int = 1) -> list[dict]:
"""列出引擎 admin 模型(models 表)。返回分页 items 列表。"""
data = await _request(