docs: Opus analysis round 2 — full audit of generation scripts (bash + Go tools + CI + profiles)
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
# Анализ генерационных скриптов — 30.06.2026 (сессия 2)
|
||||
|
||||
**Исполнитель:** Opus 4.8
|
||||
**Задача:** аудит 4 bash-скриптов, 6 Go-тулов, профилей, CI — как API-данные превращаются в YAML, Go-код и документацию
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 1: Bash-скрипты — аудит 4 файлов
|
||||
|
||||
**Прочитал:** все 4 скрипта полностью.
|
||||
|
||||
| Аспект | 01_yamls | 02_docs_v2 | 03_build | 04_publish |
|
||||
|--------|---------|-----------|---------|-----------|
|
||||
| `set -euo pipefail` | ✅ | ✅ | ✅ | ✅ |
|
||||
| `trap` cleanup | ❌ | ✅ | ✅ | ✅ |
|
||||
| API error handling | 🔴 НЕТ | — | — | — |
|
||||
| User-Agent в urllib | 🔴 НЕТ | — | — | — |
|
||||
| Проверка зависимостей (`command -v`) | ❌ | ❌ | ❌ | ✅ |
|
||||
| Идемпотентность (`rm` старого) | ✅ | ✅ | ✅ | ✅ |
|
||||
| Lock-файлы (параллельный запуск) | ❌ | ❌ | ❌ | ❌ |
|
||||
| Профиль обязателен | ✅ | ✅ | ✅ | ❌ |
|
||||
|
||||
**Проблемы:**
|
||||
- 🔴 **01_generate_yamls.sh** — python `urllib` ставит только `Authorization`, без User-Agent → дефолтный `Python-urllib/3.x` → DDoS-Guard зарежет. **P0**
|
||||
- 🔴 **01_generate_yamls.sh** — нет обработки 500/битый JSON/пустой ответ → необработанный Python traceback вместо retry. **P0**
|
||||
- 🟠 Пустой `services_list.txt` не ловится — 01_generate_yamls.sh проверяет только существование файла → «успех» без генерации. **P1**
|
||||
- 🟠 Нет `command -v go/python3` ни в 01/02/03 → непонятная ошибка если инструмента нет. **P1**
|
||||
- 🟠 Нет lock-файлов нигде → два параллельных прогона на один `PROFILE_DIR` затрут друг друга. **P1**
|
||||
- 🟡 04_build_and_publish_docs.sh — профиль НЕ обязателен (в отличие от 01-03). **P2**
|
||||
|
||||
**Предложение:** добавить UA в urllib + retry-обёртку (3 попытки, backoff); guard на непустой список; `command -v` проверки; lock через `flock` на `PROFILE_DIR`.
|
||||
|
||||
**Хорошо:** 03_build_and_upload_provider.sh — сильная валидация полноты registry перед сборкой; 04_build_and_publish_docs.sh — лучший fallback (docker → venv → system mkdocs).
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 2: service_spec_gen (API → YAML)
|
||||
|
||||
**Прочитал:** generate_service_spec.go полностью.
|
||||
|
||||
- **HTTP-клиент:** ✅ кастомный клиент с `Timeout: 30s`; ✅ User-Agent уже есть. 🔴 **Retry отсутствует** — любой 429/503/сетевой сбой → ошибка → panic в main. **P1**
|
||||
- **Парсинг API:** ✅ структуры полные — `cfsParam` маппит все 19 полей. Потери только в edge-case. Неожиданный формат → `json.Unmarshal` error → panic, без graceful degradation. **P2**
|
||||
- **classifyOperation:** покрыты `create/modify/delete/suspend/resume` → instance, `create_*/modify_*/delete_*` → subresource, остальное → action. 🟠 **Новые префиксы (`restart_*`, `pause_*`, `enable_*`) попадут в action**, а не subresource. **P1**
|
||||
- **Constraints:** ✅ всё сохраняется — `maxLength/minLength/regex/uniqueScope/dependsOn`. 🟡 `normalizeValueList` делает `fmt.Sprintf("%v")` — для вложенных объектов теряет структуру. **P2**
|
||||
- **YAML:** ✅ `yaml.Marshal` с `omitempty`, вложенные структуры корректны. Имя файла через `normalizeIdentifier` — Unicode схлопывается в `_`. **P2**
|
||||
|
||||
**Предложение:** добавить retry с backoff в `getViaProxy`; расширить `classifyOperation` карту префиксов или сделать её конфигурируемой.
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 3: gen_v2 (YAML → Go)
|
||||
|
||||
**Прочитал:** generate_resources_v2.go.
|
||||
|
||||
- 🟠 **`format.Source` fallback:** при ошибке форматирования пишет `buf.Bytes()` (неотформатированный, возможно невалидный Go) **без warning**. Ошибка всплывёт только на компиляции. **P1**
|
||||
- **computeCreateOnly:** «param в create но не в modify → ForceNew». При отсутствии modify-операции ВСЕ create-параметры → CreateOnly → корректно для immutable subresource. ✅
|
||||
- 🟠 **Subresource identity:** `DeleteParams` помечаются ForceNew, но `computeCreateOnly` их не учитывает → если delete-параметр не входит в create, возможен некорректный план. **P1**
|
||||
- 🟡 **JSON:** `data_type: json → IsJson + JsonNormalize` работает для object/array, но нет валидации что значение реально валидный JSON. **P2**
|
||||
|
||||
**Предложение:** не молчать на ошибке `format.Source` — логировать warning (или fail при невалидном Go); проверить пересечение DeleteParams ∩ CreateParams.
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 4: docs_template_gen_v2
|
||||
|
||||
**Прочитал:** docs_template_gen_v2/main.go.
|
||||
|
||||
- **Генерируется 7 MD-файлов на ресурс:** `.md`, `_example.md`, `_params_create.md`, `_params_modify.md`, `_outputs.md`, `_ops.md`, `_params.md`. Формат — Markdown для mkdocs. ✅
|
||||
- **Покрытие:** ✅ subresources и actions, есть index. Все YAML-поля используются. ✅
|
||||
- **HCL-примеры:** из create-операции, required без default → в HCL, опциональные закомментированы. ✅
|
||||
- 🟠 **Ошибки:** битый YAML → panic, пустые операции — молча пропускаются. **P1**
|
||||
- 🟡 **`-exclude clickhouse`** — дефолт флага + дублирован в 02_..._v2.sh. Хардкод, без объяснения причины. **P2** — вынести в config/комментарий.
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 5: service_ops_gen / service_params_gen — нужны?
|
||||
|
||||
**Прочитал:** оба тула + grep по devops.
|
||||
|
||||
- ❌ **Нигде не вызываются** в bash-скриптах — мёртвый код старой v1-архитектуры.
|
||||
- ✅ **Заменены `service_spec_gen`** (единый YAML на сервис).
|
||||
- **`tools/gen/`** — только placeholder-README, функциональность не реализована.
|
||||
|
||||
**Предложение:** удалить `service_ops_gen`, `service_params_gen`, `tools/gen/` — **но только по явной команде**. **P2**
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 6: embed.go и resources_yaml
|
||||
|
||||
- `//go:embed` встраивает все `*.yaml` в бинарник. **Зачем:** провайдер при старте один раз читает YAML и строит lookup-карты, без зависимости от внешних файлов.
|
||||
- **Используется в 4 местах** resources_core: params_mapping.go, params_validation_mapping.go, required_params.go, params_ref_mapping.go.
|
||||
- **Почему генерируется скриптом:** шаблонный файл без логики, генерируется если отсутствует.
|
||||
- ⚠️ **`devops/profiles/*/generated/resources_yaml/embed.go` — не существует** (per-profile embed не реализован).
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 7: Профили и CI
|
||||
|
||||
- **Профили test/prod/dev** идентичны по структуре, различаются `profile.env` (API endpoint, token-файл, версии).
|
||||
- **CI = GitLab CI** (pipeline.yaml), 4 стадии: test → build → sign → publish. Запуск `only: tags`.
|
||||
- ❌ **Автогенерации YAML в CI НЕТ** — YAML генерируются локально/вручную и коммитятся; CI только собирает и публикует. **P1**
|
||||
- **Деплой:** Docker-образ `registry-operator:${TAG}` пушится в Harbor → управляется K8s-оператором.
|
||||
- **Скрипты 10-13:** `13 clean` → `12 latest` → `11 alias` → `10 stability` (N раз — тест стабильности).
|
||||
|
||||
---
|
||||
|
||||
## Вопрос 8: Практическая проверка покрытия
|
||||
|
||||
- ✅ **Покрытие 100%:** все 41 активный сервис имеют YAML; исключённый `24 vc_nat` (DEPRECATED) YAML не имеет. Лишних YAML нет.
|
||||
- 🔴 **Ключевая проблема — свежесть содержимого.** 90_postgres.yaml содержит 11 операций, но **`backup`/`reconcile` НЕТ** — API их уже отдаёт, а YAML устарел.
|
||||
|
||||
**Вывод:** проверка «список vs файлы» зелёная, но **не ловит устаревшее содержимое**.
|
||||
|
||||
**Предложение (P1):** добавить в CI шаг diff — перегенерировать YAML и сравнить с закоммиченными; при расхождении — фейлить.
|
||||
|
||||
---
|
||||
|
||||
## Сводка приоритетов
|
||||
|
||||
### P0 (блокеры)
|
||||
1. urllib без User-Agent в 01_generate_yamls.sh → DDoS-Guard
|
||||
2. urllib без обработки ошибок API (500/битый JSON/пусто)
|
||||
|
||||
### P1 (важно)
|
||||
- Нет retry в generate_service_spec.go
|
||||
- `classifyOperation` не знает новые префиксы
|
||||
- `format.Source` молча пишет невалидный Go в gen_v2
|
||||
- DeleteParams ∩ CreateParams в subresource identity
|
||||
- Нет CI-диффа «API vs закоммиченный YAML»
|
||||
- Нет lock-файлов, нет `command -v`, пустой список не ловится
|
||||
|
||||
### P2 (доработки)
|
||||
- Удалить legacy-тулы (по команде)
|
||||
- `-exclude clickhouse` в config
|
||||
- JSON-валидация
|
||||
- Unicode в именах
|
||||
- panic на битом YAML в docs-gen
|
||||
Reference in New Issue
Block a user