refactor: P2.8 — adoptExistingInstanceOnCreate uses classifyStatus + exhaustive switch
This commit is contained in:
@@ -128,18 +128,19 @@ func adoptExistingInstanceOnCreate(ctx context.Context, client *core.UniversalCl
|
|||||||
if !resumeIfExists {
|
if !resumeIfExists {
|
||||||
return "", fmt.Errorf("инстанс с resource_name %s уже существует; выберите другое имя, если нужен новый ресурс, или выполните импорт через усыновление: установите adopt_existing_on_create=true и повторите apply. %s", displayName, formatInstanceDetails(existing, serviceID, displayName))
|
return "", fmt.Errorf("инстанс с resource_name %s уже существует; выберите другое имя, если нужен новый ресурс, или выполните импорт через усыновление: установите adopt_existing_on_create=true и повторите apply. %s", displayName, formatInstanceDetails(existing, serviceID, displayName))
|
||||||
}
|
}
|
||||||
status := normalizeStatus(existing.ExplainedStatus)
|
state := classifyStatus(existing)
|
||||||
if isStatusNotCreated(status) {
|
statusText := normalizeStatus(existing.ExplainedStatus)
|
||||||
|
|
||||||
|
switch state {
|
||||||
|
case StateNotCreated:
|
||||||
// P0.2: авто-cleanup orphan-инстанса при adopt_existing_on_create=true.
|
// P0.2: авто-cleanup orphan-инстанса при adopt_existing_on_create=true.
|
||||||
// Вместо «удалите вручную в ЛК» — удаляем сами и создаём новый.
|
|
||||||
if err := client.RunInstanceOperationUniversal(ctx, existing.InstanceUid, "delete", nil); err != nil {
|
if err := client.RunInstanceOperationUniversal(ctx, existing.InstanceUid, "delete", nil); err != nil {
|
||||||
return "", fmt.Errorf("не удалось авто-удалить orphan-инстанс %s (статус: %s): %w. %s",
|
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)
|
return client.CreateGenericInstanceUniversalV6(ctx, serviceID, displayName, params)
|
||||||
}
|
|
||||||
if isStatusRunning(status) {
|
case StateRunning, StateRunningPending:
|
||||||
// Валидация ref-параметров для running инстанса при adopt
|
|
||||||
refIssues, err := ValidateRefParamsOnAdopt(ctx, client, serviceID, params, existing.InstanceUid)
|
refIssues, err := ValidateRefParamsOnAdopt(ctx, client, serviceID, params, existing.InstanceUid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("ошибка валидации ref-параметров при adopt: %s", err)
|
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 "", fmt.Errorf("%s\n%s", FormatRefParamIssues(refIssues), formatInstanceDetails(existing, serviceID, displayName))
|
||||||
}
|
}
|
||||||
return existing.InstanceUid, nil
|
return existing.InstanceUid, nil
|
||||||
}
|
|
||||||
if !isStatusSuspended(status) {
|
case StateSuspended:
|
||||||
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 {
|
||||||
mismatches, err := RequiredParamsMismatch(ctx, client, serviceID, params, existing.InstanceUid)
|
return "", err
|
||||||
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 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) {
|
|
||||||
if err := client.RunInstanceOperationUniversal(ctx, existing.InstanceUid, "resume", nil); err != nil {
|
if err := client.RunInstanceOperationUniversal(ctx, existing.InstanceUid, "resume", nil); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -167,18 +165,37 @@ func adoptExistingInstanceOnCreate(ctx context.Context, client *core.UniversalCl
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
resumedStatus := normalizeStatus(resumed.ExplainedStatus)
|
resumedState := classifyStatus(resumed)
|
||||||
if isStatusNonAdoptable(resumedStatus) || isStatusSuspended(resumedStatus) {
|
if !isAdoptable(resumedState) {
|
||||||
return "", fmt.Errorf("resource not ready after resume: %s. %s", resumed.ExplainedStatus, formatInstanceDetails(resumed, serviceID, displayName))
|
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
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user