Files
tf_provider/docs/howitwasdone.md
T

14 KiB
Raw Blame History

How It Was Done — Developer Guide (закрытая страница)

Filename & Versioning: howitwasdone.md / 20260204 / Draft v1

Этот документ — единый технический мануал. Он доступен только по прямой ссылке и не включён в публичную навигацию.

Оглавление

  1. Архитектура и методы (CRUD)
  2. База знаний ошибок
  3. Глоссарий (со ссылками на места употребления)
  4. Билд и публикация провайдера и документации

1. Архитектура и методы (CRUD)

1.1 Архитектура универсального rebuild

  • Ядро: universal_rebuild/internal/core (универсальный клиент API и общий flow операций).
  • Провайдер: universal_rebuild/internal/provider (schema, конфигурация, подключение ресурсов).
  • YAML-спеки: universal_rebuild/resources_yaml (источник истины).
  • Генератор: universal_rebuild/tools/gen (генерация Go-ресурсов и registry).

Ключевое правило: новая логика — только новые функции/файлы. Существующий Go‑код не менять без согласования.

1.2 Источник параметров (discovery)

Параметры извлекаются через proxy endpoint API:

  • /index.cfm?endpoint=/services/{svcId}
  • /index.cfm?endpoint=/serviceOperation/{svcOperationId}
  • (опц.) /index.cfm?endpoint=/param-value-list/{svcOperationCfsParamId}

Схема: сервис → операции → CFS параметры → YAML → генерация Go.

1.3 Create (универсальный 7‑шаговый паттерн)

  1. POST /instances → instanceUid
  2. POST /instanceOperations (create) → instanceOperationUid
  3. GET /instanceOperations/{uid}?fields=cfsParams
  4. POST /instanceOperationCfsParams для каждого параметра
  5. GET /instanceOperations/{uid}/validate-cfs
  6. POST /instanceOperations/{uid}/run с payload {}
  7. Polling до завершения операции

Критично: параметры отправляются все, включая дефолты.

1.4 Read / Adopt

  • При isDeleted или explainedStatus=deleted — state очищается.
  • При совпадении display_name и resume_if_exists=true — adopt/resume.
  • Предупреждения показываются только на create и не мешают managed ресурсам.

1.5 Update / Modify

  • IDs параметров на modify отличаются от create.
  • Нельзя хардкодить ID: нужно получать manifest операции и строить маппинг.
  • Если modify отсутствует в availableOperations — выдаётся ясная ошибка.

1.6 Polling (железные правила)

  • Завершение операции определяется только по dtFinish.
  • После dtFinish результат определяется isSuccessful.
  • Для VM применяется двойной контроль: статус операции + статус инстанса (ERROR/STOPPED).

1.7 Нормализация типов

  • map/json → "{}"
  • list/array → "[]"
  • Пустые строки в JSON‑параметрах запрещены (валидаторы на plan).

1.8 Soft Delete

  • Для тяжёлых ресурсов delete заменяется на suspend (карантин/retention).
  • Повторный apply при suspend может выполнять resume.

2. База знаний ошибок

A. Аутентификация и токены

Токены лежат в secrets/{dev,test,prod}.token. Срок действия — до декабря 2026. Проверить дату JWT:

python3 -c "import json,base64; t=open('secrets/test.token').read().split('.'); d=json.loads(base64.urlsafe_b64decode(t[1]+'==')); from datetime import datetime,timezone; print(datetime.fromtimestamp(d['exp'],tz=timezone.utc))"

Симптом: 403 Forbidden (НЕ 401!) Причина (старый API index.cfm): DDoS-Guard блокирует — нет Referer или нет User-Agent. Решение для curl (старый API):

curl -s --max-time 10 \
  -H "Authorization: Bearer $TOKEN" \
  -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \
  -H "Referer: https://deck-test.ngcloud.ru/" \
  "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/services/90"

Referer должен совпадать со стендом (test/dev/prod). Новый Gateway (lk-api-gateway) требует только Authorization.

Симптом: 401 Unauthorized / Authorization header expected Причина: токен истёк или не передан в окружение Решение: обновить access_token и сохранить в файле HH‑MM‑SS.token; убедиться, что Terraform читает токен

B. Поллинг зависает

Симптом: apply «висит», операция не завершается Причина: ожидание по статусу инстанса/операции без dtFinish Решение: критерий завершения — dtFinish; далее isSuccessful

C. Modify: Invalid CFS parameter (400)

Причина: отправлены create IDs для modify Решение: получать manifest операции и динамически маппить IDs

D. Modify недоступен

Симптом: action modify not available Причина: modify нет в availableOperations Решение: проверять доступные операции и выдавать явную ошибку

E. Map/JSON/List: Invalid format

