add: documentation
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
# Universal Provider (ядро + генератор ресурсов) — подробный отчёт
|
||||
|
||||
Дата: 2026-01-31
|
||||
|
||||
## Цель
|
||||
Нужна архитектура «универсального провайдера», где:
|
||||
- есть **ядро** (общий клиент и универсальный флоу операций);
|
||||
- есть **папка ресурсов** (Go-файлы ресурсов);
|
||||
- есть **папка YAML-описаний сервисов** (чтобы DevOps мог добавить сервис одним файлом);
|
||||
- есть **генератор**, который:
|
||||
- читает YAML,
|
||||
- генерирует ресурсы,
|
||||
- генерирует реестр ресурсов,
|
||||
- дальше выполняется build (ядро + ресурсы из папки).
|
||||
|
||||
В итоге: если файла ресурса нет — в провайдере его не будет. Если YAML изменён — перегенерация.
|
||||
|
||||
---
|
||||
|
||||
## Итоговая архитектура (v2.0.0, «голое» ядро + ресурсы)
|
||||
Новая сборка размещена в:
|
||||
- [nubes_provider_gen](nubes_provider_gen)
|
||||
|
||||
Структура:
|
||||
- [nubes_provider_gen/internal/core](nubes_provider_gen/internal/core) — **ядро** (клиент, универсальный flow, запуск операций)
|
||||
- [nubes_provider_gen/internal/provider](nubes_provider_gen/internal/provider) — **провайдер** (schema + клиент)
|
||||
- [nubes_provider_gen/internal/resources_gen](nubes_provider_gen/internal/resources_gen) — **сгенерированные ресурсы** (Go)
|
||||
- [nubes_provider_gen/resources_yaml](nubes_provider_gen/resources_yaml) — **YAML-описания сервисов**
|
||||
- [nubes_provider_gen/tools/gen](nubes_provider_gen/tools/gen) — **генератор**
|
||||
- [nubes_provider_gen/test_persistent](nubes_provider_gen/test_persistent) — тестовые манифесты
|
||||
|
||||
### 1) Ядро (core)
|
||||
Файл: [nubes_provider_gen/internal/core/client.go](nubes_provider_gen/internal/core/client.go)
|
||||
|
||||
Содержит:
|
||||
- `UniversalClient` с HTTP-клиентом и API endpoint/token.
|
||||
- Универсальный flow **CreateGenericInstanceUniversalV6**:
|
||||
1. POST /instances
|
||||
2. POST /instanceOperations (create)
|
||||
3. GET /instanceOperations/{opUid}?fields=cfsParams
|
||||
4. POST /instanceOperationCfsParams (явные параметры)
|
||||
5. POST /instanceOperationCfsParams (дефолтные/пустые для пропущенных)
|
||||
6. GET /instanceOperations/{opUid}/validate-cfs
|
||||
7. POST /instanceOperations/{opUid}/run
|
||||
- Универсальные операции:
|
||||
- `RunInstanceOperationUniversal` (delete/suspend/resume и т.д.)
|
||||
- `RunInstanceOperationUniversalWithDefaults` (modify с автоподстановкой параметров)
|
||||
- Утилиты:
|
||||
- `FindInstanceByDisplayName`
|
||||
- `GetInstanceState`
|
||||
|
||||
**Почему нужно WithDefaults для modify**
|
||||
На modify требуются обязательные параметры (часто даже те, что не меняются). Без них backend падает.
|
||||
|
||||
### 2) Провайдер (provider)
|
||||
Файл: [nubes_provider_gen/internal/provider/provider.go](nubes_provider_gen/internal/provider/provider.go)
|
||||
|
||||
- Тип провайдера: `nubes`
|
||||
- Адрес: `terrareg.kube5s.ru/nubes/nubes`
|
||||
- Ресурсы приходят из **реестра**:
|
||||
- `resources_gen.AllResources()` — возвращает список функций создания ресурсов.
|
||||
|
||||
### 3) Генератор (tools/gen)
|
||||
Файл: [nubes_provider_gen/tools/gen/main.go](nubes_provider_gen/tools/gen/main.go)
|
||||
|
||||
Функции:
|
||||
- Читает все YAML-файлы в `resources_yaml/`
|
||||
- Генерирует ресурсный Go-файл в `internal/resources_gen/` для каждого YAML
|
||||
- Генерирует `registry.go` с `AllResources()`
|
||||
|
||||
То есть:
|
||||
- **Добавили YAML → сгенерировали Go → build**
|
||||
- Нет YAML → нет Go → нет ресурса
|
||||
|
||||
### 4) YAML-описания
|
||||
Файл: [nubes_provider_gen/resources_yaml/dummy.yaml](nubes_provider_gen/resources_yaml/dummy.yaml)
|
||||
|
||||
Минимальная схема (пример dummy):
|
||||
- `name`, `service_id`, `display_name_default`
|
||||
- `create.params` — ID параметров create
|
||||
- `modify.params` — ID параметров modify
|
||||
- `lifecycle` — defaults для `adopt_existing_on_create` и `suspend_on_destroy`
|
||||
|
||||
---
|
||||
|
||||
## Что было сделано (конкретные шаги)
|
||||
|
||||
### Шаг 1. «Голое» ядро + генератор
|
||||
Создан отдельный проект:
|
||||
- [nubes_provider_gen](nubes_provider_gen)
|
||||
Сделан core + provider + tools/gen + resources_yaml.
|
||||
|
||||
### Шаг 2. YAML для dummy
|
||||
Создан YAML dummy: [nubes_provider_gen/resources_yaml/dummy.yaml](nubes_provider_gen/resources_yaml/dummy.yaml)
|
||||
|
||||
### Шаг 3. Генерация ресурсов
|
||||
Команда:
|
||||
- `go run ./tools/gen`
|
||||
|
||||
Сгенерированы:
|
||||
- [nubes_provider_gen/internal/resources_gen/dummy_resource.go](nubes_provider_gen/internal/resources_gen/dummy_resource.go)
|
||||
- [nubes_provider_gen/internal/resources_gen/registry.go](nubes_provider_gen/internal/resources_gen/registry.go)
|
||||
|
||||
### Шаг 4. Build
|
||||
Команда:
|
||||
- `go build -o terraform-provider-nubes`
|
||||
|
||||
### Шаг 5. Тесты dummy
|
||||
Тестовый конфиг:
|
||||
- [nubes_provider_gen/test_persistent/main.tf](nubes_provider_gen/test_persistent/main.tf)
|
||||
- [nubes_provider_gen/test_persistent/dev_override.tfrc](nubes_provider_gen/test_persistent/dev_override.tfrc)
|
||||
|
||||
Проверены сценарии:
|
||||
1. `apply` (create/adopt) — OK
|
||||
2. `modify` (duration 750 → 820) — OK
|
||||
3. `destroy` (`suspend_on_destroy = true`) — OK
|
||||
4. `apply` после suspend (resume/adopt c явным `adopt_existing_on_create`) — OK
|
||||
5. удаление ресурса из манифеста + `apply` — OK
|
||||
6. возвращение ресурса в манифест + `apply` — OK
|
||||
|
||||
---
|
||||
|
||||
## Ошибки и как решались
|
||||
|
||||
### 1) `action modify not available`
|
||||
Причина: в Update использовался `id` из `Plan` (неизвестен).
|
||||
Решение: брать `id` из `State`.
|
||||
|
||||
### 2) `API error 400: Parameter specified does not belong to this operation`
|
||||
Причина: неверные ID параметров modify.
|
||||
Решение: для modify использовать `287/288` вместо `198/199`.
|
||||
|
||||
### 3) `API error 500: checkParam ... instanceOperationCfsParamUid` (повторно)
|
||||
Причина: операция modify требует подстановки всех параметров; без них backend падает.
|
||||
Решение:
|
||||
- Добавлен `RunInstanceOperationUniversalWithDefaults` — читает `cfsParams` и заполняет недостающие
|
||||
- Позже для dummy оказалось нужно отправлять **все** параметры (не только required)
|
||||
|
||||
### 4) `TLS handshake timeout`
|
||||
Причина: VPN/сеть.
|
||||
Решение: повторить команду.
|
||||
|
||||
### 5) `status 401`
|
||||
Причина: токен истёк/невалидный.
|
||||
Решение: заменить токен и сохранить по правилу `/home/naeel/terra/HH-MM-SS.token`.
|
||||
|
||||
### 6) Критерий завершения операции (важно)
|
||||
Любая операция (create/modify/delete/suspend/resume) считается **завершённой**, когда у неё заполнено **время окончания**.
|
||||
Это является признаком завершения **и успеха, и ошибки**. В UI и API ориентируемся на наличие `dtFinish`.
|
||||
|
||||
---
|
||||
|
||||
## Текущее состояние
|
||||
- Провайдер «голый» + ресурсы из YAML работает.
|
||||
- `dummy` полностью тестируется из YAML → Go → build.
|
||||
- В `resources_gen` присутствует 1 ресурс: `nubes_dummy`.
|
||||
|
||||
---
|
||||
|
||||
## План (следующий шаг)
|
||||
1) Расширить YAML-схему:
|
||||
- поддержку дополнительных параметров (например, failInProgress, whereFail и т.п.)
|
||||
- поддержку optional параметров с явными defaults
|
||||
2) Добавить генерацию документации из YAML
|
||||
3) Добавить проверку схемы YAML (валидация) перед генерацией
|
||||
4) Скрипт "build pipeline":
|
||||
- gen → registry → go build
|
||||
5) Опционально: тестовый фреймворк для «batch» тестов
|
||||
|
||||
---
|
||||
|
||||
## Важные файлы
|
||||
- Ядро: [nubes_provider_gen/internal/core/client.go](nubes_provider_gen/internal/core/client.go)
|
||||
- Генератор: [nubes_provider_gen/tools/gen/main.go](nubes_provider_gen/tools/gen/main.go)
|
||||
- Реестр: [nubes_provider_gen/internal/resources_gen/registry.go](nubes_provider_gen/internal/resources_gen/registry.go)
|
||||
- YAML dummy: [nubes_provider_gen/resources_yaml/dummy.yaml](nubes_provider_gen/resources_yaml/dummy.yaml)
|
||||
- Сгенерированный ресурс: [nubes_provider_gen/internal/resources_gen/dummy_resource.go](nubes_provider_gen/internal/resources_gen/dummy_resource.go)
|
||||
- Тесты: [nubes_provider_gen/test_persistent/main.tf](nubes_provider_gen/test_persistent/main.tf)
|
||||
|
||||
---
|
||||
|
||||
## MAYDO (отложено до запроса заказчика)
|
||||
- Добавить в YAML `outputs` (из `state/out`) и `state_params` (из `state/params`).
|
||||
- Добавить `param_meta`: `valueList`, `func`, `refSvcId`, `dataDescriptor`.
|
||||
- Добавить `secrets` (из `vault`) с пометкой чувствительных данных.
|
||||
- Добавить `operations` (man/описания, доступные операции) для генерации доков.
|
||||
- Добавить поддержку `subparams` (nested/list/json) и типизацию сложных структур.
|
||||
- Добавить обработку версий операций (если API это отдаёт).
|
||||
@@ -0,0 +1,12 @@
|
||||
# Dev clone checklist (terra-dev)
|
||||
|
||||
- Create and use branch: `dev/terra-dev`.
|
||||
- Namespace: `terra-dev` (do not modify `terra`).
|
||||
- Ingress host: `terr.kube5s.ru` (separate DNS/TLS secret).
|
||||
- Terraform backend: use `terraform/backend-dev.hcl` (different bucket/key).
|
||||
- Images: use dev tags (avoid pointing dev workloads to prod images/storage).
|
||||
- Secrets: create dev-only secrets and credentials (do not copy prod secrets).
|
||||
- Data: mirror S3 registry if needed (use `mc mirror` or registry mirror tools), or start with empty dev data.
|
||||
- Apply with `kubectl apply -k k8s/overlays/dev`.
|
||||
- Initialize terraform for dev: `terraform init -reconfigure -backend-config=terraform/backend-dev.hcl`.
|
||||
- Confirm: no changes to `terra` namespace and no shared tfstate or storage pointing to prod.
|
||||
@@ -0,0 +1,146 @@
|
||||
# Сводка по разработке Terraform-провайдера Nubes
|
||||
|
||||
Дата: 2026-01-22
|
||||
|
||||
---
|
||||
|
||||
## Краткое описание проекта ✅
|
||||
Разрабатываем Terraform-провайдер для облака Nubes (рабочее локальное имя `mycloud`). Цель — дать клиентам возможность управлять сервисами облака (инстансы, S3, Kubernetes и др.) через Terraform с использованием современного Terraform Plugin Framework.
|
||||
|
||||
---
|
||||
|
||||
## Что уже реализовано (фактически) ✅
|
||||
- Провайдер на Go, структура проекта и `main.go` (providerserver.Serve).
|
||||
- Минимальный ресурс `mycloud_dummy_instance` со схемой: `display_name`, `description`, `id`, `status`.
|
||||
- Реализованы методы Create, Read, Update, Delete для dummy ресурса.
|
||||
- Провайдер успешно создаёт экземпляр (POST /instances) и создаёт операцию (POST /instanceOperations).
|
||||
- При создании операции реализована логика отправки параметров операций (POST /instanceOperationCfsParams) для триггера — добавлена функция submitOperationParams.
|
||||
- Проведено тестирование: создание, обновление, удаление ресурсов — рабочие сценарии (хотя операции часто требуют ручного запуска в UI).
|
||||
|
||||
---
|
||||
|
||||
## Важные технические находки 🔎
|
||||
- API Nubes использует двухшаговый паттерн: POST `/instances` → POST `/instanceOperations` → (нужен шаг запуска/submit).
|
||||
- UI показывает, что операция не всегда стартует автоматически; набор параметров (`instanceOperationCfsParams`) должен корректно заполниться. Некоторые параметры (например `mapExample`) требуют валидных значений — иначе 400 и операция не стартует.
|
||||
- Для запуска операции вручную нажимается кнопка "Выполнить" в UI; Network tab показал последовательность POST/PUT к `instanceOperationCfsParams` и затем GET к `instanceOperations/{uid}` (статус `dtSubmit` остаётся null, если операция не стартовала).
|
||||
|
||||
---
|
||||
|
||||
## Аутентификация: текущее состояние и план 🔐
|
||||
- Сейчас: временный workaround — использовать JWT из браузера вручную через
|
||||
`export MYCLOUD_API_TOKEN="<JWT>"` — удобно для разработки, но не для CI/продакшна.
|
||||
- Рекомендуемый рабочий путь: **Keycloak client_credentials** (OAuth2) или Service Account с long-lived key.
|
||||
- План: реализовать в провайдере поддержку client_credentials + автоматический refresh токена, а также чтение credentials из:
|
||||
- provider HCL parameters
|
||||
- переменных окружения
|
||||
- файла `~/.config/mycloud/credentials` (профили)
|
||||
- CLI login (опционально) — `nubes-cli login` (authorization code + refresh_token сохранение)
|
||||
|
||||
---
|
||||
|
||||
## Что добавить в провайдер (текущие задачи) 🛠️
|
||||
1. Поддержка OAuth2 client_credentials + автообновление токена. (высокий приоритет)
|
||||
2. Улучшить Create/Update/Delete: после создания операции обеспечить корректную последовательность установки параметров и проверку запуска; увеличить retry/timeout.
|
||||
3. Добавить ресурсы: `mycloud_vm_instance` (VM) и `mycloud_s3_bucket` (S3) — MVP набор.
|
||||
4. Добавить sensitive поле `admin_config_b64` для Kubernetes-кластеров и показать пример с `local_file` для автоматической записи kubeconfig (с предупреждениями по state security).
|
||||
|
||||
---
|
||||
|
||||
## Registry & Deployment (публикация провайдера) 📦
|
||||
- Подход: хранить релизы провайдера как S3 объекты:
|
||||
- Структура: `/providers/mycloud/mycloud/<version>/<platform>/...`
|
||||
- Артефакты: бинарники, `SHA256SUMS`, `index.json`, GPG подписи
|
||||
- Быстрый PoC: S3 + self-hosted GitHub Actions runner в k8s (actions-runner-controller).
|
||||
- Продакшн: S3 + оператор для управления сборками.
|
||||
|
||||
---
|
||||
|
||||
## Operator для автоматизированной публикации (идея) 🤖
|
||||
- CRD `ProviderBuild` (или `TerraformProviderRelease`) — контроллер запускает Job на событие (git tag / создание CR):
|
||||
- запускает build job (cross‑build)
|
||||
- прогоняет тесты
|
||||
- генерирует SHA/GPG
|
||||
- загружает артефакты в S3
|
||||
- обновляет статус CR (urls, checksums, logs)
|
||||
|
||||
---
|
||||
|
||||
## CI / Runner — рекомендации ⚙️
|
||||
- Для контейнерной сборки можно использовать GitHub Actions (hosted) для PoC.
|
||||
- Для контроля и приватности рекомендовано ставить self-hosted runner в Nubes (VM или k8s). actions-runner-controller — удобный вариант.
|
||||
- Секреты (S3 creds, GPG keys, Keycloak client_secret) хранить в Vault/Kubernetes Secrets.
|
||||
|
||||
---
|
||||
|
||||
## UX: kubeconfig и автоматизация для пользователей 🧑💻
|
||||
- Варианты: 1) кнопка «Download kubeconfig» на UI (простой FE таск), 2) `nubes-cli get-kubeconfig`, 3) провайдер возвращает `admin_config_b64` (sensitive) и пример `local_file` в документации.
|
||||
- Рекомендация: поддержать все 3 варианта (FE кнопка — удобство; CLI — power users; Terraform — infra-as-code flow), но сначала реализовать провайдер+CLI minimal.
|
||||
|
||||
---
|
||||
|
||||
## Оценки по времени (ориентировочно)
|
||||
- OAuth2 client_credentials + token refresh: 8–16ч
|
||||
- VM resource + S3 resource: 24–40ч
|
||||
- CLI `nubes-cli` (minimal login + get-kubeconfig): 8–16ч
|
||||
- S3 PoC + runner setup + publish script: 8–16ч
|
||||
- Operator skeleton (CRD + basic controller): 3–5 дн
|
||||
|
||||
---
|
||||
|
||||
## Приоритеты и план работ (короткая дорожная карта) 🗺️
|
||||
1. (1–3 дня) Stabilize provider: fix autostart of operations, add token quick-improvements.
|
||||
2. (3–7 дней) Add VM + S3 resources, tests, examples.
|
||||
3. (1–2 дня) PoC: S3 + runner + publish script.
|
||||
4. (3–7 дней) Operator skeleton для автоматических билдов и публикации (K8s CRD).
|
||||
|
||||
---
|
||||
|
||||
## Текущие блокеры / вопросы для DevOps
|
||||
- Хотим ли мы сразу выдавать service client (client_id/secret) в Keycloak для CI? (рекомендуется для production later)
|
||||
- Хотим ли развернуть S3‑подход в тестовом кластере? (рекомендуется для HA)
|
||||
|
||||
---
|
||||
|
||||
## Команды и полезные ссылки (для демонстрации)
|
||||
- Примеры запросов для проверки токена:
|
||||
```bash
|
||||
curl -s -X POST "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/token" \
|
||||
-d 'grant_type=client_credentials' \
|
||||
-d 'client_id=YOUR_ID' \
|
||||
-d 'client_secret=YOUR_SECRET'
|
||||
```
|
||||
- Проверка API:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer $TOKEN" https://deck-api.ngcloud.ru/api/v1/index.cfm/instances
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Файлы проекта (важные местоположения)
|
||||
- `internal/provider/provider.go` — конфигурация провайдера
|
||||
- `internal/provider/dummy_resource.go` — dummy resource (создание, операции, submitOperationParams)
|
||||
- `test/main.tf` и `examples/main.tf` — пример использования
|
||||
- `docs/discovery/development-journey.md` — подробная история разработки (есть)
|
||||
- `docs/for_nomo_chat.md` — этот файл
|
||||
|
||||
---
|
||||
|
||||
Если нужно, могу экспортировать эту сводку в PDF или другой формат и подготовить короткую презентацию для начальника. Хочешь, добавлю ещё краткий `README` с шагами для запуска PoC (S3 + self-hosted runner + build workflow)?
|
||||
|
||||
*Файл сохранён по пути*: `docs/for_nomo_chat.md`
|
||||
|
||||
---
|
||||
|
||||
Автор: GitHub Copilot (Raptor mini (Preview))
|
||||
|
||||
|
||||
## Новые находки по API (22.01.2026) 🔎
|
||||
⚠️ **Найден недостающий метод "Execute"!**
|
||||
В документации обнаружен эндпоинт, который выполняет ту самую роль кнопки "Выполнить":
|
||||
- `POST /instanceOperations/{instanceOperationUid}/run`
|
||||
- Описание: "Запуск выполнения операции".
|
||||
|
||||
**План исправлений в провайдере:**
|
||||
1. После `submitOperationParams` (заполнения параметров) нужно вызвать `validate-cfs` (опционально, для проверки).
|
||||
2. Вызвать `POST /instanceOperations/{uid}/run`.
|
||||
3. Только после этого поллить статус операции.
|
||||
Reference in New Issue
Block a user