Files
tf_registry/HISTORY/plan-sonnet-full.md
T

5.4 KiB
Raw Blame History

Plan: Flask Registry — tf_registry (ПОЛНЫЙ ОРИГИНАЛ)

Создан на основе CHAT_SUMMARY_2026-08-06.md + анализа Go-кода. Сохранён из session-памяти в постоянный HISTORY.

TL;DR

Переписать Go-реестр (server/main.go) на Python/Flask для деплоя как managed-сервис в облаке. Логика 1:1 — те же эндпоинты, та же S3-структура, тот же GPG-ключ.


Анализ Go-кода

ENV-переменные (те же в Flask):

Переменная По умолчанию
REGISTRY_HOSTNAME localhost:8080
S3_ENDPOINT
S3_ACCESS_KEY
S3_SECRET_KEY
S3_BUCKET terraform-registry

S3-структура путей (ключи):

Провайдер: {hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{version}_{os}_{arch}.zip
SHA256:    {hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{version}_SHA256SUMS
Подпись:   {hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{version}_SHA256SUMS.sig
Docs:      docs/{namespace}/{name}/{version}/{path}

Эндпоинты:

Метод URL Что делает
GET /.well-known/terraform.json Discovery: {"providers.v1": "/v1/providers/"}
GET /v1/providers/{ns}/{name}/versions Список версий + платформ из S3
GET /v1/providers/{ns}/{name}/{ver}/download/{os}/{arch} JSON с URL для скачивания
GET /v1/proxy?bucket=...&key=... Стриминг файла из S3
GET /docs/{ns}/{name}/{ver}/... Статика документации из S3
GET /healthz, /readyz Отвечают "ok" 200
GET / HTML-страница "ONLINE"

Платформы (listVersions):

Только два паттерна из имён файлов (в исходниках):

  • _linux_amd64.zip{os: linux, arch: amd64}
  • _windows_amd64.zip{os: windows, arch: amd64}

⚠️ Живой Go-деплой также отдаёт darwin_amd64 — operator собрал более новую версию.

GPG-ключ:

Жёстко зашит в registrykeys/public_key.go:

  • KeyID = "CB3A0DF161ECC416" (legacy)
  • ASCIIArmor = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n..." Flask просто возвращает его как строку в JSON — никакого python-gnupg не нужно.

⚠️ Живой Go-деплой отдаёт ДВА ключа: основной 3EC4673EB798238A + legacy CB3A0DF161ECC416.

Прокси:

Параметры: ?bucket=...&key=... (НЕ ?url=... — в chat summary ошибка). Стримит файл через Response(stream_with_context(...)).

Docs:

Кандидаты S3-ключей (в порядке попытки):

  1. docs/{ns}/{name}/{ver}/{rest} (точный путь)
  2. docs/{ns}/{name}/{ver}/{rest}/index.html (если нет расширения)
  3. docs/{ns}/{name}/{ver}/index.html (fallback) MIME по расширению файла.

Файлы для создания:

tf_registry/
├── site/
│   └── app.py          # ~300 строк, весь Flask
└── requirements.txt    # flask, boto3

Шаги:

Фаза 1 — Git-реорганизация (опционально)

  1. git checkout -b golang — сохранить Go-код
  2. git checkout master
  3. Удалить: server/, operator/, k8s/, charts/, scripts/, registrykeys/, REGISTRY_OVERVIEW.md
  4. Оставить: site/app.py, requirements.txt, README.md

Фаза 2 — Flask app.py

Структура app.py:

  1. Импорты: flask, boto3, os, mimetypes, io
  2. Конфиг из ENV (5 переменных выше)
  3. S3-клиент: boto3.client('s3', endpoint_url=..., aws_access_key_id=..., aws_secret_access_key=...)
  4. GPG_KEY_ID и GPG_ASCII_ARMOR — константы
  5. Роуты в точном соответствии с таблицей выше

Фаза 3 — Проверка

  1. python -m py_compile site/app.py
  2. Деплой в managed-сервис registry через UI
  3. curl /.well-known/terraform.json
  4. curl /v1/providers/nubes-test/nubes/versions
  5. terraform init с новым source

Решения:

  • GPG: только публичный ключ в JSON, никакой криптографии в Flask
  • Прокси: ?bucket=&key= (не ?url=)
  • Платформы: linux_amd64 + windows_amd64 (как в исходниках Go) → + darwin (как в живом деплое)
  • Домен: registry.pythonk8s.dev.nubes.ru
  • S3_PREFIX: registry.kube5s.ru (S3-ключи под старым хостнеймом)

Исключено из scope:

  • Operator (остаётся в ветке golang)
  • K8s-манифесты
  • Docker-образы
  • Docs-сервер как отдельный деплоймент

Расхождения исходники vs живой деплой (обнаружены при проверке):

Что Исходники Живой Go
Платформы linux, windows linux, windows, darwin
GPG-ключи 1 ключ (CB3A0D...) 2 ключа (3EC467... + CB3A0D...)
id в versions nubes-test/nubes registry.kube5s.ru/nubes-test/nubes