fix(core): досылать незаданные modify-params из live state.params (а не paramValue формы) — устраняет сброс needEnableAVI/ALB
This commit is contained in:
@@ -4,7 +4,7 @@ TOKEN_FILE="secrets/dev.token"
|
|||||||
|
|
||||||
# Release versions
|
# Release versions
|
||||||
# Version
|
# Version
|
||||||
VERSION="2.0.13"
|
VERSION="2.0.14"
|
||||||
|
|
||||||
NAMESPACE="nubes-dev"
|
NAMESPACE="nubes-dev"
|
||||||
PROVIDER_NAME="nubes"
|
PROVIDER_NAME="nubes"
|
||||||
|
|||||||
@@ -4,8 +4,49 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// instanceLiveParams возвращает ТЕКУЩИЕ params инстанса (GET /instances/{uid} → state.params),
|
||||||
|
// keyed by lower(code). Это единственный достоверный источник live-значений.
|
||||||
|
//
|
||||||
|
// ВАЖНО: paramValue из ответа GET /instanceOperations/{opUid}?fields=cfsParams — это
|
||||||
|
// дефолт ФОРМЫ операции, а НЕ состояние инстанса. Пример из HAR/edge_.har:
|
||||||
|
// для needEnableAVI в cfsParams paramValue="false", тогда как live-значение инстанса
|
||||||
|
// needEnableAVI=true. Досылка paramValue как live стирала ALB (reset-to-default).
|
||||||
|
func (c *UniversalClient) instanceLiveParams(ctx context.Context, instanceUid string) map[string]string {
|
||||||
|
live := map[string]string{}
|
||||||
|
params, err := c.GetInstanceStateParams(ctx, instanceUid)
|
||||||
|
if err != nil {
|
||||||
|
return live
|
||||||
|
}
|
||||||
|
for k, v := range params {
|
||||||
|
key := strings.ToLower(strings.TrimSpace(k))
|
||||||
|
if key == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
live[key] = v
|
||||||
|
}
|
||||||
|
return live
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookupLiveParam ищет live-значение параметра инстанса по возможным ключам cfsParam.
|
||||||
|
func lookupLiveParam(live map[string]string, p universalCfsParam) (string, bool) {
|
||||||
|
if len(live) == 0 {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
for _, cand := range []string{p.Code, p.SvcOperationCfsParam, p.Name, p.Label} {
|
||||||
|
key := strings.ToLower(strings.TrimSpace(cand))
|
||||||
|
if key == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v, ok := live[key]; ok && strings.TrimSpace(v) != "" {
|
||||||
|
return v, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
// fetchOperationCfsParams возвращает cfsParams операции. При неудаче живого
|
// fetchOperationCfsParams возвращает cfsParams операции. При неудаче живого
|
||||||
// GET /instanceOperations/{opUid}?fields=cfsParams (backend 500 в
|
// GET /instanceOperations/{opUid}?fields=cfsParams (backend 500 в
|
||||||
// getResourceRealmConfig на проблемных инстансах) берёт схему из
|
// getResourceRealmConfig на проблемных инстансах) берёт схему из
|
||||||
|
|||||||
@@ -135,16 +135,21 @@ func (c *UniversalClient) RunInstanceOperationUniversalWithDefaults(ctx context.
|
|||||||
sent[paramId] = true
|
sent[paramId] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
live := c.instanceLiveParams(ctx, instanceUid)
|
||||||
for _, param := range cfsParams {
|
for _, param := range cfsParams {
|
||||||
if sent[param.SvcOperationCfsParamId] {
|
if sent[param.SvcOperationCfsParamId] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val := ""
|
// Приоритет: live state.params инстанса → paramValue операции → defaultValue.
|
||||||
if param.ParamValue != nil {
|
// paramValue из cfsParams — дефолт формы, не состояние инстанса (см. operation_cfs.go).
|
||||||
val = *param.ParamValue
|
val, hasLive := lookupLiveParam(live, param)
|
||||||
} else if param.DefaultValue != nil {
|
if !hasLive {
|
||||||
val = *param.DefaultValue
|
if param.ParamValue != nil {
|
||||||
|
val = *param.ParamValue
|
||||||
|
} else if param.DefaultValue != nil {
|
||||||
|
val = *param.DefaultValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val = normalizeUniversalValueV6(val, param)
|
val = normalizeUniversalValueV6(val, param)
|
||||||
|
|
||||||
|
|||||||
@@ -105,26 +105,31 @@ func (c *UniversalClient) runInstanceOperationByCode(ctx context.Context, instan
|
|||||||
sent[paramId] = true
|
sent[paramId] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
live := c.instanceLiveParams(ctx, instanceUid)
|
||||||
for _, param := range cfsParams {
|
for _, param := range cfsParams {
|
||||||
if sent[param.SvcOperationCfsParamId] {
|
if sent[param.SvcOperationCfsParamId] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Дозаполняем ВСЕ незаданные параметры их текущим live-значением
|
// Дозаполняем ВСЕ незаданные параметры, чтобы бэкенд modify не трактовал
|
||||||
// (ParamValue из GET ?fields=cfsParams), а не только required.
|
// пропущенный/null как reset-to-default (иначе частичный payload затирает
|
||||||
// Бэкенд для modify трактует пропущенный/null как reset-to-default,
|
// create-поля, см. prompt_for_opus_modifier_null_bug.md).
|
||||||
// из-за чего частичный payload затирал create-поля (см. prompt_for_opus_modifier_null_bug.md).
|
//
|
||||||
// Поведение выровнено под RunInstanceOperationUniversalWithDefaults.
|
// ПРИОРИТЕТ ИСТОЧНИКА: live state.params инстанса → paramValue операции → defaultValue.
|
||||||
// НО: если ни live-значения, ни дефолта НЕТ — пропускаем (не шлём синтетический
|
// КРИТИЧНО: paramValue из ?fields=cfsParams — дефолт ФОРМЫ операции, не состояние
|
||||||
|
// инстанса (HAR/edge_.har: needEnableAVI paramValue="false" при live=true → стирало ALB).
|
||||||
|
// Если ни live, ни paramValue, ни defaultValue НЕТ — пропускаем (не шлём синтетический
|
||||||
// "0"/"false"/"[]", который может нарушить constraint "integer > 0").
|
// "0"/"false"/"[]", который может нарушить constraint "integer > 0").
|
||||||
if (param.ParamValue == nil || strings.TrimSpace(*param.ParamValue) == "") &&
|
val, hasLive := lookupLiveParam(live, param)
|
||||||
(param.DefaultValue == nil || strings.TrimSpace(*param.DefaultValue) == "") {
|
if !hasLive {
|
||||||
continue
|
if (param.ParamValue == nil || strings.TrimSpace(*param.ParamValue) == "") &&
|
||||||
}
|
(param.DefaultValue == nil || strings.TrimSpace(*param.DefaultValue) == "") {
|
||||||
val := ""
|
continue
|
||||||
if param.ParamValue != nil {
|
}
|
||||||
val = *param.ParamValue
|
if param.ParamValue != nil {
|
||||||
} else if param.DefaultValue != nil {
|
val = *param.ParamValue
|
||||||
val = *param.DefaultValue
|
} else if param.DefaultValue != nil {
|
||||||
|
val = *param.DefaultValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val = normalizeUniversalValueV6(val, param)
|
val = normalizeUniversalValueV6(val, param)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user