fix(core): fallback на /instanceOperations/default/{opId} при 500 getResourceRealmConfig в modify
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user