Files
tf_provider/HISTORY/2026-07-02_api_gateway_migration.md
T

9.7 KiB
Raw Blame History

2026-07-02 — Миграция с deck-api на API Gateway (lk-api-gateway)

Контекст

Старый API: https://deck-api-{stand}.ngcloud.ru/api/v1/index.cfm?endpoint=/services/123 Новый API Gateway: https://lk-api-gateway-{stand}.ngcloud.ru/api/v1/svc/services/123

Ответы JSON идентичны. Различается только формат URL:

  • Старый: proxy через index.cfm?endpoint=
  • Новый: прямые REST-пути

Цель: перевести TEST-стенд на новый Gateway, сохранив совместимость со старым для dev/prod.

Архитектурное решение

Авто-детект режима по наличию index.cfm в URL:

  • Есть index.cfm → старый proxy (?endpoint=)
  • Нет index.cfm → новый REST (прямая конкатенация пути)

Один env-параметр NUBES_API_ENDPOINT управляет всем.

Изменения (11 файлов)

1. Генератор YAML: universal_rebuild/tools/service_spec_gen/generate_service_spec.go

  • normalizeAPIEndpoint() — убрано принудительное добавление /index.cfm, теперь только trim trailing slash
  • getViaProxy()callAPI() — авто-детект: если index.cfm в URL → ?endpoint=, иначе → прямая конкатенация {base}{path}
  • Добавлен метод isProxyAPI() для детекта
  • Обновлён комментарий с документированием двух режимов

2. Ядро провайдера: universal_rebuild/internal/core/client.go

  • Добавлены isProxyAPI() и buildURL(path string) string — единая точка конструирования URL
  • Заменены все 4 места с хардкодом ?endpoint=:
    • FindExistingInstances (пагинированный поиск, строка ~515)
    • GetInstanceState (строка ~590)
    • GetInstanceStateRaw (строка ~637)
    • doRequest (POST/PUT/GET, строки ~838-853)

3. Оркестратор YAML: devops/01_generate_yamls.sh

  • Убрана принудительная нормализация if [[ "$API_ENDPOINT" != */index.cfm ]] → автоматическая
  • Python-скрипт: авто-детект "index.cfm" in endpoint?endpoint= vs прямой путь

4. Генератор документации: devops/02_generate_resources_and_docs_v2.sh

  • Добавлена передача -api-endpoint "$DOCS_API_ENDPOINT" в docs_template_gen_v2
  • Нормализация: если нет ни index.cfm, ни /svc → дописать /index.cfm (обратная совместимость)

5. Публикация доков: devops/04_build_and_publish_docs.sh

  • normalize_api_endpoint() — убрано принудительное /index.cfm, только trim

6. Корневой скрипт: 01_generate_yamls.sh (корень)

  • Python-скрипт: такой же авто-детект, как в devops/01

7-8. Шаблоны документации: docs_template_gen_v2/main.go + docs_template_gen/main.go

  • Добавлен флаг -api-endpoint (default: старый deck-api)
  • Все хардкоды api_endpoint = "https://deck-api...index.cfm" заменены на fmt.Sprintf
  • Проброшено через writeResourceDocsbuildExamplePageexampleBlockbuildSubresourceExamplePage

9-10. Провайдеры: internal/provider/provider.go + universal_rebuild/internal/provider/provider.go

  • Добавлен TODO(api-gateway) комментарий над дефолтным apiEndpoint
  • Сам дефолт не менялся (runtime провайдера теперь использует core.buildURL())

11. Профиль TEST: devops/profiles/test/profile.env

  • NUBES_API_ENDPOINThttps://lk-api-gateway-test.ngcloud.ru/api/v1/svc

Бонус: версия в бинарник

  • devops/build-provider.sh: go build теперь с -ldflags "-X main.version=${VERSION}" — версия из профиля вшивается в бинарник (раньше всегда была из main.go)

Анализ пайплайна (попутно)

Полный пайплайн: services_list.txt01_generate_yamls.sh02_generate_resources_and_docs_v2.sh03_build_and_upload_provider.sh04_build_and_publish_docs.sh.