Симптом: 400 Invalid format map/array/json Причина: пустые строки вместо {} или [] Решение: нормализация по типу, trim, отправка {} или []

F. VM: зависание на FW / 500 String[]→GUID

Симптом: зависание на стадии FW, 500 checkParam Причина: пустые/невалидные JSON‑массивы, ошибки backend Решение: валидация JSON массивов, дефолт ["0.0.0.0/0"], фильтрация пустых значений; при повторении — эскалация на поддержку

G. VM modify: checkParam instanceOperationCfsParamUid

Симптом: 500 Invalid call of function checkParam Причина: дублирование параметров при POST/PUT Решение: гибридный PUT/POST по наличию instanceOperationCfsParamUid; проверить формат эндпойнта

H. Postgres: split() on null

Симптом: Cannot invoke method split() on null object Причина: передан UUID конкретного S3‑бакета Решение: использовать UUID сервиса S3 (svcId 12), а не бакета

I. GPG/Registry

Симптом: authentication signature from unknown issuer Причина: ключ подписи не совпадает с ключом в registry Решение: обновить signing_keys на сервере или пересобрать/подменить бинарник

Симптом: openpgp invalid data Причина: ASCIIarmor для .sig Решение: бинарная detached подпись без --armor

J. Registry/S3

Симптом: presigned URL не работает через Ingress Причина: Host заголовок ломает подпись Решение: proxy‑режим download на сервере registry

K. Документация: 404

Причина: неверный S3‑ключ (hostname в префиксе) Решение: фиксированный префикс docs////

L. Версии Terraform Plugin Framework

Симптом: ошибки сборки при апгрейде Причина: несовместимость framework и plugingo Решение: использовать совместимые версии

M. TLS handshake timeout

Причина: сетевые условия/VPN Решение: повторить apply


3. Глоссарий (с ссылками на места употребления)

Каждый термин содержит ссылки на разделы этого же документа, где он используется.

  • instance — экземпляр сервиса в Nubes Cloud.

  • instanceOperation — асинхронная операция над instance (create/modify/delete/suspend/resume).

  • cfsParams — список параметров операции, получаемый через manifest операции.

  • svcOperationCfsParamId — ID параметра операции, различается для create и modify.

  • dtFinish — единственный надёжный индикатор завершения операции.

  • isSuccessful — результат операции после dtFinish.

  • resourceRealm — окружение/realm; иногда обязателен и задаётся пользователем.

  • display_name — человекочитаемое имя; используется для adopt/resume.

  • resume_if_exists — включение adopt/resume по display_name.

  • delete_mode — режим удаления (delete/suspend/state_only).

  • suspend — мягкое удаление (карантин/retention).

  • validate-cfs — проверка параметров операции до run.

  • state.out — выходные данные API; при отсутствии задаются null.

  • computed — вычисляемые поля, должны быть известны после apply.

  • registry protocol — API Terraform Registry (discovery + versions + download).

  • signing_keys — публичные GPG ключи, выдаваемые registry.

  • NLI — Natural Language Infrastructure (AI‑парсинг инструкций).


4. Билд и публикация провайдера и документации

4.1 Сборка провайдера (universal_rebuild)

Общий цикл:

  1. Генерация YAML параметров сервисов.
  2. Генерация Go‑ресурсов.
  3. Сборка бинарника go build.

Ключевые каталоги:

  • universal_rebuild/resources_yaml
  • universal_rebuild/internal/resources_gen
  • universal_rebuild/tools/gen

4.2 Публикация провайдера в Registry

  • Артефакты: zip, SHA256SUMS, SHA256SUMS.sig
  • Подпись: для .sig использовать бинарную detached подпись
  • Хранилище: S3 bucket terraformregistry
  • Префикс — по правилам registry‑сервера

4.3 Документация (MkDocs)

  • Сборка: Docker образ squidfunk/mkdocs-material
  • Результат: директория site/
  • Публикация: scripts/publish-docs.sh
  • Путь: docs////

4.4 Важные нюансы

  • При смене домена обновлять registry и ключи подписи.
  • Presigned URL через Ingress может ломаться — использовать proxy mode.
  • Технические папки исключаются из публикации.

4.5 Рекомендованный порядок работ

  1. Discovery параметров сервиса
  2. Генерация YAML
  3. Генерация Go‑ресурсов
  4. Build
  5. Тесты create/modify/suspend/resume
  6. Документация и публикация

4.6 AI‑интеграция (NLI)

Кратко: реализована для ресурса Tubulus через ModifyPlan + askGemini, с защитой от двойного вызова AI.

4.7 Прямая ссылка

https://registry.kube5s.ru/docs/nubes/nubes/2.0.0/howitwasdone/