Files
tf_provider/docs/CODEBASE_ANALYSIS_AND_ROADMAP.md
T

761 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- ⛔ LEGACY: deck-api.ngcloud.ru ЗАКРЫВАЕТСЯ. Актуальный API: lk-api-gateway.ngcloud.ru/api/v1/svc -->
# Полный анализ кодовой базы и план развития
**Дата:** 2026-03-13
**Проект:** Terraform Provider for Nubes Cloud
**Версия провайдера:** dev (legacy) / 5.0.18 (universal_rebuild)
**Go:** 1.24 / Terraform Plugin Framework: v1.16 (legacy), v1.8 (rebuild)
---
## Содержание
1. [Общая архитектура](#1-общая-архитектура)
2. [Инвентаризация кода](#2-инвентаризация-кода)
3. [Критические проблемы (P0)](#3-критические-проблемы-p0)
4. [Серьёзные проблемы (P1)](#4-серьёзные-проблемы-p1)
5. [Средний приоритет (P2)](#5-средний-приоритет-p2)
6. [Анализ по слоям](#6-анализ-по-слоям)
7. [Эволюция API-клиента](#7-эволюция-api-клиента)
8. [Генератор кода v2](#8-генератор-кода-v2)
9. [Соответствие provider_philosophy.md](#9-соответствие-provider_philosophymd)
10. [Тестирование](#10-тестирование)
11. [Безопасность](#11-безопасность)
12. [Дорожная карта (Roadmap)](#12-дорожная-карта-roadmap)
13. [Рекомендации по агенту/модели](#13-рекомендации-по-агентумодели)
---
## 1. Общая архитектура
### Два провайдера в одном репозитории
| Компонент | Каталог | Версия | Registry Address | Статус |
|-----------|---------|--------|------------------|--------|
| **Legacy Provider** | `/internal/`, `/main.go` | dev | `registry.terraform.io/nubes/nubes` | Ручной код, 13 ресурсов |
| **Universal Provider** | `/universal_rebuild/` | 5.0.18 | `registry.kube5s.ru/nubes/nubes` | Генерируемый, ~50 ресурсов |
### Архитектурные слои
```
┌─────────────────────────────────────────────────┐
│ TERRAFORM CLI / HCL │
├─────────────────────────────────────────────────┤
│ Provider Layer (provider.go) │
│ ├── Resource Registration │
│ ├── Auth (token / env / file) │
│ └── HTTP Client Init │
├─────────────────────────────────────────────────┤
│ Resource Layer │
│ ├── Manual (vm, edge, vdc, vapp, postgres…) │ ← legacy, internal/provider/
│ └── Generated (50+ services) │ ← universal_rebuild/internal/resources_gen/
├─────────────────────────────────────────────────┤
│ Core Layer │
│ ├── UniversalClient (API V6 flow) │
│ ├── Instance Lookup / State │
│ ├── Operation Runner / Polling │
│ └── Timeout Management │
├─────────────────────────────────────────────────┤
│ CRUD Layer (resources_core/) │
│ ├── CreateResource / UpdateResource / Delete │
│ ├── adoptExistingInstanceOnCreate() │
│ ├── State Refresh / Output Mapping │
│ └── Params Compare / Ref Resolution │
├─────────────────────────────────────────────────┤
│ Nubes Cloud API (deck-api.ngcloud.ru/api/v1) │
└─────────────────────────────────────────────────┘
```
### Конвейер генерации
```
API (live) YAML specs Go code + Docs
│ │ │
▼ ▼ ▼
01_generate_yamls.sh → resources_yaml/*.yaml → 02_generate_*.sh
(service_ops_gen) (gen_v2 + docs_template_gen_v2)
03_build_and_upload.sh → S3
04_build_and_publish_docs.sh → S3
```
---
## 2. Инвентаризация кода
### Legacy Provider (`internal/`)
| Файл | LOC | Назначение | Качество |
|------|-----|------------|----------|
| `provider/provider.go` | 110 | Регистрация, auth, HTTP клиент | ⚠️ InsecureSkipVerify |
| `provider/client_impl.go` | ~350 | HTTP-клиент (NubesClient) | Без retry, без polling |
| `provider/vm_resource.go` | ~500 | VM lifecycle (лучший ресурс) | ✅ Полный CRUD + import |
| `provider/edge_resource.go` | ~400 | Edge gateway | ✅ Полный flow |
| `provider/vdc_resource.go` | ~300 | VDC с triggers | ✅ Multi-stage create |
| `provider/vapp_resource.go` | ~250 | vApp | ✅ Базовый CRUD |
| `provider/postgres_resource.go` | ~200 | Postgres | ⚠️ Только create/delete |
| `provider/s3bucket_resource.go` | ~200 | S3 bucket | ✅ CRUD |
| `provider/pgadmin_resource.go` | ~150 | PgAdmin | ⚠️ Ограниченный |
| `provider/org_resource.go` | ~100 | Organization | ⚠️ Минимальный |
| `provider/quickstart_resource.go` | ~300 | Full-stack helper | Специальный |
| `provider/tubulus_resource.go` | ~200 | AI/Gemini интеграция | Экспериментальный |
| `provider/validators.go` | ~150 | Валидаторы | ✅ Хорошо |
| `core/client.go` | 1065 | UniversalClient (V1V6) | 🔴 Раздут, 6 версий |
| `core/instance_lookup.go` | 87 | Поиск инстансов | ⚠️ Нет exact match |
| `core/instance_ops.go` | 159 | Операции + polling | ⚠️ Fixed 5s interval |
| **Итого** | **~4500** | | |
### Universal Rebuild (`universal_rebuild/`)
| Каталог | Файлов | LOC | Назначение |
|---------|--------|-----|------------|
| `internal/core/` | 5 | ~1400 | UniversalClient V6, timeouts, refSvc |
| `internal/provider/` | 2 | ~300 | Provider setup, timeout embed |
| `internal/resources_core/` | 16 | ~2500 | CRUD, state refresh, diagnostics, params |
| `internal/resources_gen/` | ~100+ | ~15000+ | Сгенерированные ресурсы (50 сервисов) |
| `resources_yaml/` | ~50 | — | YAML-спецификации сервисов |
| `tools/gen_v2/` | 1 | ~2500 | Генератор Go-кода |
| `tools/docs_template_gen_v2/` | 1 | ~800 | Генератор документации |
| `tools/service_ops_gen/` | 1 | ~800 | API → YAML генератор |
| `tools/service_params_gen/` | 1 | ~600 | Параметрический генератор |
| **Итого** | **~180** | **~24000+** | |
### Generated Code Summary (`resources_gen/`)
| Тип ресурса | Кол-во | Примеры |
|-------------|--------|---------|
| Instance (CRUD) | ~50 | postgres, rabbitmq, kafka, k8s, vc_vm |
| Subresource (user/db) | ~20 | postgres_user, postgres_database |
| Action (restart/etc.) | ~10 | postgres_restart, postgres_recovery |
| Registry | 1 | registry.go (auto-сгенерированный список) |
---
## 3. Критические проблемы (P0)
### P0-1: InsecureSkipVerify=true в production
**Где:** `internal/provider/provider.go:103`
```go
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, // ← MITM уязвимость
}
```
**Риск:** Атака "человек посередине" (MITM) — перехват API-токенов и данных.
**Решение:**
```go
// Новый атрибут провайдера:
"insecure": schema.BoolAttribute{
Optional: true,
Description: "Skip TLS certificate verification (dev only)",
},
// + env var NUBES_INSECURE
```
**Также проверить:** `universal_rebuild/internal/provider/provider.go` — аналогичная проблема.
---
### P0-2: Захардкоженный путь debug-лога
**Где:** `internal/core/client.go:18`
```go
f, err := os.OpenFile("/home/naeel/terra/debug_nubes.log", ...)
```
**Риск:** Сбой на любой другой машине. Потенциальная утечка данных в файл вне проекта.
**Решение:**
- Использовать `tflog` (terraform plugin logging) вместо файлового лога
- Или env var `NUBES_DEBUG_LOG` с fallback на `/tmp/nubes_debug.log`
---
### P0-3: Ноль автотестов
**Факт:** В репозитории не найдено ни одного `*_test.go` файла.
**Риск:**
- Регрессии при правках генератора
- Невозможно валидировать lifecycle-логику без ручной проверки
- Нет CI/CD confidence
**Решение:** См. раздел [10. Тестирование](#10-тестирование).
---
### P0-4: 6 версий CreateGenericInstance в одном файле
**Где:** `internal/core/client.go` — 1065 строк, 6 методов.
| Версия | Строки | Статус |
|--------|--------|--------|
| V1 `CreateGenericInstance` | 52-168 | Legacy, не используется |
| V2 `...Universal` | 195-334 | Legacy |
| V3 `...UniversalV2` | 361-504 | Legacy |
| V4 `...UniversalV3` | 531-676 | Legacy |
| V5 `...UniversalV4` | 703-840 | Legacy |
| V6 `...UniversalV5` | 867-1000 | Production |
**Риск:** Путаница — какой метод вызывать? Разная нормализация. Разные баги.
**Решение:**
- V1V5 — пометить `// Deprecated: use CreateGenericInstanceUniversalV5`
- Убедиться, что все ресурсы используют V6/V5
- В перспективе — удалить мёртвый код (после аудита вызовов)
---
## 4. Серьёзные проблемы (P1)
### P1-1: Lifecycle-флаги — legacy vs. canonical
**Требование (provider_philosophy.md §7-9):**
- `adopt_existing_on_create` (default: `false`)
- `suspend_on_destroy` (default: `true`)
**Реальность в legacy:**
- `internal/generated/bolvan_resource_universal_lifecycle.go` использует `delete_mode` и `resume_if_exists`
- Это прямо запрещено в стратегии
**Реальность в universal_rebuild:**
- `resources_core/crud.go` использует `resumeIfExists` bool параметр
- Генератор `gen_v2` генерирует канонические флаги `suspend_on_destroy`, `adopt_existing_on_create`
- **Разрыв:** CRUD-слой принимает bool, но не полностью реализует decision matrix из §7
**Решение:**
1. Обновить `crud.go` — полная реализация status-matrix:
- `not created` → hard error
- `creating/pending/failed` → hard error
- `suspend` + `adopt=false` → hard error с диагностикой
- `running` + `adopt=true` → adopt (import)
- `running` + `adopt=false` → hard error "already exists"
2. Legacy bolvanka — отдельная задача, не трогать
---
### P1-2: Read() — стабы в сгенерированных ресурсах
**Проблема:** Многие сгенерированные ресурсы имеют пустой `Read()`.
**Последствия:**
- Terraform не видит state drift (облако изменилось, TF state устарел)
- `terraform plan` после `apply` показывает расхождения
- `terraform import` бесполезен без Read
**Уже решено в universal_rebuild?**
Да, `state_refresh.go:RefreshResourceState()` обеспечивает полный read-back. Но нужно убедиться, что все сгенерированные ресурсы этот метод ВЫЗЫВАЮТ в своём Read().
---
### P1-3: Нет retry/backoff для API-вызовов
**Где:** Все HTTP-вызовы через `doRequest()` — один попытка, без retry.
**Реальный сценарий:**
- API вернул 503 (maintenance) → terraform apply упал
- Сетевой timeout → terraform apply упал
- Rate limit (429) → terraform apply упал
**Решение:**
```go
// Добавить в core/client.go
func (c *UniversalClient) doRequestWithRetry(ctx context.Context, ...) (*http.Response, error) {
maxRetries := 3
backoff := 2 * time.Second
for attempt := 0; attempt <= maxRetries; attempt++ {
resp, err := c.doRequest(ctx, ...)
if err == nil && resp.StatusCode < 500 && resp.StatusCode != 429 {
return resp, nil
}
if attempt < maxRetries {
time.Sleep(backoff * time.Duration(1<<attempt)) // exponential
}
}
return lastResp, lastErr
}
```
---
### P1-4: Polling с фиксированным интервалом 5с
**Где:** `instance_ops.go:81``time.NewTicker(5 * time.Second)`
**Проблема:**
- Для быстрых операций (suspend ~10с) — 5с интервал нормально
- Для долгих (create VM ~5мин) — 5с создаёт лишние API-запросы
- Нет adaptive polling (увеличение интервала со временем)
**Решение:**
```go
// Adaptive polling: 3s → 5s → 10s → 15s → 30s (max)
intervals := []time.Duration{3*time.Second, 5*time.Second, 10*time.Second, 15*time.Second, 30*time.Second}
```
---
### P1-5: FindInstanceByDisplayName — неточный поиск
**Где:** `instance_lookup.go:29`
**Проблема:** Ищет подстрокой по `displayName`, нет exact match. Если есть "mydb" и "mydb-test", может вернуть неверный инстанс.
**Решение:** Добавить exact match фильтр после получения результатов:
```go
if instance.DisplayName == displayName { // exact match
return instance, nil
}
```
---
## 5. Средний приоритет (P2)
### P2-1: Дублирование client.go между legacy и universal_rebuild
Два файла `client.go`:
- `internal/core/client.go` (1065 строк, V1V6)
- `universal_rebuild/internal/core/client.go` (1034 строк, V6 + refSvc)
**Решение:** Legacy provider постепенно заменяется universal_rebuild. Не рефакторить — просто фиксировать (freeze) legacy.
---
### P2-2: Update() не реализован в большинстве ресурсов
Сгенерированные ресурсы через `gen_v2` уже генерируют Update() если у сервиса есть `modify` операция. Ручные ресурсы (edge, vdc, org) — нет.
**Решение:** Для ручных ресурсов — оставить как есть (ForceNew), если modify не критичен. Для generated — уже работает.
---
### P2-3: Нет валидации YAML-спецификаций
Генератор `01_generate_yamls.sh` → YAML → `gen_v2` — нет промежуточной валидации YAML на корректность/полноту.
**Решение:** Добавить JSON Schema для YAML-спецификаций и валидировать перед генерацией.
---
### P2-4: Нормализация параметров — разные стратегии
| Версия | Стратегия normalization |
|--------|------------------------|
| V1-V2 | empty → empty |
| V3-V4 | empty → `{}` (map) / `[]` (array) |
| V5-V6 | TrimSpace + null-string + `\"\"` → empty |
**Решение:** Зафиксировать V6 behavior как единственный стандарт. Задокументировать.
---
### P2-5: Отсутствие structured logging
- `tflog` используется, но нет единого формата
- Нет trace ID / correlation ID для chain запросов
- Debug-лог в файл вместо terraform framework
**Решение:** Стандартизировать tflog с трейсами:
```go
tflog.Debug(ctx, "API request", map[string]interface{}{
"method": "POST",
"url": url,
"instance_uid": uid,
"operation": opName,
})
```
---
## 6. Анализ по слоям
### 6.1 Provider Layer
| Аспект | Legacy | Universal Rebuild |
|--------|--------|-------------------|
| Auth | token/env/file ✅ | token/env/file ✅ |
| TLS | InsecureSkipVerify 🔴 | InsecureSkipVerify 🔴 |
| HTTP Timeout | 300s | Configurable ✅ |
| Resources | 13 (ручные) | 50+ (генерируемые) |
| Schema | Hand-written | Generated from YAML ✅ |
### 6.2 Resource Layer
**Legacy ресурсы (ручные):**
- VM — лучший: полный CRUD, import, status polling, рабочие timeout'ы
- Edge — хороший: multi-step create, operation discovery
- VDC — хороший: triggers для пересоздания
- Postgres, PgAdmin, Org — минимальные, часть Methods не реализованы
**Universal ресурсы (generated):**
- Полный CRUD для instance если есть create/modify/suspend operations
- Subresource (user, database) с ForceNew если нет modify
- Action (restart, recovery) с trigger field `run_id`
- Lifecycle flags: `suspend_on_destroy`, `adopt_existing_on_create`
- State refresh через `RefreshResourceState`
### 6.3 Core Layer
**Сильные стороны:**
- Единый API flow (V6): create → init op → send params → validate → run → wait
- Timeout management с override per-service
- RefSvc resolution (linked services)
- Operation polling с dtFinish проверкой
**Слабые стороны:**
- Нет retry / circuit breaker
- Фиксированный polling interval
- 6 версий Create в legacy (мусор)
- Debug log в файл (hardcoded path)
### 6.4 CRUD Layer (`resources_core/`)
**Сильные стороны:**
- `adoptExistingInstanceOnCreate()` — базовая adopt-логика
- `RefreshResourceState` — generic state sync с type conversion
- `RequiredParamsMismatch()` — сравнение params при adopt
- `resource_diagnostics.go` — форматированные диагностики
**Слабые стороны:**
- Decision matrix из philosophy § 7 не полностью реализована
- Delete behavior: "state_only" по умолчанию если пустая строка — нарушает `suspend_on_destroy=true` default
- Нет обработки статусов `creating`, `pending`, `failed`
---
## 7. Эволюция API-клиента
```
V1 (simple)
│ + server defaults
V2 (Universal)
│ + name/code hints для normalization
V3 (UniversalV2)
│ + label field
V4 (UniversalV3)
│ + TrimSpace, null → empty
V5 (UniversalV4)
│ + debug file logging, `\"\"` handling
V6 (UniversalV5) ← PRODUCTION (legacy provider)
└─→ V6 Rebuilt ← PRODUCTION (universal_rebuild)
+ refSvc resolution
+ configurable timeouts
+ ensureInstanceCreated()
+ operation timeout per-service
```
**Рекомендация:**
- Legacy V1-V5 → пометить deprecated, не удалять (immutability policy)
- В перспективе: legacy provider замораживается, весь development идёт в `universal_rebuild`
---
## 8. Генератор кода v2
### Архитектура генератора
```
tools/gen_v2/generate_resources_v2.go (~2500 LOC)
├── loadSpecs() → Парсинг YAML per-service
│ ├── Instance operations → GenResource
│ ├── Subresource operations → GenSubresource
│ └── Action operations → GenAction
├── writeInstanceResource() → Go template → *_resource.go
├── writeSubresource() → Go template → *_subresource.go
├── writeActionResource() → Go template → *_action.go
└── writeRegistry() → registry.go (список всех ресурсов)
```
### Что генерирует
Для каждого сервиса от 1 до 3 файлов:
1. **Instance Resource** (`90_postgres_resource.go`):
- `Schema()` — из YAML params (create + modify)
- `Create()``resources_core.CreateResourceWithTimeout()`
- `Read()``resources_core.RefreshResourceState()`
- `Update()``resources_core.UpdateResourceWithTimeout()` (если есть modify)
- `Delete()``resources_core.DeleteResourceWithTimeout()`
- `ImportState()` → passthrough ID
2. **Subresource** (`90_postgres_user_resource.go`):
- ForceNew для всех params (если нет modify_user)
- Create → `RunOperationByCode("create_user")`
- Delete → `RunOperationByCode("delete_user")`
3. **Action** (`90_postgres_restart.go`):
- Trigger field `run_id` (PlanModifier: UseStateForUnknown)
- Create → `RunOperationByCode("restart")`
### Сильные стороны генератора
- ✅ Единый YAML → Go pipeline
- ✅ Canonical lifecycle flags (`suspend_on_destroy`, `adopt_existing_on_create`)
- ✅ RefSvc resolution для linked services
- ✅ ForceNew detection для create-only params
- ✅ Type mapping (string/bool/int64)
- ✅ Auto-registry generation
### Слабые стороны
- ❌ Не генерирует `*_test.go`
- ❌ Нет go fmt / go vet на generated output
- ❌ Нет YAML schema validation перед генерацией
- ❌ Нет diff-отчёта (что изменилось при регенерации)
- ⚠️ Template embedded inline (не отдельные `.tmpl` файлы) — сложно поддерживать при росте
---
## 9. Соответствие provider_philosophy.md
### Матрица статусов (§7)
| Статус инстанса | adopt=false | adopt=true | Реализовано? |
|-----------------|-------------|------------|--------------|
| Not found / Deleted | Create | Create | ✅ |
| Suspended | **Hard error** | Resume + Adopt | ⚠️ Частично |
| Running | **Hard error** | Adopt (import) | ⚠️ Частично |
| Not Created | **Hard error** | **Hard error** | ❌ Нет проверки |
| Creating/Pending | **Hard error** | **Hard error** | ❌ Нет проверки |
| Failed | **Hard error** | **Hard error** | ❌ Нет проверки |
### Destroy behavior (§7)
| Флаг | Действие | Реализовано? |
|------|----------|--------------|
| `suspend_on_destroy=true` (default) | Suspend | ✅ |
| `suspend_on_destroy=false` | State-only | ✅ |
### Diagnostics format (§8)
**Требуется:**
```
resource_name: mydb
service_id: 90
instance_uid: abc-123
status: running
status_raw: Running
flag: adopt_existing_on_create = false
decision: Error — instance already exists
action: Set adopt_existing_on_create = true or rename resource
```
**Реализовано:** `resource_diagnostics.go` реализует multi-line format, но не все поля и не все кейсы.
### GAP Analysis
| Требование | Статус | Файл |
|------------|--------|------|
| Canonical flags in schema | ✅ | gen_v2 templates |
| Decision matrix on Create | ⚠️ 60% | crud.go |
| Hard error on "Not Created" | ❌ | crud.go |
| Hard error on "Creating/Pending/Failed" | ❌ | crud.go |
| Multi-line diagnostics | ⚠️ 70% | resource_diagnostics.go |
| Param mismatch check on adopt | ✅ | required_params_compare.go |
| Plan messages with cloud status | ❌ | Not implemented |
---
## 10. Тестирование
### Текущее состояние
**Тестовых файлов:** 0
**Unit tests:** 0
**Integration tests:** 0
**Acceptance tests:** 0
### План тестирования
#### Фаза 1: Unit Tests для Core (приоритет — P0)
| Тест | Файл | Покрытие |
|------|------|----------|
| `TestNormalizeUniversalValue` | `core/client_test.go` | Нормализация всех типов |
| `TestIsInstanceDeleted` | `core/instance_lookup_test.go` | Все статусы |
| `TestIsStatusSuspended` | `core/crud_test.go` | Edge cases |
| `TestAdoptLogicMatrix` | `core/crud_test.go` | Все комбинации status × adopt flag |
| `TestParamsMismatch` | `core/params_compare_test.go` | Сравнение params |
| `TestRefreshResourceState` | `core/state_refresh_test.go` | Type conversion |
| `TestOperationTimeoutParsing` | `core/timeouts_test.go` | Config loading |
| `TestResolveRefSvcParam` | `core/refsvc_test.go` | UUID ↔ display_name |
**Оценка:** ~40 test cases, ~800 LOC
#### Фаза 2: Integration Tests (приоритет — P1)
| Тест | Описание |
|------|----------|
| `TestCreateAndDeleteInstance` | Full lifecycle на test stand |
| `TestAdoptExistingInstance` | Create → suspend → re-create with adopt=true |
| `TestModifyInstance` | Create → modify → verify params changed |
| `TestSubresourceLifecycle` | User create → delete |
| `TestActionExecution` | Restart trigger |
**Требуется:** Test stand (dev profile) + test service (dummy/bolvanka)
#### Фаза 3: Acceptance Tests (приоритет — P2)
```bash
TF_ACC=1 go test ./internal/... -v -run TestAcc
```
С реальным Terraform CLI: plan → apply → verify → destroy.
---
## 11. Безопасность
### Текущие уязвимости
| # | Уязвимость | OWASP | Severity | Где |
|---|-----------|-------|----------|-----|
| S1 | InsecureSkipVerify=true | A07:Crypto Failures | CRITICAL | provider.go:103 |
| S2 | Hardcoded debug log path | A05:Security Misconfig | HIGH | core/client.go:18 |
| S3 | Нет input validation на API responses | A03:Injection | MEDIUM | core/client.go |
| S4 | Token в памяти без rotation | A07:Auth Failures | MEDIUM | provider.go |
| S5 | Нет rate limiting | A04:Insecure Design | LOW | core/client.go |
| S6 | Secrets в репозитории (secrets/) | A05:Security Misconfig | HIGH | secrets/ |
### Рекомендации по безопасности
1. **S1:** `insecure` flag в provider schema (default: false), env var `NUBES_INSECURE`
2. **S2:** Удалить файловый debug log, использовать только `tflog`
3. **S3:** Валидировать JSON responses на ожидаемые поля
4. **S6:** Перенести secrets в vault / CI variables, добавить в `.gitignore`
---
## 12. Дорожная карта (Roadmap)
### Фаза 0: Стабилизация (текущая — P0 fixes)
| # | Задача | Объём | Зависимости |
|---|--------|-------|-------------|
| 0.1 | Сделать InsecureSkipVerify конфигурируемым | 25 LOC | — |
| 0.2 | Заменить hardcoded debug log на tflog/env var | 15 LOC | — |
| 0.3 | Пометить V1V5 CreateGenericInstance deprecated | Комментарии | — |
| 0.4 | Unit tests для core layer (Фаза 1) | ~800 LOC | — |
| 0.5 | Добавить secrets/ в .gitignore | 1 строка | — |
### Фаза 1: Compliance с provider_philosophy.md
| # | Задача | Объём | Зависимости |
|---|--------|-------|-------------|
| 1.1 | Полная decision matrix в crud.go | ~100 LOC | 0.4 |
| 1.2 | Hard error для "Not Created", "Creating", "Failed" | ~50 LOC | 1.1 |
| 1.3 | Multi-line diagnostics для всех кейсов | ~100 LOC | 1.1 |
| 1.4 | Plan messages с cloud status | ~80 LOC | 1.1 |
| 1.5 | Integration test для adopt matrix | ~200 LOC | 1.1 |
### Фаза 2: Надёжность
| # | Задача | Объём | Зависимости |
|---|--------|-------|-------------|
| 2.1 | Retry с exponential backoff для API-вызовов | ~80 LOC | — |
| 2.2 | Adaptive polling intervals | ~40 LOC | — |
| 2.3 | Exact match в FindInstanceByDisplayName | ~10 LOC | — |
| 2.4 | YAML schema validation перед генерацией | ~200 LOC | — |
| 2.5 | go fmt + go vet в pipeline генерации | ~10 LOC | — |
### Фаза 3: Масштабирование
| # | Задача | Объём | Зависимости |
|---|--------|-------|-------------|
| 3.1 | Генерация *_test.go в gen_v2 | ~500 LOC | 2.4 |
| 3.2 | Diff-отчёт при регенерации | ~200 LOC | — |
| 3.3 | Acceptance tests (TF_ACC) | ~500 LOC | 1.5 |
| 3.4 | Structured logging с trace ID | ~150 LOC | — |
| 3.5 | CI pipeline (build → test → publish) | Config | 3.1, 3.3 |
### Фаза 4: Production Hardening
| # | Задача | Объём | Зависимости |
|---|--------|-------|-------------|
| 4.1 | Заморозить legacy provider (internal/) | Процесс | 3.5 |
| 4.2 | Миграция ручных ресурсов в universal_rebuild | Большая | 4.1 |
| 4.3 | Мониторинг generation stability | Infra | 3.5 |
| 4.4 | Нагрузочное тестирование (параллельный apply) | ~200 LOC | 3.3 |
---
## 13. Рекомендации по агенту/модели
### Выбор модели для разных задач
| Тип задачи | Рекомендуемый агент | Почему |
|-------------|---------------------|--------|
| **Архитектурные решения** | Claude Opus 4.6 (текущий) | Глубокий контекст, сложная логика |
| **Отладка сложных багов** | Claude Opus 4.6 | Лучше держит контекст, видит неочевидные связи |
| **Анализ codebase, code review** | Claude Opus 4.6 | Качество анализа выше |
| **Генерация Go-кода по шаблонам** | Claude Sonnet 4.6 | Достаточно для шаблонного кода, экономичнее |
| **Написание тестов** | Claude Sonnet 4.6 | Шаблонная работа |
| **Массовые правки в генераторе** | Claude Sonnet 4.6 | Достаточно контекста в одном файле |
| **Правки shell-скриптов** | Claude Sonnet 4.6 | Простые правки |
| **Документация** | Claude Sonnet 4.6 | Текстовая генерация |
| **Lifecycle state machine** | Claude Opus 4.6 | Сложные state transitions |
| **API reverse-engineering** | Claude Opus 4.6 | Нужен глубокий анализ HAR/JSON |
### Стратегия переключения
1. **Планирование и design review** → Opus 4.6
2. **Имплементация запланированного** → Sonnet 4.6
3. **Баг не воспроизводится / непонятная причина** → Opus 4.6
4. **Регенерация и routine CI** → Sonnet 4.6
### Практический совет
Для текущей фазы развития (стабилизация + compliance):
- **Opus 4.6** для задач 1.11.4 (lifecycle decision matrix — сложная логика)
- **Sonnet 4.6** для задач 0.10.5, 2.12.5, 3.1 (шаблонные правки, тесты)
---
## Приложение A: Ключевые файлы для изучения
| Приоритет | Файл | Зачем |
|-----------|------|-------|
| ★★★ | `docs/60_strategy/provider_philosophy.md` | Канон lifecycle-логики |
| ★★★ | `universal_rebuild/internal/resources_core/crud.go` | CRUD + adopt-логика |
| ★★★ | `universal_rebuild/internal/core/client.go` | API V6 flow |
| ★★☆ | `universal_rebuild/tools/gen_v2/generate_resources_v2.go` | Генератор |
| ★★☆ | `universal_rebuild/internal/resources_core/state_refresh.go` | State sync |
| ★★☆ | `universal_rebuild/internal/resources_core/resource_diagnostics.go` | Диагностики |
| ★☆☆ | `devops/ARCHITECTURE.md` | Build pipeline design |
| ★☆☆ | `internal/core/client.go` | Legacy reference (V1V6) |
## Приложение B: Команды для быстрого старта
```bash
# Проверка компиляции (universal_rebuild)
cd universal_rebuild && go build ./...
# Проверка компиляции (legacy)
cd /home/naeel/remote_dev/terraform && go build ./...
# Генерация YAML из API
cd devops && bash 01_generate_yamls.sh
# Генерация Go-кода из YAML
cd devops && bash 02_generate_resources_and_docs_template_v2.sh
# Сборка провайдера
cd devops && bash 03_build_and_upload_provider.sh
# Публикация документации
cd devops && bash 04_build_and_publish_docs.sh
```
---
*Документ сформирован автоматически на основе полного анализа кодовой базы. Обновлять при существенных архитектурных изменениях.*