156 lines
13 KiB
Markdown
156 lines
13 KiB
Markdown
# Резюме сессии: VDC create-flow, диалог с Opus и правка fallback (2026-09-21)
|
||
|
||
## 1. Контекст задачи
|
||
- Цель: довести до рабочего состояния создание `nubes_vc_vdc` в `FullPipe`.
|
||
- Симптом: при создании VDC провайдер падал на `GET /instanceOperations/{opUid}?fields=cfsParams` с HTTP 500.
|
||
- В ходе разбора было подтверждено, что обычные сервисы через тот же провайдер работали, а VDC попадал в отдельную проблемную ветку backend-обработки.
|
||
|
||
---
|
||
|
||
## 2. Диагностика проблемы
|
||
|
||
### 2.1. Что ломалось
|
||
- В `provider/internal/core/client.go` create-flow делал `GET /instanceOperations/{opUid}?fields=cfsParams` сразу после создания операции.
|
||
- Для VDC этот запрос приводил к ошибке backend’а:
|
||
- `Invalid call of the function [getResourceRealmConfig]`
|
||
- `Cannot cast Object type [Struct] to a value of type [string]`
|
||
- источник ошибки: `/app/api/v1/resources/instance_operation_cfs_param.cfc`
|
||
- Причина по отчету: для `vc_vdc` вычислялся динамический `descr` у `storageConfig.name`, и backend падал на `resourceRealm`, который в DEV хранится как `Struct`, а не `string`.
|
||
|
||
### 2.2. Почему обычные сервисы не ломались
|
||
- На обычных сервисах этот `GET` либо не попадал в проблемный backend-код, либо не требовал вычисления `resourceRealm`.
|
||
- Для VDC в YAML есть специфическая зависимость:
|
||
- `generated/dev/resources_yaml/21_vc_vdc.yaml`
|
||
- `storageConfig.name` содержит вычисляемый `descr` с `getResourceRealmConfig(...resourceRealm...)`.
|
||
- Для обычных сервисов, например `vapp` и `postgres`, такого вычисляемого `resourceRealm`-контекста нет.
|
||
|
||
### 2.3. Почему `hasUnresolvedParams` мешал
|
||
- Эвристика проверяла **все** строковые параметры, а не только параметры с `ref_svc_id`.
|
||
- Для VDC это ломало fallback на обычных литералах вроде:
|
||
- `providerVdc = fast-2.8`
|
||
- `networkProvider = default`
|
||
- Эти значения не UUID и не JSON, но и резолвить их не нужно.
|
||
- В результате при падении GET провайдер вместо продолжения переходил в ошибку.
|
||
|
||
---
|
||
|
||
## 3. Диалог с Opus
|
||
|
||
### 3.1. Что просили у Opus
|
||
- Проверить только:
|
||
- `provider/internal/core/client.go`
|
||
- `docs/DEBUG_REPORT_VC_VDC_500.md`
|
||
- `generated/dev/resources_yaml/21_vc_vdc.yaml`
|
||
- `generated/dev/resources_yaml/26_vapp.yaml`
|
||
- `generated/dev/resources_yaml/90_postgres.yaml`
|
||
- Вопросы к Opus были узкими:
|
||
1. почему обычные сервисы работали, а VDC начал падать на `GET ?fields=cfsParams`
|
||
2. есть ли в VDC специфическая структура или зависимость, которой нет у обычных сервисов
|
||
3. является ли `hasUnresolvedParams` неверной эвристикой именно в этом месте
|
||
4. что именно надо исправить
|
||
|
||
### 3.2. Что ответил Opus по сути
|
||
- Root cause — не данные Terraform и не сами строки `fast-2.8` / `default`, а backend-ошибка на `GET /instanceOperations/{opUid}?fields=cfsParams` именно для VDC.
|
||
- VDC отличается от обычных сервисов тем, что в его YAML есть динамический `descr` для `storageConfig.name`, который тянет `resourceRealm`.
|
||
- `hasUnresolvedParams` была признана лишней и хрупкой эвристикой: она может ломать fallback на обычных строках.
|
||
- Итоговое решение Opus: при ошибке GET идти дальше по браузерному flow, без условий по всем строковым параметрам.
|
||
|
||
### 3.3. Дополнительные уточнения в диалоге
|
||
- Был отдельный спор по формулировке про Lucee / ColdFusion backend.
|
||
- В итоге было зафиксировано, что этот термин — не отдельная гипотеза, а просто обозначение backend-слоя, который уже фигурировал в отчетах и traceback’ах.
|
||
- Opus также подтвердил, что для VDC этот GET нужен только как вспомогательный шаг для `resolveRefSvcParamValues`, а не как обязательный бизнес-этап.
|
||
|
||
---
|
||
|
||
## 4. Что изменили в коде
|
||
|
||
### 4.1. `provider/internal/core/client.go`
|
||
- В `CreateGenericInstanceUniversalV6` удалён gate по `hasUnresolvedParams`.
|
||
- Теперь логика такая:
|
||
- если `GET /instanceOperations/{opUid}?fields=cfsParams` успешен — парсим и резолвим `ref_svc_id`
|
||
- если GET падает — просто продолжаем POST’ить параметры, а потом идём в `validate-cfs` и `run`
|
||
- Функция `hasUnresolvedParams` удалена полностью.
|
||
- После удаления была убрана осиротевшая документационная строка, оставшаяся над `isHexDigit`.
|
||
|
||
### 4.2. `provider/internal/core/client_test.go`
|
||
- Добавлен тест:
|
||
- `TestCreateGenericInstanceUniversalV6_ContinuesWhenOpDetailsGETFails`
|
||
- Тест моделирует:
|
||
- `POST /instances`
|
||
- `POST /instanceOperations`
|
||
- `GET /instanceOperations/{opUid}?fields=cfsParams` → 500
|
||
- `POST /instanceOperationCfsParams`
|
||
- `GET /instanceOperations/{opUid}/validate-cfs`
|
||
- `POST /instanceOperations/{opUid}/run`
|
||
- финальный `GET /instances/{uid}`
|
||
- Проверка теста:
|
||
- create-flow завершился успешно
|
||
- все 7 параметров были отправлены с ожидаемыми значениями
|
||
- polling по операции был ровно один раз
|
||
|
||
---
|
||
|
||
## 5. Проверка после правки
|
||
- `cd /home/naeel/TF/tf_provider/provider && go test ./internal/core` — успешно.
|
||
- После ревью был пойман и исправлен только косметический хвост:
|
||
- старый комментарий над `isHexDigit`, оставшийся после удаления `hasUnresolvedParams`.
|
||
- После этого пакет `internal/core` снова прошёл тесты.
|
||
|
||
---
|
||
|
||
## 6. Вывод по итогам сессии
|
||
- Проблема была не в обычных сервисах как таковых, а в специфике VDC-данных и backend-пути, который срабатывал на `GET ?fields=cfsParams`.
|
||
- `hasUnresolvedParams` была неверной эвристикой именно в create-flow VDC и ломала рабочий fallback.
|
||
- Правильное поведение: если GET падает, не гадать по строковым параметрам, а продолжать browser-like flow через POST параметров, validate и run.
|
||
|
||
---
|
||
|
||
## 7. Что дальше
|
||
- Следующий этап — уже не правка логики, а публикация и стендовая проверка при необходимости.
|
||
- DEV-релиз `2.0.3` успешно собран и загружен в registry `nubes-dev` через `TOOLS/scripts/03_build_and_upload_provider.sh --profile TOOLS/config/dev`.
|
||
- Перед этим уже был подготовлен короткий запрос на ревью для Opus и получен ответ, который подтвердил направление правки.
|
||
|
||
---
|
||
|
||
## 8. Отдельный диалог про `organization_uid`, refSvcId и универсальное поведение
|
||
|
||
### 8.1. Что стало проблемой
|
||
- В `vc_vdc` поле `organization_uid` можно передавать как display name (`kontora`), так и как UUID организации.
|
||
- В коде `provider/internal/resources_gen/21_vc_vdc_resource.go` это поле сейчас резолвится через `ResolveRefSvcParamValue(...)` в UUID.
|
||
- После `apply` Terraform видит расхождение: в конфиге было имя, в state оказался UUID, и появляется ошибка `Provider produced inconsistent result after apply`.
|
||
- Параллельно в этом же ресурсе остаются ручные `EqualFold`-хаки, которые пытаются сохранить старое значение, но не решают кейс "имя vs UUID".
|
||
|
||
### 8.2. Почему это сравнивали с S3
|
||
- Для `nubes_s3_bucket` похожее поведение уже работает: ref-поле `s3_user_uid` проходит через общий механизм refSvc-резолва и state-refresh.
|
||
- В S3 есть симметричный путь: UUID можно принимать на вход, а состояние при чтении синхронизируется через общий mapping-слой.
|
||
- Поэтому S3 не падает на inconsistency, а VDC падает из-за локальных restore-хаков и разного поведения на create/read/update.
|
||
|
||
### 8.3. Что выяснили по коду
|
||
- Ключевой участок VDC:
|
||
- [provider/internal/resources_gen/21_vc_vdc_resource.go](provider/internal/resources_gen/21_vc_vdc_resource.go#L197-L202)
|
||
- [provider/internal/resources_gen/21_vc_vdc_resource.go](provider/internal/resources_gen/21_vc_vdc_resource.go#L323-L338)
|
||
- [provider/internal/resources_gen/21_vc_vdc_resource.go](provider/internal/resources_gen/21_vc_vdc_resource.go#L388-L403)
|
||
- [provider/internal/resources_gen/21_vc_vdc_resource.go](provider/internal/resources_gen/21_vc_vdc_resource.go#L511-L525)
|
||
- В S3 аналогичный слой устроен аккуратнее:
|
||
- [provider/internal/resources_gen/13_s3bucket_resource.go](provider/internal/resources_gen/13_s3bucket_resource.go#L149-L159)
|
||
- [provider/internal/resources_core/state_refresh.go](provider/internal/resources_core/state_refresh.go#L82-L96)
|
||
- [provider/internal/resources_core/params_ref_mapping.go](provider/internal/resources_core/params_ref_mapping.go#L124-L147)
|
||
|
||
### 8.4. Что решил сделать дальше
|
||
- Пользователю нужен не частный фикс только для VDC, а универсальная схема для всех refSvcId-полей.
|
||
- Была сформулирована задача для Opus: определить, какой канон выбрать для state, где делать name→UUID и UUID→display_name, и как убрать ручные `EqualFold`-хаки без поломки S3 и других уже рабочих ресурсов.
|
||
- Отдельно зафиксировано требование: ответ Opus нужен короткий, но сам вопрос должен быть подробным и однозначным.
|
||
|
||
### 8.5. Важный вывод на сейчас
|
||
- Универсальное решение пока не внедрено.
|
||
- Текущий безопасный путь — сначала получить короткий архитектурный ответ от Opus, а уже потом править генератор и пересобирать ресурсы.
|
||
|
||
---
|
||
|
||
## 9. Детерминированная пересборка генератора
|
||
|
||
- После отдельного разбора `kind: modifier` выяснилось, что падение генерации было эксплуатационным: запускался устаревший бинарник `resource-generator`, а не текущие исходники.
|
||
- В `TOOLS/scripts/02_generate_resources_and_docs_v2.sh` убран `mtime`-гард через `find ... -newer`; генераторы теперь всегда собираются заново перед прогоном.
|
||
- Это сделано специально, чтобы старый бинарник больше не мог скрыть поддержку новых `kind`-веток в YAML-спеках.
|
||
- Дополнительно `TOOLS/resource-generator/bin/` добавлен в ignore, чтобы локальный stale-артефакт не путал следующий запуск.
|