Найденные проблемы (не исправлялись, зафиксированы):

  • main.go Address = nubes-test (только для test, для prod нужно nubes)
  • Нет сборки под darwin/arm64 (Apple Silicon)
  • Корневой 01_generate_yamls.sh ссылается на несуществующий service_params_gen
  • Кросс-стадийная валидация отсутствует (сбои 01 не видны в 02)

Оставшиеся deck-api в коде

Только как значения по умолчанию (переопределяются через NUBES_API_ENDPOINT):

  • service_spec_gen/generate_service_spec.go:150getenvDefault("NUBES_API_ENDPOINT", "https://deck-api...")
  • devops/01_generate_yamls.sh:108${NUBES_API_ENDPOINT:-https://deck-api...}
  • devops/02_generate_resources_and_docs_v2.sh:95 — аналогично
  • devops/04_build_and_publish_docs.sh:13,87 — аналогично
  • docs_template_gen_v2/main.go:91 — flag default
  • docs_template_gen/main.go:81 — flag default
  • internal/provider/provider.go:105 + universal_rebuild/...с TODO

Хардкодов в теле функций/примеров больше нет.

Для перехода dev/prod

Достаточно поменять одну строку в profile.env:

NUBES_API_ENDPOINT="https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc"   # dev
NUBES_API_ENDPOINT="https://lk-api-gateway.ngcloud.ru/api/v1/svc"       # prod

Всё остальное — авто-детект.


Доступ к СТАРОМУ deck-api (DDoS-Guard 403)

Старый API жив, но DDoS-Guard усилил фильтрацию. Просто User-Agent: Mozilla/5.0 уже недостаточно.

Рабочие заголовки для curl:

curl -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 с доменом того же стенда. Без него — 403.

Без токена (публичные эндпоинты):

curl -H "User-Agent: Mozilla/5.0" \
  "https://deck-api-test.ngcloud.ru/api/v1"
# → 200 (OK)

Что изменилось с июля 2026

DDoS-Guard ужесточил правила:

  • Старый User-Agent: Mozilla/5.0 + Accept: */* → 403
  • Новый: нужен полный браузерный User-Agent + Referer
  • Провайдер (v5.0.75) использовал старые заголовки — при следующем билде надо обновить
  • Новый Gateway (lk-api-gateway) — 403 не выдаёт, работает с любым User-Agent

Проблема map-fixed параметров и dataDescriptor

Суть

Новый Gateway группирует плоские параметры в map-fixed JSON-блоки. Sub-поля (dataDescriptor) не видны в /serviceOperation/{id} — появляются только в ответе уже выполненной операции /instanceOperations/{uid}.

Как получить sub-поля (на примере postgres)

# 1. Найти любой успешный инстанс postgres
curl ... "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/instances?serviceId=90&page=1&size=1"

# 2. Взять instanceUid → запросить операции → взять create-операцию
curl ... "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/instances/{uid}"

# 3. Запросить операцию — в cfsParams будет dataDescriptor с sub-полями
curl ... "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/instanceOperations/{opUid}"

Правильные JSON-ключи для postgres (из dataDescriptor)

Блок Поля
startupConfiguration resourceRealm
clusterConfiguration cpu, memory, replicas, disk
accessConfiguration masterIpSpace, masterAccessList, slaveIpSpace, slaveAccessList
postgresConfiguration version, sslRequired, poolerMaster, poolerSlave
postgresConf paramName, paramValue (массив)
backupConfiguration s3Uid, retain, schedule
autoscaleConfiguration enabled, schedule, quota, percent

Обсуждение с девопсами (02.07.2026)

  • Плоские параметры не вернутся — map-fixed остаётся (нужно для групп ключей, нод, учёток)
  • Структуру блоков обещают давать в API, но пока не придумали формат
  • Пока единственный источник структуры — Jenkins-конфиги

CMDB backend bug

При run операции бэкенд /app/cmdb падает с ValidationError: InstanceState: version, instanceUid, dtState, isTest, instanceOperationUid — can't be blank. Это баг в Gateway→CMDB, не в провайдере.