diff --git a/NOTES/30_analysis/HAR_FRESH_CREATE_2026-09-24.md b/NOTES/30_analysis/HAR_FRESH_CREATE_2026-09-24.md new file mode 100644 index 0000000..ecfe9a0 --- /dev/null +++ b/NOTES/30_analysis/HAR_FRESH_CREATE_2026-09-24.md @@ -0,0 +1,78 @@ +# HAR fresh-create: что происходит при создании орги/эджа (dev, 2026-09-24) + +> Источники: `HAR/globak.har` (ЛК: создание орги + vDC + эджа, затем два modify), +> `HAR/org_already exists.har` (отказ создания орги из-за коллизии имени). +> Стенд: `lk-api-gateway-dev.ngcloud.ru`, realm `sandbox.nubes.ru`. +> Цель разбора: понять, что реально приходит в `state.params` после `create` +> (влияет на read-back в сгенерированных ресурсах). + +## 1. Поток создания в ЛК + +Инстанс создаётся **в два шага**, не одним запросом: + +1. `POST /instances` — тело **только** `{"serviceId":N,"displayName":"…","descr":""}`. Никаких параметров. +2. `POST /instanceOperations` — `{"instanceUid":"…","operation":"create"}` → возвращает `instanceOperationUid`. +3. `POST /instanceOperationCfsParams` — по одному запросу на параметр: `{"paramValue":"…","instanceOperationUid":"…","svcOperationCfsParamId":NNN}`. +4. `GET /instanceOperations/{opUid}/validate-cfs`. +5. `POST /instanceOperations/{opUid}/run`. +6. Поллинг `GET /instanceOperations/{opUid}` до `dtFinish`. + +Это в точности тот же набор эндпоинтов, что использует наш провайдер (`core/operation_run.go`, `operation_cfs.go`). + +## 2. Параметры операций (из HAR) + +| Сервис | Операция | Параметры | +|---|---|---| +| Орга (19) | create | `418 resourceRealm=sandbox.nubes.ru`, `556 organizationType`, `1125 orgSuffix` | +| vDC (21) | create | `30`, `746`, `335`, `397`, `557`, `558`, `361` (+ `8` = uid орги) | +| Эдж / vc_nsxt (22) | create | `621 vdcType=vdc`, `8 vdcUid`, `622`, `340 needEnableAVI`, `341 virtualServicesCount`, `825 qosProfile`, `1110 routedNetConfiguration` | +| Орга (19) | modify (207) | `662 vIPConfigure = [{"name":"internet-ipv4-v1","count":"3"}]` | +| Эдж (22) | modify (111) | `368 needEnableAVI`, `369 virtualServicesCount=4`, `856 qosProfile`, **`372 ipSpaceName=internet-ipv4-v1`**, `1112 routedNetConfiguration` | + +`372 ipSpaceName` **не участвует в create** — только в modify. Ровно как в нашем `Update` +(`22_vc_nsxt_resource.go`), который шлёт 368/369/372/856/1112. + +## 3. `state.params` до и после modify + +Ответ `GET /instances/{uid}`: параметры лежат в **`instance.state.params`** +(`instance.params` = `null`). Наш `GetInstanceStateParams` (`core/instance_params.go:35-45`) +читает именно этот путь — то есть read-back их видит. + +| Инстанс | Сразу после create | После modify | +|---|---|---| +| Орга `df5ec5f2…` («kontra») | `{"admins":[], "vIPConfigure":[{}], "resourceRealm":"sandbox.nubes.ru", "organizationType":"saas"}` | `vIPConfigure=[{"name":"internet-ipv4-v1","count":"3"}]`, state version 3 → 4 | +| Эдж `ad0ab577…` («tedj») | `vdcUid`, `vdcType`, `qosProfile="QoS-100Mbit"`, `vdcGroupUid=""`, `needEnableAVI=true`, `virtualServicesCount="1"`, `routedNetConfiguration` — **ключа `ipSpaceName` НЕТ** | `ipSpaceName="internet-ipv4-v1"`, `virtualServicesCount="4"`, version 1 → 2 | + +Ключевое: у орги `vIPConfigure` **присутствует и равен `[{}]`** (пустой элемент); +у эджа `ipSpaceName` **отсутствует** до первого modify. + +## 4. Провал операции приходит внутри тела, а не HTTP-кодом + +`HAR/org_already exists.har`: создание орги с `organizationType=iaas` и `orgSuffix=suff`: + +- `POST /instances` → 201, `POST /instanceOperations` → 201, `validate-cfs` → 204, `run` → 201; +- финальный `GET /instanceOperations/{opUid}`: `submitResult="201"`, `isSuccessful=false`, + `errorLog="Организация с именем 'WZ03709-iaas' уже существует в рамках ресурсной платформы sandbox.nubes.ru"`. + +Вывод: **ошибку операции нужно читать из `errorLog`/`isSuccessful`** поллинга; HTTP-код ничего не скажет. + +Дополнительно: имя орги формируется как `-<тип>` (`WZ03709-iaas` / `WZ03709-saas`), +то есть в одном realm — по одной орге каждого типа; повтор даёт ту же ошибку. + +## 5. Выводы для нашего провайдера + +1. `nubes_vc_org.v_ip_configure` — **Required** в схеме (generator мержит create+modify, `loader.go:96`), + но при `Create` не отправляется, а read-back после create вернёт `[{}]` вместо планового значения + → риск `Provider produced inconsistent result after apply` на создании орги. **Прогоном не проверено.** +2. `nubes_vc_nsxt.ip_space_name` — Optional+Computed: при create ключа в state нет, значение сохраняется + в state, но **SNAT не включается**; включается только следующим `apply` (Update → 372). **Прогоном не проверено.** +3. `RefreshResourceState` (`resources_core/state_refresh.go`) перезаписывает поля из `state.params`; + для modify-only параметров это поведение опасное — в create его включать не следует (универсальная правка генератора). +4. Из п.1–2 следует, что одной правкой «добавить два ресурса-модификатора» инцидент может не закрыться: + схема `nubes_vc_org` останется с Required-полем. + +## 6. Ограничения разбора + +- `apply`/`plan` не запускались: пункты 1–2 — вывод из кода + HAR, не подтверждены живым прогоном. +- Проверено на одном стенде (dev), одной орге (`NarodOrg` — во втором HAR имя `WZ03709-iaas` уже занято). +- `qosProfile` в create ЛК отправляет пустым, после modify в state = `QoS-100Mbit`.