From c808a3b345ecb1cd92394b43e443a4d43872e84c Mon Sep 17 00:00:00 2001 From: Nail Date: Thu, 24 Sep 2026 20:53:17 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=87=D0=B8=D1=82=D0=B0=D0=B5=D0=BC=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20provider-behavior.md=20(=D1=83=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=89=D0=B5=D0=BD=D1=8B=20=C2=A71=20=D1=81=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=BA=D0=BE=D0=BC,=20=C2=A72=20=D0=BC=D0=BE=D0=B4=D0=B8?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D0=B0=D1=82=D0=BE=D1=80=D1=8B,=20=C2=A73=20i?= =?UTF-8?q?d/=D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F,=20=C2=A75=20=D0=BF=D1=80=D0=B8=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D1=82=20=D1=84=D0=BB=D0=B0=D0=B3=D0=BE=D0=B2,=20?= =?UTF-8?q?=C2=A76=20ALB-=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=82?= =?UTF-8?q?=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/30_registry/guides/provider-behavior.md | 37 ++++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/docs/30_registry/guides/provider-behavior.md b/docs/30_registry/guides/provider-behavior.md index 5784a51..7ce696c 100644 --- a/docs/30_registry/guides/provider-behavior.md +++ b/docs/30_registry/guides/provider-behavior.md @@ -8,29 +8,34 @@ Провайдер Nubes — это не плагин к гипервизору, а **обёртка над API личного кабинета**: каждый Terraform-ресурс соответствует *инстансу услуги* в облаке, а `create` / `update` / `delete` транслируются в **асинхронные операции** -платформы (`create`, `modify`, `suspend`, `resume`, `delete`). Отсюда все отличия: долгие операции с поллингом, -изменение вместо пересоздания, ошибки внутри тела ответа, идентичность ресурса по имени и возможность -«мягкого» удаления. +платформы (`create`, `modify`, `suspend`, `resume`, `delete`). Отсюда и все отличия от привычного Terraform: + +- операции **долгие** — провайдер ждёт их завершения (поллинг); +- меняется **уже созданный объект**, а не создаётся заново; +- ошибки приходят **внутри тела ответа**, а не HTTP-кодом; +- ресурс ищется **по имени**, а не только по `id`; +- удаление может быть **«мягким»** — объект остаётся в облаке. ## 2. Какие ресурсы за что отвечают | Услуга облака | Ресурс Terraform | Что делает | |---|---|---| -| Организация в Cloud Director (19) | `nubes_vc_org_ip_allocation` | **модификатор**: меняет квоту внешних IP в уже существующей организации (саму организацию создают в ЛК) | +| Организация в Cloud Director (19) | `nubes_vc_org_ip_allocation` | **модификатор**: меняет квоту внешних IP в организации (саму организацию создают в ЛК, Terraform её не трогает) | | Виртуальный датацентр (21) | `nubes_vc_vdc` | создаёт vDC с ресурсами (CPU/RAM/Storage) | | Сетевой шлюз периметра (22) | `nubes_vc_nsxt` | создаёт Edge (routed-сеть, ALB/AVI) | | Сетевой шлюз периметра (22) | `nubes_vc_nsxt_snat` | **модификатор**: включает/переключает SNAT (`ipSpaceName`) на существующем Edge | | Kubernetes кластер Штурвал (150) | `nubes_k8s_sthutrval_cluster` | создаёт кластер (control plane + группы воркеров) | -Общее правило: **создаёт** только «инстансный» ресурс услуги, а всё остальное, что делается операцией `modify` -(квота IP, SNAT, свойства шлюза), — это отдельные ресурсы-модификаторы со своим жизненным циклом. +Общее правило. Ресурс, у которого есть свой «объект в облаке», **создаёт** этот объект. А то, что платформа +меняет операцией `modify` (квота IP, включение SNAT, настройки шлюза), собрано в отдельные ресурсы- +**модификаторы**: они не создают ничего нового, а правят уже существующий объект. ## 3. Отличия от «учебного» Terraform | Ожидание по канону | Как в Nubes | Причина | |---|---|---| | `create` = один вызов API | Создание инстанса — **последовательность**: `POST /instances` → `POST /instanceOperations` → параметры (`instanceOperationCfsParams`) → `run` → поллинг до `dtFinish` | Так устроен API платформы | -| `id` — произвольная строка | `id` = UUID инстанса в облаке; чтение — из `instance.state.params` / `state.out` | Состояние живёт в облаке, не в Terraform | +| `id` — произвольная строка | `id` = UUID инстанса в облаке; провайдер читает его из ответа платформы | Состояние живёт в облаке, не в Terraform | | `update` = замена при несовместимых параметрах | `update` = операция **`modify`** над тем же инстансом; часть параметров — **create-only** (менять нельзя → ошибка на этапе plan) | Платформа не пересоздаёт объекты «из коробки» | | есть `data sources` для поиска существующего | Поиск/ссылки — через **ref-параметры**: можно указать UUID **или имя** инстанса | Экономит data sources, но требует дисциплины в значениях | | `import` — явная команда | Плюс к `import` есть **авто-усыновление** `adopt_existing_on_create = true`: ресурс сам находит инстанс **по имени** | В проде объекты живут неделями, и пересоздавать их нельзя | @@ -38,7 +43,7 @@ | `delete` удаляет | `delete` может быть `delete` / `suspend` / `state_only` — см. §5 | У платформы не всё удаляется, а часть объектов удалять нельзя, пока жив потребитель | | ошибка приходит HTTP-кодом | Ошибка операции — **в теле**: `isSuccessful=false` + `errorLog`, при успешном HTTP-коде | API платформы отвечает 200/201 почти всегда | | операции быстрые | Операции асинхронные и долгие (Штурвал — десятки минут) → параметр `operation_timeout`; одновременные операции на одном инстансе не поддерживаются | Наследство платформы (внутри — CFS-оркестратор) | -| план обязан совпадать с config | Тоже, но с оговоркой: **ref-параметры в плане не нормализуются** (нельзя подменить `name` → `uuid`), нормализация только перед вызовом API | Иначе Terraform упадёт с «Provider produced invalid plan» | +| план обязан совпадать с config | Тоже, но: **ref-параметры в плане остаются как написаны** (`name` не подменяется на `uuid`), а уже перед вызовом API провайдер сам разберётся, имя это или UUID | Иначе Terraform упадёт с «Provider produced invalid plan» | | параметры сравниваются как строки | JSON-параметры сравниваются **канонично**: порядок ключей и пробелы не важны, скаляры приводятся к строке, UUID — без учёта регистра | API возвращает JSON в своём виде, иначе будет «вечный diff» | | идентичность — по `id` | Дополнительно: инстанс ищется по `resource_name` (displayName) → **переименование = новый ресурс** | Имя задаётся при создании и не меняется | @@ -70,11 +75,12 @@ | Флаг | Где применим | Поведение при `destroy` | Предупреждение в выводе | |---|---|---|---| | `suspend_on_destroy = true` | кластер Штурвала, vDC (по умолчанию `true`) | объект **приостанавливается**, не удаляется | «Ресурс заморожен, а не удалён» | -| `keep_on_destroy = true` | Edge, SNAT, квота IP (по умолчанию `false`) | объект **не трогается в облаке**, только убирается из state | «Ресурс оставлен как есть, а не удалён» / «SNAT не выключался» / «Аллокация IP не снималась» | +| `keep_on_destroy = true` | Edge, SNAT, квота IP (по умолчанию `false`) | объект **не трогается в облаке**, только убирается из state | «Оставлен как есть» (для SNAT — «SNAT не выключался», для квоты IP — «Аллокация IP не снималась») | | оба `false` | любой | обычное удаление | — | -Приоритет: `keep_on_destroy` важнее `suspend_on_destroy`. Дефолты провайдера — **разрушающие** -(`keep_on_destroy = false`), «заморозку» включают явно в конфигурации стенда. +Если выставлены оба флага, победит `keep_on_destroy` (объект просто не тронут). По умолчанию провайдер +удаляет по-настоящему (`keep_on_destroy = false`), а «заморозку» или «оставить как есть» включают явно +в конфигурации стенда. ### Почему Edge остаётся `running` @@ -117,7 +123,8 @@ Edge **физически не умеет `suspend`**: в списке дост 1. Организация — **вручную в ЛК** (Terraform её не создаёт). 2. `nubes_vc_vdc` — виртуальный датацентр. -3. `nubes_vc_nsxt` — Edge; обязательно с ALB (`need_enable_avi = true`) и `virtual_services_count >= 3`. +3. `nubes_vc_nsxt` — Edge. Обязательно включать балансировщик (параметр `need_enable_avi = true`) + и задать не меньше 3 виртуальных сервисов (`virtual_services_count >= 3`) — это нужно кластеру Штурвала. 4. `nubes_vc_org_ip_allocation` — внешние адреса в организации (минимум 3 по инструкции услуги Штурвала). 5. `nubes_vc_nsxt_snat` — SNAT на Edge (по `depends_on` после аллокации адресов). 6. `nubes_k8s_sthutrval_cluster` — кластер Штурвала (по `depends_on` после SNAT: нодам нужен выход в интернет). @@ -129,9 +136,9 @@ Edge **физически не умеет `suspend`**: в списке дост - Edge не удаляется при живых зависимых объектах (по инструкции услуги). - Квота IP не опускается ниже занятых адресов (см. §5). -Практическая проверка корректности конфигурации: `terraform plan` после `apply` должен говорить -`No changes`. Если появляется стабильный diff — сравнивайте не «на глаз», а по `terraform state show` -и состоянию инстанса в ЛК. +Как проверить, что конфигурация корректна: `terraform plan` после `apply` должен говорить +`No changes`. Если появляется стабильный diff — сверяйте его с `terraform state show` и с тем, +что реально показывается в личном кабинете. ## 7. Регистр UUID и канонизация значений