fix(core): fallback на /instanceOperations/default/{opId} при 500 getResourceRealmConfig в modify

This commit is contained in:
Repinoid
2026-09-22 16:49:36 +03:00
parent 947887a6ea
commit b1cea8a930
+40 -17
View File
@@ -188,6 +188,13 @@ type universalOperation struct {
CfsParams []universalCfsParam `json:"cfsParams"`
}
// universalOpDefaultResponse — схема операции из GET /instanceOperations/default/{opId}.
// Не вычисляет instance-специфичные выражения (getResourceRealmConfig) и не падает
// с 500 на проблемных инстансах (см. docs/DEBUG_REPORT_VC_VDC_500.md).
type universalOpDefaultResponse struct {
SvcOperation universalOperation `json:"svcOperation"`
}
type universalSubParam struct {
DefaultValue string `json:"defaultValue"`
DataType string `json:"dataType"`
@@ -400,6 +407,30 @@ func normalizeUniversalValueV6(val string, param universalCfsParam) string {
return trimmed
}
// fetchOperationCfsParams возвращает cfsParams операции. При неудаче живого
// GET /instanceOperations/{opUid}?fields=cfsParams (backend 500 в
// getResourceRealmConfig на проблемных инстансах) берёт схему из
// /instanceOperations/default/{opId}.
func (c *UniversalClient) fetchOperationCfsParams(ctx context.Context, opUid string, opId int) ([]universalCfsParam, error) {
opDetailsResp, _, err := c.doRequest(ctx, "GET", fmt.Sprintf("/instanceOperations/%s?fields=cfsParams", opUid), nil)
if err == nil {
var opDetails universalOpResponse
if uerr := json.Unmarshal(opDetailsResp, &opDetails); uerr == nil {
return opDetails.InstanceOperation.CfsParams, nil
}
}
defResp, _, defErr := c.doRequest(ctx, "GET", fmt.Sprintf("/instanceOperations/default/%d", opId), nil)
if defErr != nil {
return nil, fmt.Errorf("не удалось получить детали операции: %w", defErr)
}
var def universalOpDefaultResponse
if uerr := json.Unmarshal(defResp, &def); uerr != nil {
return nil, fmt.Errorf("не удалось разобрать детали операции: %w", uerr)
}
return def.SvcOperation.CfsParams, nil
}
// RunInstanceOperationUniversal runs an available operation (modify/suspend/delete/resume) if possible.
func (c *UniversalClient) RunInstanceOperationUniversal(ctx context.Context, instanceUid string, action string, params map[int]string) error {
state, err := c.GetInstanceState(ctx, instanceUid)
@@ -495,16 +526,12 @@ func (c *UniversalClient) RunInstanceOperationUniversalWithDefaults(ctx context.
return fmt.Errorf("не удалось получить UID операции для %s", action)
}
opDetailsResp, _, err := c.doRequest(ctx, "GET", fmt.Sprintf("/instanceOperations/%s?fields=cfsParams", opUid), nil)
cfsParams, err := c.fetchOperationCfsParams(ctx, opUid, opId)
if err != nil {
return fmt.Errorf("не удалось получить детали операции: %w", err)
}
var opDetails universalOpResponse
if err := json.Unmarshal(opDetailsResp, &opDetails); err != nil {
return fmt.Errorf("не удалось разобрать детали операции: %w", err)
return err
}
params, err = c.resolveRefSvcParamValues(ctx, opDetails.InstanceOperation.CfsParams, params)
params, err = c.resolveRefSvcParamValues(ctx, cfsParams, params)
if err != nil {
return err
}
@@ -523,7 +550,7 @@ func (c *UniversalClient) RunInstanceOperationUniversalWithDefaults(ctx context.
sent[paramId] = true
}
for _, param := range opDetails.InstanceOperation.CfsParams {
for _, param := range cfsParams {
if sent[param.SvcOperationCfsParamId] {
continue
}
@@ -1524,17 +1551,13 @@ func (c *UniversalClient) RunInstanceOperationUniversalByCode(ctx context.Contex
return fmt.Errorf("не удалось получить UID операции для %s", action)
}
opDetailsResp, _, err := c.doRequest(ctx, "GET", fmt.Sprintf("/instanceOperations/%s?fields=cfsParams", opUid), nil)
cfsParams, err := c.fetchOperationCfsParams(ctx, opUid, opId)
if err != nil {
return fmt.Errorf("не удалось получить детали операции: %w", err)
}
var opDetails universalOpResponse
if err := json.Unmarshal(opDetailsResp, &opDetails); err != nil {
return fmt.Errorf("не удалось разобрать детали операции: %w", err)
return err
}
codeToParam := make(map[string]universalCfsParam)
for _, p := range opDetails.InstanceOperation.CfsParams {
for _, p := range cfsParams {
if key := strings.ToLower(strings.TrimSpace(p.Code)); key != "" {
codeToParam[key] = p
}
@@ -1553,7 +1576,7 @@ func (c *UniversalClient) RunInstanceOperationUniversalByCode(ctx context.Contex
paramsByID[p.SvcOperationCfsParamId] = value
}
paramsByID, err = c.resolveRefSvcParamValues(ctx, opDetails.InstanceOperation.CfsParams, paramsByID)
paramsByID, err = c.resolveRefSvcParamValues(ctx, cfsParams, paramsByID)
if err != nil {
return err
}
@@ -1572,7 +1595,7 @@ func (c *UniversalClient) RunInstanceOperationUniversalByCode(ctx context.Contex
sent[paramId] = true
}
for _, param := range opDetails.InstanceOperation.CfsParams {
for _, param := range cfsParams {
if sent[param.SvcOperationCfsParamId] {
continue
}