fix(core): подсказки при конфликте имени учитывают отсутствие suspend/resume (no adopt) + supportsSuspend в сигнатурах
This commit is contained in:
@@ -17,15 +17,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// PlanExistingResourceDiagnosticsWithParams returns diagnostics when resource exists and compares required params.
|
// PlanExistingResourceDiagnosticsWithParams returns diagnostics when resource exists and compares required params.
|
||||||
|
// Устаревшая обёртка: считает, что сервис поддерживает suspend/resume (старое поведение).
|
||||||
func PlanExistingResourceDiagnosticsWithParams(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredParams map[int]string) diag.Diagnostics {
|
func PlanExistingResourceDiagnosticsWithParams(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredParams map[int]string) diag.Diagnostics {
|
||||||
return PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, client, serviceID, resourceName, adoptExistingOnCreate, desiredParams, "", nil)
|
return PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, client, serviceID, resourceName, adoptExistingOnCreate, desiredParams, "", nil, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PlanExistingResourceDiagnosticsWithParamsAndDomain — см. PlanExistingResourceDiagnosticsWithParams.
|
||||||
func PlanExistingResourceDiagnosticsWithParamsAndDomain(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredParams map[int]string, desiredDomain string) diag.Diagnostics {
|
func PlanExistingResourceDiagnosticsWithParamsAndDomain(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredParams map[int]string, desiredDomain string) diag.Diagnostics {
|
||||||
return PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, client, serviceID, resourceName, adoptExistingOnCreate, desiredParams, desiredDomain, nil)
|
return PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, client, serviceID, resourceName, adoptExistingOnCreate, desiredParams, desiredDomain, nil, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredParams map[int]string, desiredDomain string, allowedDomainServiceIDs []int) diag.Diagnostics {
|
// PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices — create-time проверка
|
||||||
|
// «инстанс с таким именем уже существует».
|
||||||
|
//
|
||||||
|
// supportsSuspend — поддерживает ли сервис операции suspend/resume (из YAML-спеки).
|
||||||
|
// Если НЕТ (например vc_nsxt/Edge), то:
|
||||||
|
// - советы про resume/adopt для состояния Suspend бессмысленны — такое состояние
|
||||||
|
// для такого сервиса вообще недостижимо, а усыновление требует resume;
|
||||||
|
// - корректные действия пользователя: удалить инстанс в ЛК или взять другое имя.
|
||||||
|
func PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredParams map[int]string, desiredDomain string, allowedDomainServiceIDs []int, supportsSuspend bool) diag.Diagnostics {
|
||||||
f, _ := os.OpenFile("/tmp/nubes_find_debug.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
f, _ := os.OpenFile("/tmp/nubes_find_debug.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if f != nil {
|
if f != nil {
|
||||||
fmt.Fprintf(f, "[FIND-DEBUG] PlanExistingResourceDiagnostics entered: serviceId=%d name=%q adopt=%v client=%v\n", serviceID, resourceName, adoptExistingOnCreate, client != nil)
|
fmt.Fprintf(f, "[FIND-DEBUG] PlanExistingResourceDiagnostics entered: serviceId=%d name=%q adopt=%v client=%v\n", serviceID, resourceName, adoptExistingOnCreate, client != nil)
|
||||||
@@ -71,7 +81,7 @@ func PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx context.C
|
|||||||
}
|
}
|
||||||
diags.AddError(
|
diags.AddError(
|
||||||
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING)",
|
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING)",
|
||||||
"Инстанс с таким resource_name уже работает.\nАвто-усыновление отключено (adopt_existing_on_create=false).\nВыберите другое имя, если нужен новый ресурс.\nИли выполните импорт существующего ресурса через усыновление: установите adopt_existing_on_create=true и повторите apply."+formatInstanceDetails(existing, serviceID, resourceName),
|
"Инстанс с таким resource_name уже работает.\nАвто-усыновление отключено (adopt_existing_on_create=false).\nВыберите другое имя, если нужен новый ресурс."+runningConflictHint(supportsSuspend)+formatInstanceDetails(existing, serviceID, resourceName),
|
||||||
)
|
)
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -86,7 +96,7 @@ func PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx context.C
|
|||||||
if !adoptExistingOnCreate {
|
if !adoptExistingOnCreate {
|
||||||
diags.AddError(
|
diags.AddError(
|
||||||
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (SUSPEND)",
|
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (SUSPEND)",
|
||||||
"Инстанс найден в состоянии Suspend, но adopt_existing_on_create=false.\nДля восстановления/импорта этим ресурсом включите adopt_existing_on_create=true и повторите apply."+formatInstanceDetails(existing, serviceID, resourceName),
|
"Инстанс найден в состоянии Suspend, но adopt_existing_on_create=false."+suspendConflictHint(supportsSuspend)+formatInstanceDetails(existing, serviceID, resourceName),
|
||||||
)
|
)
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -192,11 +202,15 @@ func appendRemotePlanInputDiagnostics(ctx context.Context, client *core.Universa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateExistingResourceDiagnosticsWithDomain — устаревшая обёртка (suspend считается
|
||||||
|
// поддерживаемым). См. CreateExistingResourceDiagnosticsWithDomainAndServices.
|
||||||
func CreateExistingResourceDiagnosticsWithDomain(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredDomain string) diag.Diagnostics {
|
func CreateExistingResourceDiagnosticsWithDomain(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredDomain string) diag.Diagnostics {
|
||||||
return CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, client, serviceID, resourceName, adoptExistingOnCreate, desiredDomain, nil)
|
return CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, client, serviceID, resourceName, adoptExistingOnCreate, desiredDomain, nil, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateExistingResourceDiagnosticsWithDomainAndServices(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredDomain string, allowedDomainServiceIDs []int) diag.Diagnostics {
|
// CreateExistingResourceDiagnosticsWithDomainAndServices — см.
|
||||||
|
// PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices (supportsSuspend).
|
||||||
|
func CreateExistingResourceDiagnosticsWithDomainAndServices(ctx context.Context, client *core.UniversalClient, serviceID int, resourceName string, adoptExistingOnCreate bool, desiredDomain string, allowedDomainServiceIDs []int, supportsSuspend bool) diag.Diagnostics {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return diags
|
return diags
|
||||||
@@ -230,7 +244,7 @@ func CreateExistingResourceDiagnosticsWithDomainAndServices(ctx context.Context,
|
|||||||
}
|
}
|
||||||
diags.AddError(
|
diags.AddError(
|
||||||
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING)",
|
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING)",
|
||||||
"Инстанс с таким resource_name уже работает.\nАвто-усыновление отключено (adopt_existing_on_create=false).\nВыберите другое имя, если нужен новый ресурс.\nИли выполните импорт существующего ресурса через усыновление: установите adopt_existing_on_create=true и повторите apply."+formatInstanceDetails(existing, serviceID, resourceName),
|
"Инстанс с таким resource_name уже работает.\nАвто-усыновление отключено (adopt_existing_on_create=false).\nВыберите другое имя, если нужен новый ресурс."+runningConflictHint(supportsSuspend)+formatInstanceDetails(existing, serviceID, resourceName),
|
||||||
)
|
)
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -240,7 +254,7 @@ func CreateExistingResourceDiagnosticsWithDomainAndServices(ctx context.Context,
|
|||||||
}
|
}
|
||||||
diags.AddError(
|
diags.AddError(
|
||||||
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (SUSPEND)",
|
"РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (SUSPEND)",
|
||||||
"Инстанс найден в состоянии Suspend, но adopt_existing_on_create=false.\nДля восстановления/импорта этим ресурсом включите adopt_existing_on_create=true и повторите apply."+formatInstanceDetails(existing, serviceID, resourceName),
|
"Инстанс найден в состоянии Suspend, но adopt_existing_on_create=false."+suspendConflictHint(supportsSuspend)+formatInstanceDetails(existing, serviceID, resourceName),
|
||||||
)
|
)
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@@ -252,6 +266,30 @@ func CreateExistingResourceDiagnosticsWithDomainAndServices(ctx context.Context,
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// runningConflictHint — что предлагать, если инстанс с таким именем уже работает.
|
||||||
|
//
|
||||||
|
// Для сервисов БЕЗ suspend/resume усыновление работающего инстанса технически возможно
|
||||||
|
// (приостановка не требуется — adopt просто берёт существующий uid), но пользователю
|
||||||
|
// часто нужен именно destroy, поэтому называем оба пути явно.
|
||||||
|
func runningConflictHint(supportsSuspend bool) string {
|
||||||
|
if !supportsSuspend {
|
||||||
|
return "\nЛибо усыновите существующий инстанс: adopt_existing_on_create=true (он уже работает, suspend не требуется).\nЛибо удалите инстанс в Личном кабинете Nubes и повторите apply."
|
||||||
|
}
|
||||||
|
return "\nИли выполните импорт существующего ресурса через усыновление: установите adopt_existing_on_create=true и повторите apply."
|
||||||
|
}
|
||||||
|
|
||||||
|
// suspendConflictHint — что предлагать, если инстанс найден в состоянии Suspend.
|
||||||
|
//
|
||||||
|
// Для сервисов БЕЗ suspend/resume состояние Suspend недостижимо, а adopt требует
|
||||||
|
// resume — значит совет «включите adopt_existing_on_create=true» заведомо невыполним.
|
||||||
|
// Корректный выход один: удалить инстанс и/или взять другое имя.
|
||||||
|
func suspendConflictHint(supportsSuspend bool) string {
|
||||||
|
if !supportsSuspend {
|
||||||
|
return "\nСервис НЕ поддерживает suspend/resume, поэтому усыновление (adopt) для него невозможно.\nУдалите инстанс в Личном кабинете Nubes и повторите apply, либо выберите другое resource_name."
|
||||||
|
}
|
||||||
|
return "\nДля восстановления/импорта этим ресурсом включите adopt_existing_on_create=true и повторите apply."
|
||||||
|
}
|
||||||
|
|
||||||
func appendLocalPlanInputDiagnostics(serviceID int, desiredParams map[int]string, desiredDomain string, diags *diag.Diagnostics) {
|
func appendLocalPlanInputDiagnostics(serviceID int, desiredParams map[int]string, desiredDomain string, diags *diag.Diagnostics) {
|
||||||
if diags == nil {
|
if diags == nil {
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user