chore: save current changes

This commit is contained in:
Repinoid
2026-09-24 07:25:27 +03:00
parent a96e38fb1e
commit d93ff66482
7 changed files with 243 additions and 22 deletions
+199
View File
@@ -0,0 +1,199 @@
# CHAT RESUME: IaC-развёртывание Штурвала — состояние на 2026-09-24
> **Кому:** новый чат / новый участник. Читать целиком, это хендовер.
> **Что это:** сводка длинной сессии (2026-09-23/24) по вопросу «как дать клиенту IaC для цепочки Штурвал».
> **Статус:** решение НЕ принято, код НЕ написан. Есть анализ, проверенные факты и развилка.
---
## 0. TL;DR (одним абзацем)
Клиенту нужен **настоящий IaC**: один конфиг + `terraform apply` = вся инфраструктура. Цепочка Штурвала
(`vcOrg → vcVdc → vcNsxt → [modify оргов/эдж] → k8sShturval`) упирается в две операции `modify`, которые
провайдер сейчас выразить не может: в схеме tf-ресурса их параметров нет (схема строится только из `create`).
Ручной ЛК и скрипт **отклонены** — это не IaC. Единственный каноничный путь — **отдельные tf-ресурсы под
модификации** (как сделано в провайдере VMware Cloud Director, прецедент в папке `!/`),
плюс желательно, чтобы платформа отдавала через API выводимые значения (`ipSpaceName`), которые юзер знать не может.
Часть прежних «блокеров» оказалась **ложной** — см. §7, это критично.
---
## 1. Задача
Развернуть Штурвал (k8s) целиком через Terraform, с корректным `apply`/`plan`/`destroy`:
```
vcOrg -> create (в нашем случае орг уже создана вручную и НЕ в state)
vcVdc -> create
vcNsxt -> create (Edge)
------------------------------
vcOrg -> modify (аллокация внешних IP: vIPConfigure)
vcNsxt -> modify (включить SNAT, указать внешний IP из vcOrg: ipSpaceName)
------------------------------
k8sShturval -> create
```
Операции строго последовательны. Проблема: между `nsxt.create` и `shturval.create` стоят два `modify`,
которые в один tf-ресурс не укладываются.
---
## 2. Позиции участников (Telegram 2026-09-23)
| Кто | Позиция |
|---|---|
| **Владимир (наш)** | Пытается сделать всё терраформом. `create` — ок, `modify` — «просто так не получится, надо создавать дополнительные ресурсы-модификаторы». Сомневался: может, руками в ЛК или скриптом. |
| **Георгий** | **Основной запрос клиента — IaC.** Ручной ЛК/скрипт «совсем не подойдёт». Правильно указал порядок: сначала nsxt, потом квота на оргу. |
| **Дмитрий** | Хочет «terraform apply одного ямлика со всей инфрой — и всё». Спрашивал, как это реализовано в провайдере Cloud Director из провайдерской УЗ. |
| **Виталий** | Дал 3 tf-файла (`vmware_org.tf`, `vdc.tf`, `network.tf.tmpl`) — **официальный провайдер Cloud Director**. Ключевое: `ipSpace → providerGateway → providerVdc` (цепочка, которую юзер не знает), «квоту делаем через API на оргу, т.к. эджей много, а орга одна», «при создании параметры подкладываются», «в организации один T0». |
---
## 3. Подтверждённые факты (с источниками)
1. **Схема tf-ресурса строится ТОЛЬКО из `create`** (генератор `TOOLS/resource-generator`).
→ modify-only параметры в схему не попадают.
2. **`vIPConfigure`** (vc_org, modify id **207**, param id **662**, `array-map-fixed`, sub: `name`=39, `count`=40)
есть **только** в modify. В `create` (id 136) — только `resourceRealm`(418), `organizationType`(556), `orgSuffix`(1125).
Файл: `generated/dev/resources_yaml/19_vc_org.yaml`.
3. **`ipSpaceName`** (vc_nsxt, modify id **111**, param id **372**, string, required false) есть **только** в modify.
В `create` (id 10) — `vdcUid`, `needEnableAVI`(340), `virtualServicesCount`(341), `qosProfile`(825), `routedNetConfiguration`(1110).
Файл: `generated/dev/resources_yaml/22_vc_nsxt.yaml`.
4. **`vIPConfigure` — replace-семантика, НЕ накопительная.** Повторный modify с тем же count не задваивает (1→1),
работает вверх/вниз/до 0, `count=0` принимается (несмотря на `minvalue:1`), live читается из `state.params`.
Источник: `docs/ORG_IP_MODIFIER_TEST_2026-09-22.md` (проверено на стенде DEV_STAND/FullPipe, провайдер 2.0.9).
5. **`ipSpaceName` — выводимое значение:** цепочка `providerVdc → providerGateway → ipSpace`, юзер его не знает.
Платформа сейчас «подкладывает» недостающие параметры при создании пустой орги. Список доступных ipSpace
в статической выгрузке (`/instanceOperations/default/{id}`) — пустой, виден только в ЛК/живом инстансе. (Виталий + форензика)
6. **Допущение платформы: в организации один T0/провайдер-шлюз.** Рост T0 отложен, но при нём схема сломается.
7. **Доступ к значению modify-параметра:** live берётся из `GET /instances/{uid}` → `state.params`,
а НЕ из `cfsParams.paramValue` (это сохранённый дефолт формы от прошлых прогонов, см. `dtCreated` в HAR).
8. **Flow modify (HAR `org_enough_.har`):** `POST /instanceOperations {instanceUid, operation:"modify"}` →
`POST /instanceOperationCfsParams {paramValue, instanceOperationUid, svcOperationCfsParamId}` →
`POST /instanceOperations/{opUid}/validate-cfs` → `POST /instanceOperations/{opUid}/run`.
9. **Прецедент (VCD, папка `!/`):** та же цепочка делается **отдельными ресурсами** с `depends_on`:
`vcd_nsxt_alb_settings` (`count = var.alb_enable ? 1 : 0`), `vcd_nsxt_alb_edgegateway_service_engine_group`
(`reserved_virtual_services`), `vcd_network_routed_v2`, `vcd_ip_space_custom_quota` (на оргу).
Приём «включено/выключено» = существование ресурса; **inverse = удаление ресурса**.
10. **Nubes — надстройка над Cloud Director.** Наши `vcOrg`/`vcVdc`/`vcNsxt` создают объекты в VCD.
Провайдер Nubes — обёртка над API Nubes, отдельный от официального `terraform-provider-vcd`.
---
## 4. Почему «просто добавить поле» / «насильно в state» / «скрипт» — не работает
- **Добавить поле в .tf** → падает на `plan`: атрибута нет в схеме (см. §3.1).
- **Terraform не может внутри одного ресурса** сделать «create → через N шагов modify».
Декларативный Update требует **желаемого состояния**; `ipSpaceName` — это включение SNAT, а не значение поля.
- **Вписать в tfstate** нельзя: state валидируется по схеме провайдера, а «записанное» состояние ≠ реальность
(получишь чистый `plan` при сломанной инфраструктуре). `null_resource`/`terraform_data` + `local-exec` даёт
только **факт** выполнения, не состояние.
- **Ручной ЛК / скрипт вне tf** — отклонено: это не IaC (нет версионирования, воспроизводимости, дрейфа, отката).
- **Правка провайдера «по-старому»** (метки `kind: modifier` в YAML + реестр в `yaml-generator`) — **отменённый заход**,
см. §7.
---
## 5. Каноничное решение (что делать)
**Два независимых требования — нужны оба:**
1. **Отдельные tf-ресурсы под `modify`** (наша сторона): e.g. `nubes_org_ip_allocation` (vIPConfigure),
`nubes_nsxt_network` (`needEnableAVI`/`virtualServicesCount`/`ipSpaceName`/`routedNetConfiguration`),
привязка через `depends_on` к орге/эджу.
- `Read` = читать родителя (`state.params`), `Delete` = обратный modify (`count=0` / `needEnableAVI=false` /
`ipSpaceName="no-needed"`), `Create/Update` = `modify` с параметрами.
2. **Доступ к выводимым значениям через API** (сторона платформы): динамические `valueList` + цепочка
`providerVdc → providerGateway → ipSpace`. Иначе юзер подсматривает в ЛК (ручной ввод как временный долг допустим,
но поле надо делать `Optional+Computed`, чтобы позже включить автоподстановку без breaking change).
**Дизайн-требования, заложить сразу:**
- `ip_space_name` → `Optional + Computed`;
- optional селектор шлюза (`t0_id` / `provider_gateway`) — чтобы рост T0 не сломал схему;
- не тащить доменные метки в универсальный YAML (см. §7).
---
## 6. Что можно делать уже сейчас, не дожидаясь платформы
- **`vIPConfigure` (аллокация IP на оргу) — можно делать начисто**: блокеров нет, replace-семантика подтверждена тестом,
Read/Delete выражаются через `state.params` и `count=0`.
- **`needEnableAVI` / `virtualServicesCount`** — выразимы (есть и в create, и в modify).
- **`ipSpaceName`** — единственное, что упирается в платформу; временно — ввод юзером (значение он и так смотрит в ЛК).
- **`routedNetConfiguration`** — есть в create (1110) и modify (1112), выразимо.
**Не решено (требует решения до кода):**
- откуда генератор берёт **список** доменных ресурсов (это не данные API, а доменное знание — то самое место,
где раньше был реестр в `yaml-generator`). Форму выбрать осознанно: явный список vs отдельный вход.
- какие шаги вообще остаются на **провайдерском** (облачном) уровне, а какие отдаются тенанту
(квота ipSpace / ALB — возможно, это уровень облака, и тогда в клиентский tf они не входят).
---
## 7. ⚠️ Исправленные ошибки (НЕ повторять!)
1. **Ложный факт «`vIPConfigure` накопительный».** Был протащен в промпт для Opus как «подтверждённый», из-за чего
Opus построил вывод «накопительный API несовместим с декларативной моделью» и объявил два «блокера»
(Read счётчика, адресное освобождение). **Оба ложны** — тест `ORG_IP_MODIFIER_TEST_2026-09-22.md` доказывает
идемпотентность и работу в обе стороны. Документы исправлены.
2. **Прежняя repo-память (`modifier-gotchas.md`) содержала устаревшие утверждения** (эпоха 09-21/22):
`kind: modifier`, `delete_strategy`, `nubes_vc_nsxt_network`, «у vc_nsxt нет instance-modify»,
«Update = no-op». **Файл перезаписан** актуальными фактами. НЕ использовать старую формулировку.
3. **Старые «модификаторы» были написаны и даже работали** (09-22), но заход признан негодным:
доменную логику вшили в универсальный генератор (метки в YAML). Соответствующие документы помечены баннером LEGACY.
---
## 8. Карта файлов
**АКТУАЛЬНО (источник истины):**
- `docs/CHAT_RESUME_IAC_2026-09-24.md` ← этот файл
- `docs/SHTURVAL_IAC_MODIFY_ANALYSIS_2026-09-23.md` — анализ, варианты A–E, мнение
- `docs/OPUS_ANSWER_IAC_SHTURVAL_MODIFY_2026-09-23.md` — ответ Opus + поправки (ложные блокеры сняты)
- `docs/ORG_IP_MODIFIER_TEST_2026-09-22.md` — проверенные факты по vIPConfigure
- `docs/prompts/prompt_for_opus_iac_shturval_modify.md` — промпт (факты исправлены)
- `generated/dev/resources_yaml/19_vc_org.yaml`, `22_vc_nsxt.yaml` — спеки (факты по операциям/параметрам)
- `HAR/org_enough_.har`, `HAR/org2.har`, `HAR/edge_.har` — live-семантика modify
- `!/` — прецедент Cloud Director (3 файла `vcd_*`), НЕ наш код
**LEGACY (история, НЕ источник истины):**
- `PLAN_modifier_redesign.md` ⛔ (баннер добавлен)
- `docs/60_strategy/modifier_resources_ideology_and_specification.md` ⛔ (баннер добавлен)
- `docs/inverse_rollback_analysis_2026-09-23.md`
- `prompt_for_opus_modifier_global_architecture.md`, `prompt_for_opus_modifier_review_2.md` (корень)
- `docs/prompts/prompt_for_opus_modifier_*.md`, `docs/prompts/prompt_for_opus_modifiable_architecture.md`
- `HISTORY/OPUS/2026-09-22_modifier_*.md`
- `PLAN_regenerate_providers_0.0.1.md` — перекрыт `PLAN_FLASH_reversion_cleanup.md` (0.0.1 объявлен легаси)
> Примечание: `docs/ORG_IP_MODIFIER_TEST_2026-09-22.md` — **актуален** (это отчёт по проверке, не план).
**Инфра-контекст:**
- `TOOLS/config/<стенд>/profile.env` → `NUBES_API_ENDPOINT`, `TOKEN_FILE`
- `VERSIONS.md` — залитые версии (DEV на 09-22 = 2.0.13; в `generated/dev/provider_build/` лежат 2.0.17 — расхождение)
---
## 9. Развилка (ждёт решения)
| Вариант | Суть | Вердикт |
|---|---|---|
| **A** | Отдельные tf-ресурсы под modify (+ позже data-source для ipSpace) | канон; реализуемо сейчас для `vIPConfigure` |
| **B** | То же, но значения вводит юзер вручную | приемлемый временный долг при `Optional+Computed` |
| **C** | Ждать новых спеков платформы | часть работ всё равно можно начать сейчас |
| **D** | Ручной ЛК / скрипт вне tf | ❌ отклонено (требование IaC) |
| **E** | Пресеты/дефолтное окружение | снижает боль на старте, IaC не заменяет |
**Не принято:** делать ли `modify`-ресурсы доменными «руками» (и как их перечислять в генераторе) —
вопрос архитектуры; и что из шагов остаётся за облаком.
---
## 10. Открытые вопросы к людям
1. **Георгию/продукту:** какие шаги цепочки — тенантские, а какие — уровень облака (квота ipSpace, ALB)?
От этого зависит объём ресурсов в клиентском tf.
2. **Виталию (платформа):** можете отдавать через API (а) динамические списки значений (`ipSpace`),
(б) цепочку `providerVdc → providerGateway → ipSpace`?
3. **Виталию:** файлы `!/` — ваш инструмент провижининга от провайдерской УЗ или справочный пример?
(в диалоге он сказал только «это провайдер от клауд директора»)
4. **Команде:** откуда генератор берёт список доменных ресурсов-модификаций (форма решения, без меток в YAML).