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_*` 显式覆盖。脚本会以主
|
文件中,不写入报告或日志。上述值仍可用 `AI_GATEWAY_ACCEPTANCE_*` 显式覆盖。脚本会以主
|
||||||
身份为模板幂等准备其余隔离身份;模型变量可省略,脚本会从当前启用候选中选择 Gemini 图片
|
身份为模板幂等准备其余隔离身份;模型变量可省略,脚本会从当前启用候选中选择 Gemini 图片
|
||||||
编辑模型,以及 `omni_video.max_images >= 9` 的视频模型并优先 Seedance 2.0/fast。
|
编辑模型,以及 `omni_video.max_images >= 9` 的视频模型并优先 Seedance 2.0/fast。
|
||||||
|
验收组按 release SHA 隔离;历史 Run 的用户和分片不会被清理或复用到新 release,本次需要的
|
||||||
|
分片及其 API Key 会幂等迁移到当前 release 的专属组。
|
||||||
|
|
||||||
为保证请求严格各有一半命中宁波和香港,可以把两个 Gateway URL 配成两个节点的
|
为保证请求严格各有一半命中宁波和香港,可以把两个 Gateway URL 配成两个节点的
|
||||||
`https://<节点IP>`,并设置
|
`https://<节点IP>`,并设置
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ api_image=$(node "$cluster_root/scripts/release-manifest.mjs" get "$release_mani
|
|||||||
}
|
}
|
||||||
api_digest=${api_image##*@}
|
api_digest=${api_image##*@}
|
||||||
worker_digest=$api_digest
|
worker_digest=$api_digest
|
||||||
|
acceptance_group_key=production-acceptance-${release_sha:0:12}
|
||||||
if [[ $skip_local_acceptance != true ]]; then
|
if [[ $skip_local_acceptance != true ]]; then
|
||||||
node "$cluster_root/scripts/acceptance/report.mjs" validate \
|
node "$cluster_root/scripts/acceptance/report.mjs" validate \
|
||||||
--input "$local_acceptance_report" >/dev/null
|
--input "$local_acceptance_report" >/dev/null
|
||||||
@@ -736,12 +737,12 @@ ensure_acceptance_user_group() {
|
|||||||
local user_response=$temporary_root/acceptance-user.json
|
local user_response=$temporary_root/acceptance-user.json
|
||||||
local group_id group_body user_body isolation_state
|
local group_id group_body user_body isolation_state
|
||||||
admin_request GET /api/admin/user-groups '' "$groups_response"
|
admin_request GET /api/admin/user-groups '' "$groups_response"
|
||||||
group_id=$(jq -r '
|
group_id=$(jq -r --arg groupKey "$acceptance_group_key" '
|
||||||
[.items[] | select(.groupKey == "production-acceptance") | .id]
|
[.items[] | select(.groupKey == $groupKey) | .id]
|
||||||
| if length == 1 then .[0] else empty end
|
| if length == 1 then .[0] else empty end
|
||||||
' "$groups_response")
|
' "$groups_response")
|
||||||
group_body=$(jq -cn '{
|
group_body=$(jq -cn --arg groupKey "$acceptance_group_key" '{
|
||||||
groupKey:"production-acceptance",
|
groupKey:$groupKey,
|
||||||
name:"Production Acceptance",
|
name:"Production Acceptance",
|
||||||
description:"Dedicated production-isomorphic acceptance traffic",
|
description:"Dedicated production-isomorphic acceptance traffic",
|
||||||
source:"gateway",
|
source:"gateway",
|
||||||
@@ -754,8 +755,8 @@ ensure_acceptance_user_group() {
|
|||||||
status:"active"
|
status:"active"
|
||||||
}')
|
}')
|
||||||
if [[ -z $group_id ]]; then
|
if [[ -z $group_id ]]; then
|
||||||
[[ $(jq '[.items[] | select(.groupKey == "production-acceptance")] | length' \
|
[[ $(jq --arg groupKey "$acceptance_group_key" \
|
||||||
"$groups_response") == 0 ]] || {
|
'[.items[] | select(.groupKey == $groupKey)] | length' "$groups_response") == 0 ]] || {
|
||||||
echo 'acceptance user group lookup was ambiguous' >&2
|
echo 'acceptance user group lookup was ambiguous' >&2
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -931,19 +932,22 @@ WITH primary_user AS (
|
|||||||
AND deleted_at IS NULL
|
AND deleted_at IS NULL
|
||||||
AND COALESCE(key_secret, '') <> ''
|
AND COALESCE(key_secret, '') <> ''
|
||||||
), existing_keys AS (
|
), 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
|
FROM shard_users shard
|
||||||
JOIN LATERAL (
|
WHERE key.id=(
|
||||||
SELECT key.id, key.gateway_user_id, key.key_secret
|
SELECT selected.id
|
||||||
FROM gateway_api_keys key
|
FROM gateway_api_keys selected
|
||||||
WHERE key.gateway_user_id=shard.id
|
WHERE selected.gateway_user_id=shard.id
|
||||||
AND key.name='Production Acceptance Shard'
|
AND selected.name='Production Acceptance Shard'
|
||||||
AND key.status='active'
|
AND selected.status='active'
|
||||||
AND key.deleted_at IS NULL
|
AND selected.deleted_at IS NULL
|
||||||
AND COALESCE(key.key_secret, '') <> ''
|
AND COALESCE(selected.key_secret, '') <> ''
|
||||||
ORDER BY key.created_at
|
ORDER BY selected.created_at
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
) selected ON true
|
)
|
||||||
|
RETURNING key.id, key.gateway_user_id, key.key_secret
|
||||||
), new_key_material AS (
|
), new_key_material AS (
|
||||||
SELECT shard.id AS gateway_user_id,
|
SELECT shard.id AS gateway_user_id,
|
||||||
'sk-gw-' || encode(gen_random_bytes(32), 'hex') AS secret
|
'sk-gw-' || encode(gen_random_bytes(32), 'hex') AS secret
|
||||||
|
|||||||
Reference in New Issue
Block a user