fix(acceptance): 按发布隔离验收身份组
历史验收主身份仍引用固定 production-acceptance 组,严格隔离门禁因此在切换 validation 前正确阻断。 验收组改为包含 release SHA 的稳定键;历史身份保持可审计,本次分片及已有 API Key 幂等迁移到当前发布专属组,避免清理或影响正式身份。 验证:bash -n、ShellCheck、验收报告测试、线上引用关系只读审计。
This commit is contained in:
@@ -124,6 +124,8 @@ PNG 并通过验收 Key 上传到 Gateway。生产快照默认在已部署的 AP
|
||||
文件中,不写入报告或日志。上述值仍可用 `AI_GATEWAY_ACCEPTANCE_*` 显式覆盖。脚本会以主
|
||||
身份为模板幂等准备其余隔离身份;模型变量可省略,脚本会从当前启用候选中选择 Gemini 图片
|
||||
编辑模型,以及 `omni_video.max_images >= 9` 的视频模型并优先 Seedance 2.0/fast。
|
||||
验收组按 release SHA 隔离;历史 Run 的用户和分片不会被清理或复用到新 release,本次需要的
|
||||
分片及其 API Key 会幂等迁移到当前 release 的专属组。
|
||||
|
||||
为保证请求严格各有一半命中宁波和香港,可以把两个 Gateway URL 配成两个节点的
|
||||
`https://<节点IP>`,并设置
|
||||
|
||||
@@ -156,6 +156,7 @@ api_image=$(node "$cluster_root/scripts/release-manifest.mjs" get "$release_mani
|
||||
}
|
||||
api_digest=${api_image##*@}
|
||||
worker_digest=$api_digest
|
||||
acceptance_group_key=production-acceptance-${release_sha:0:12}
|
||||
if [[ $skip_local_acceptance != true ]]; then
|
||||
node "$cluster_root/scripts/acceptance/report.mjs" validate \
|
||||
--input "$local_acceptance_report" >/dev/null
|
||||
@@ -736,12 +737,12 @@ ensure_acceptance_user_group() {
|
||||
local user_response=$temporary_root/acceptance-user.json
|
||||
local group_id group_body user_body isolation_state
|
||||
admin_request GET /api/admin/user-groups '' "$groups_response"
|
||||
group_id=$(jq -r '
|
||||
[.items[] | select(.groupKey == "production-acceptance") | .id]
|
||||
group_id=$(jq -r --arg groupKey "$acceptance_group_key" '
|
||||
[.items[] | select(.groupKey == $groupKey) | .id]
|
||||
| if length == 1 then .[0] else empty end
|
||||
' "$groups_response")
|
||||
group_body=$(jq -cn '{
|
||||
groupKey:"production-acceptance",
|
||||
group_body=$(jq -cn --arg groupKey "$acceptance_group_key" '{
|
||||
groupKey:$groupKey,
|
||||
name:"Production Acceptance",
|
||||
description:"Dedicated production-isomorphic acceptance traffic",
|
||||
source:"gateway",
|
||||
@@ -754,8 +755,8 @@ ensure_acceptance_user_group() {
|
||||
status:"active"
|
||||
}')
|
||||
if [[ -z $group_id ]]; then
|
||||
[[ $(jq '[.items[] | select(.groupKey == "production-acceptance")] | length' \
|
||||
"$groups_response") == 0 ]] || {
|
||||
[[ $(jq --arg groupKey "$acceptance_group_key" \
|
||||
'[.items[] | select(.groupKey == $groupKey)] | length' "$groups_response") == 0 ]] || {
|
||||
echo 'acceptance user group lookup was ambiguous' >&2
|
||||
return 1
|
||||
}
|
||||
@@ -931,19 +932,22 @@ WITH primary_user AS (
|
||||
AND deleted_at IS NULL
|
||||
AND COALESCE(key_secret, '') <> ''
|
||||
), existing_keys AS (
|
||||
SELECT selected.id, selected.gateway_user_id, selected.key_secret
|
||||
UPDATE gateway_api_keys key
|
||||
SET user_group_id='$acceptance_group_id'::uuid,
|
||||
updated_at=now()
|
||||
FROM shard_users shard
|
||||
JOIN LATERAL (
|
||||
SELECT key.id, key.gateway_user_id, key.key_secret
|
||||
FROM gateway_api_keys key
|
||||
WHERE key.gateway_user_id=shard.id
|
||||
AND key.name='Production Acceptance Shard'
|
||||
AND key.status='active'
|
||||
AND key.deleted_at IS NULL
|
||||
AND COALESCE(key.key_secret, '') <> ''
|
||||
ORDER BY key.created_at
|
||||
WHERE key.id=(
|
||||
SELECT selected.id
|
||||
FROM gateway_api_keys selected
|
||||
WHERE selected.gateway_user_id=shard.id
|
||||
AND selected.name='Production Acceptance Shard'
|
||||
AND selected.status='active'
|
||||
AND selected.deleted_at IS NULL
|
||||
AND COALESCE(selected.key_secret, '') <> ''
|
||||
ORDER BY selected.created_at
|
||||
LIMIT 1
|
||||
) selected ON true
|
||||
)
|
||||
RETURNING key.id, key.gateway_user_id, key.key_secret
|
||||
), new_key_material AS (
|
||||
SELECT shard.id AS gateway_user_id,
|
||||
'sk-gw-' || encode(gen_random_bytes(32), 'hex') AS secret
|
||||
|
||||
Reference in New Issue
Block a user