131 lines
6.4 KiB
Markdown
131 lines
6.4 KiB
Markdown
# 2026-07-06 — Архитектурный рефакторинг tf_provider
|
||
|
||
## Контекст
|
||
|
||
После анализа Claude Opus (`HISTORY/OPUS/2026-07-06_architectural_analysis.md`) выявлены архитектурные проблемы и выполнены исправления.
|
||
|
||
## Выполненные изменения
|
||
|
||
### 1. Реструктуризация проекта
|
||
|
||
```
|
||
Было: Стало:
|
||
devops/ TOOLS/scripts/ (все .sh)
|
||
devops/profiles/ TOOLS/config/ (profile.env, services_list, timeouts)
|
||
devops/ARCHITECTURE.md TOOLS/ARCHITECTURE.md
|
||
devops/config/ УДАЛЕНО (дубликат profiles)
|
||
provider/resources_yaml/ УДАЛЕНО (сгенерированное → generated/)
|
||
provider/internal/resources_gen/ УДАЛЕНО (сгенерированное → generated/)
|
||
generated/{test,prod,dev}/ (вывод пайплайна)
|
||
```
|
||
|
||
### 2. Независимость генераторов
|
||
|
||
- `yaml-generator` — требует `NUBES_OUTPUT_DIR`, без default в `provider/`
|
||
- `resource-generator` — требует `NUBES_RESOURCES_DIR` + `NUBES_RESOURCES_GEN_DIR`
|
||
- `docs-generator` — требует `--resources`, `--docs`, `--version` флаги
|
||
- Удалён `detectVersion()` — больше не читает `provider/main.go`
|
||
- Удалён `detectRoot()`, `pickPath()` — нет хардкод-путей
|
||
|
||
### 3. Общая библиотека типов
|
||
|
||
Создан `TOOLS/lib/` — единый YAML-контракт. Модуль: `tf-tools/lib`.
|
||
|
||
Подключены:
|
||
- `yaml-generator` → type alias `ParamSpec = lib.ParamSpec` и др.
|
||
- `resource-generator` → type alias `OutputParam`, `OperationSpec`, `ParamSpec`
|
||
|
||
НЕ подключён:
|
||
- `docs-generator` — будет заменён на LLM-генератор, не трогаем
|
||
|
||
При добавлении поля в YAML — править `lib/types.go`, несогласованность ловится компилятором.
|
||
|
||
### 4. Синхронизация версий
|
||
|
||
- `provider/main.go`: 5.0.75 → 5.0.60 (соответствует последней сборке)
|
||
- `profile.env`: три переменные → одна `VERSION`
|
||
- `03_build`, `04_publish`: `${PROVIDER_VERSION:-${RELEASE_VERSION:-}}` → `${VERSION}`
|
||
|
||
### 5. Автосборка бинарников
|
||
|
||
`01_generate_yamls.sh`: если исходники новее бинарника — пересборка.
|
||
|
||
### 6. Удалённый мусор
|
||
|
||
- `devops/config/` — дубликат profiles
|
||
- `02_generate_resources_and_docs.sh` + `_template.sh` — legacy, заменены v2
|
||
- `cloud-dashboard/`, `tools/` (root), `internal/` (root), `universal_rebuild/`
|
||
- 18 одноразовых файлов (check_ops.py, s.sh, ...)
|
||
|
||
### 7. Слияние ops-generator → docs-generator
|
||
|
||
`--ops` флаг. Три генератора вместо четырёх.
|
||
|
||
### 8. Документация LLM
|
||
|
||
`docs/LLM_DOCS_GENERATION.md` — подход, промпт, тест на Postgres (gpt-oss-120b, 9/10).
|
||
|
||
## Текущее состояние
|
||
|
||
```
|
||
tf_provider/
|
||
├── TOOLS/ — всё для генерации (код + скрипты + настройки)
|
||
│ ├── yaml-generator/
|
||
│ ├── resource-generator/
|
||
│ ├── docs-generator/
|
||
│ ├── lib/ — общие YAML-типы
|
||
│ ├── scripts/
|
||
│ ├── config/{test,prod,dev}/
|
||
│ └── ARCHITECTURE.md
|
||
├── provider/ — только исходники
|
||
├── generated/ — вывод пайплайна (gitignored)
|
||
└── docs/ — документация
|
||
```
|
||
|
||
## Осталось
|
||
|
||
- [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 может упасть
|