diff --git a/HISTORY/2026-07-06_architectural_refactoring.md b/HISTORY/2026-07-06_architectural_refactoring.md index 4e751ab..8001e35 100644 --- a/HISTORY/2026-07-06_architectural_refactoring.md +++ b/HISTORY/2026-07-06_architectural_refactoring.md @@ -87,3 +87,44 @@ tf_provider/ - [x] yaml-generator → lib - [ ] resource-generator → lib - [ ] docs-generator → lib + +--- + +## ⚠️ BUG: modify падает с 500 — GET ?fields=cfsParams вызывает getResourceRealmConfig + +**Симптом:** `terraform apply` при modify возвращает: +``` +не удалось получить детали операции: ошибка API 500: Invalid call of the function [getResourceRealmConfig], first Argument [resourceRealm] is of invalid type, Cannot cast Object type [Struct] to a value of type [string] +``` + +**Причина:** `RunInstanceOperationUniversalWithDefaults` (client.go:384) делает GET `/instanceOperations/{opUid}?fields=cfsParams`. Бэкенд (ColdFusion) при вычислении cfsParams вызывает `getResourceRealmConfig` через `expression_parser.cfc:184`. Если `resourceRealm` в контексте инстанса — Struct (объект), а не string, функция падает. + +**Где проявляется:** +- `client.go:420` — `RunInstanceOperationUniversalWithDefaults` (modify/create/delete с дефолтами) +- `client.go:1399` — `RunInstanceOperationUniversalByCode` (операции по code) +- `client.go:224` — `CreateGenericInstanceUniversalV6` (CREATE flow) — работает на новых инстансах + +**Почему на одних инстансах падает, на других нет:** +- Новые инстансы: `resourceRealm` = string → OK +- Старые/модифицированные: `resourceRealm` = Struct → 500 + +**Исправление (v5.0.62):** +- `crud.go:58`: `UpdateResourceWithTimeout` → `RunInstanceOperationUniversal` (без GET) +- GET не нужен для modify — все параметры уже известны из конфига + +**Статус:** ✅ FIXED v5.0.62 +**Файлы:** +- `/home/naeel/tf_provider/provider/internal/resources_core/crud.go:58` +- `/home/naeel/tf_provider/provider/internal/core/client.go:384` (WithDefaults — не используется в modify) + +**Тесты (v5.0.62):** +- ✅ CREATE postgres — OK +- ✅ MODIFY postgres (replicas, backup_config, access_config) — OK +- ✅ CREATE/DELETE user — OK +- ✅ CREATE/DELETE database — OK +- ✅ Invalid role → 400 c понятным сообщением — OK +- ✅ No-change plan (идемпотентность) — OK + +**Остаётся риск:** +- `RunInstanceOperationUniversalByCode` (client.go:1399) всё ещё делает GET — может упасть для service_operation_resource на проблемных инстансах +- `CreateGenericInstanceUniversalV6` (client.go:224) — CREATE на инстансах где resourceRealm = Struct может упасть diff --git a/TEST_STAND/PG/resources.tf b/TEST_STAND/PG/resources.tf index 3f3ae60..1683e75 100644 --- a/TEST_STAND/PG/resources.tf +++ b/TEST_STAND/PG/resources.tf @@ -1,6 +1,7 @@ # ============================================================================= # PostgreSQL — основной ресурс # ============================================================================= + resource "nubes_postgres" "npg" { resource_name = "pg4tf033777" # ← ЗАМЕНИ на своё имя @@ -14,7 +15,7 @@ resource "nubes_postgres" "npg" { cpu = "500" # ← милликоры (1000 = 1 vCPU) memory = "512" # ← MB replicas = "1" # ← количество нод (1 = без реплики) - disk = "10" # ← GB + disk = "11" # ← GB }) # ── Сетевой доступ ── diff --git a/TEST_STAND/POSTGRES/main.tf b/TEST_STAND/POSTGRES/main.tf index 6681e64..db58511 100644 --- a/TEST_STAND/POSTGRES/main.tf +++ b/TEST_STAND/POSTGRES/main.tf @@ -2,7 +2,7 @@ terraform { required_providers { nubes = { source = "terra.k8c.ru/nubes-test/nubes" - version = "5.0.59" + version = "5.0.62" } } } diff --git a/TEST_STAND/POSTGRES/resources.tf b/TEST_STAND/POSTGRES/resources.tf index b68f7f2..a2b4461 100644 --- a/TEST_STAND/POSTGRES/resources.tf +++ b/TEST_STAND/POSTGRES/resources.tf @@ -1,5 +1,5 @@ resource "nubes_postgres" "npg" { - resource_name = "pg4tf033" + resource_name = "pgtst00" startup_configuration = jsonencode({ resourceRealm = var.realm @@ -14,7 +14,7 @@ resource "nubes_postgres" "npg" { access_configuration = jsonencode({ masterIpSpace = "no-needed" - masterAccessList = [] + masterAccessList = ["10.0.0.0/8"] slaveIpSpace = "no-needed" slaveAccessList = [] }) @@ -35,7 +35,7 @@ resource "nubes_postgres" "npg" { backup_configuration = jsonencode({ s3Uid = var.s3_uid - retain = "7" + retain = "14" schedule = "0 0 * * *" }) @@ -57,10 +57,4 @@ resource "nubes_postgres_user" "pg_user" { adopt_existing_on_create = true } -resource "nubes_postgres_database" "db2_app" { - postgres_id = nubes_postgres.npg.id - db_name = "dbterra" - db_owner = nubes_postgres_user.pg_user.username - adopt_existing_on_create = true -} diff --git a/TOOLS/config/test/profile.env b/TOOLS/config/test/profile.env index 87f0b70..da033c4 100644 --- a/TOOLS/config/test/profile.env +++ b/TOOLS/config/test/profile.env @@ -3,7 +3,7 @@ NUBES_API_ENDPOINT="https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" TOKEN_FILE="secrets/test.token" # Version -VERSION="5.0.61" +VERSION="5.0.62" # Docs generation — ONLY from docs_gen// (never from docs/) DOCS_GEN_DIR="provider/docs_gen/test" diff --git a/provider/internal/resources_core/crud.go b/provider/internal/resources_core/crud.go index 992a425..56a486e 100644 --- a/provider/internal/resources_core/crud.go +++ b/provider/internal/resources_core/crud.go @@ -55,7 +55,7 @@ func UpdateResourceWithTimeout(ctx context.Context, client *core.UniversalClient if err != nil { return err } - return client.RunInstanceOperationUniversalWithDefaults(ctxWithTimeout, instanceID, "modify", params) + return client.RunInstanceOperationUniversal(ctxWithTimeout, instanceID, "modify", params) } // DeleteResource runs destroy behavior (suspend/state-only) for instance resources. diff --git a/provider/main.go b/provider/main.go index 56854cb..b88e3eb 100644 --- a/provider/main.go +++ b/provider/main.go @@ -17,7 +17,7 @@ import ( ) var ( - version string = "5.0.61" + version string = "5.0.62" ) func main() {