6.4 KiB
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_DIRdocs-generator— требует--resources,--docs,--versionфлаги- Удалён
detectVersion()— больше не читаетprovider/main.go - Удалён
detectRoot(),pickPath()— нет хардкод-путей
3. Общая библиотека типов
Создан TOOLS/lib/ — единый YAML-контракт. Модуль: tf-tools/lib.
Подключены:
yaml-generator→ type aliasParamSpec = lib.ParamSpecи др.resource-generator→ type aliasOutputParam,OperationSpec,ParamSpec
НЕ подключён:
docs-generator— будет заменён на LLM-генератор, не трогаем
При добавлении поля в YAML — править lib/types.go, несогласованность ловится компилятором.
4. Синхронизация версий
provider/main.go: 5.0.75 → 5.0.60 (соответствует последней сборке)profile.env: три переменные → однаVERSION03_build,04_publish:${PROVIDER_VERSION:-${RELEASE_VERSION:-}}→${VERSION}
5. Автосборка бинарников
01_generate_yamls.sh: если исходники новее бинарника — пересборка.
6. Удалённый мусор
devops/config/— дубликат profiles02_generate_resources_and_docs.sh+_template.sh— legacy, заменены v2cloud-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/ — документация
Осталось
- 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 может упасть