From 0998b19ec586fa695905b09c19d6ca91291f5f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Tue, 30 Jun 2026 17:38:46 +0400 Subject: [PATCH] =?UTF-8?q?refactor:=20P2.8=20=E2=80=94=20adoptExistingIns?= =?UTF-8?q?tanceOnCreate=20uses=20classifyStatus=20+=20exhaustive=20switch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/resources_core/crud.go | 77 +++++++++++-------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/universal_rebuild/internal/resources_core/crud.go b/universal_rebuild/internal/resources_core/crud.go index 809cc56..cc96f8c 100644 --- a/universal_rebuild/internal/resources_core/crud.go +++ b/universal_rebuild/internal/resources_core/crud.go @@ -128,18 +128,19 @@ func adoptExistingInstanceOnCreate(ctx context.Context, client *core.UniversalCl if !resumeIfExists { return "", fmt.Errorf("инстанс с resource_name %s уже существует; выберите другое имя, если нужен новый ресурс, или выполните импорт через усыновление: установите adopt_existing_on_create=true и повторите apply. %s", displayName, formatInstanceDetails(existing, serviceID, displayName)) } - status := normalizeStatus(existing.ExplainedStatus) - if isStatusNotCreated(status) { + state := classifyStatus(existing) + statusText := normalizeStatus(existing.ExplainedStatus) + + switch state { + case StateNotCreated: // P0.2: авто-cleanup orphan-инстанса при adopt_existing_on_create=true. - // Вместо «удалите вручную в ЛК» — удаляем сами и создаём новый. if err := client.RunInstanceOperationUniversal(ctx, existing.InstanceUid, "delete", nil); err != nil { return "", fmt.Errorf("не удалось авто-удалить orphan-инстанс %s (статус: %s): %w. %s", - existing.InstanceUid, status, err, formatInstanceDetails(existing, serviceID, displayName)) + existing.InstanceUid, statusText, err, formatInstanceDetails(existing, serviceID, displayName)) } return client.CreateGenericInstanceUniversalV6(ctx, serviceID, displayName, params) - } - if isStatusRunning(status) { - // Валидация ref-параметров для running инстанса при adopt + + case StateRunning, StateRunningPending: refIssues, err := ValidateRefParamsOnAdopt(ctx, client, serviceID, params, existing.InstanceUid) if err != nil { return "", fmt.Errorf("ошибка валидации ref-параметров при adopt: %s", err) @@ -148,18 +149,15 @@ func adoptExistingInstanceOnCreate(ctx context.Context, client *core.UniversalCl return "", fmt.Errorf("%s\n%s", FormatRefParamIssues(refIssues), formatInstanceDetails(existing, serviceID, displayName)) } return existing.InstanceUid, nil - } - if !isStatusSuspended(status) { - return "", fmt.Errorf("инстанс с resource_name %s найден, но статус не подходит для авто-усыновления: %s. %s", displayName, status, formatInstanceDetails(existing, serviceID, displayName)) - } - mismatches, err := RequiredParamsMismatch(ctx, client, serviceID, params, existing.InstanceUid) - if err != nil { - return "", err - } - if len(mismatches) > 0 { - return "", fmt.Errorf("required params mismatch for resource_name %s: %s. %s", displayName, FormatRequiredParamMismatchMessage(mismatches), formatInstanceDetails(existing, serviceID, displayName)) - } - if isStatusSuspended(status) { + + case StateSuspended: + mismatches, err := RequiredParamsMismatch(ctx, client, serviceID, params, existing.InstanceUid) + if err != nil { + return "", err + } + if len(mismatches) > 0 { + return "", fmt.Errorf("required params mismatch for resource_name %s: %s. %s", displayName, FormatRequiredParamMismatchMessage(mismatches), formatInstanceDetails(existing, serviceID, displayName)) + } if err := client.RunInstanceOperationUniversal(ctx, existing.InstanceUid, "resume", nil); err != nil { return "", err } @@ -167,18 +165,37 @@ func adoptExistingInstanceOnCreate(ctx context.Context, client *core.UniversalCl if err != nil { return "", err } - resumedStatus := normalizeStatus(resumed.ExplainedStatus) - if isStatusNonAdoptable(resumedStatus) || isStatusSuspended(resumedStatus) { + resumedState := classifyStatus(resumed) + if !isAdoptable(resumedState) { return "", fmt.Errorf("resource not ready after resume: %s. %s", resumed.ExplainedStatus, formatInstanceDetails(resumed, serviceID, displayName)) } + refIssues, err := ValidateRefParamsOnAdopt(ctx, client, serviceID, params, existing.InstanceUid) + if err != nil { + return "", fmt.Errorf("ошибка валидации ref-параметров после resume: %s", err) + } + if HasHardErrors(refIssues) { + return "", fmt.Errorf("%s\n%s", FormatRefParamIssues(refIssues), formatInstanceDetails(existing, serviceID, displayName)) + } + return existing.InstanceUid, nil + + case StateCreating, StateModifying, StateSuspending, StateResuming, StateDeleting: + return "", fmt.Errorf("инстанс с resource_name %s: операция в процессе (статус: %s). Дождитесь завершения и повторите apply. %s", + displayName, statusText, formatInstanceDetails(existing, serviceID, displayName)) + + case StateCreationFailed: + return "", fmt.Errorf("инстанс с resource_name %s: создание не удалось (статус: %s). Удалите его в Личном кабинете или установите adopt_existing_on_create=true для авто-очистки. %s", + displayName, statusText, formatInstanceDetails(existing, serviceID, displayName)) + + case StateModificationFailed, StateSuspendFailed, StateResumeFailed, StateDeletionFailed: + return "", fmt.Errorf("инстанс с resource_name %s: предыдущая операция завершилась ошибкой (статус: %s). Проверьте состояние в Личном кабинете. %s", + displayName, statusText, formatInstanceDetails(existing, serviceID, displayName)) + + case StateDeleted, StateOrphaned: + return "", fmt.Errorf("инстанс с resource_name %s: удалён или осиротел (статус: %s). Выберите другое имя для нового ресурса. %s", + displayName, statusText, formatInstanceDetails(existing, serviceID, displayName)) + + default: + return "", fmt.Errorf("инстанс с resource_name %s: неизвестный статус %q. %s", + displayName, statusText, formatInstanceDetails(existing, serviceID, displayName)) } - // Валидация ref-параметров после resume/adopt - refIssues, err := ValidateRefParamsOnAdopt(ctx, client, serviceID, params, existing.InstanceUid) - if err != nil { - return "", fmt.Errorf("ошибка валидации ref-параметров после resume: %s", err) - } - if HasHardErrors(refIssues) { - return "", fmt.Errorf("%s\n%s", FormatRefParamIssues(refIssues), formatInstanceDetails(existing, serviceID, displayName)) - } - return existing.InstanceUid, nil }