diff --git a/HISTORY/2026-08-06-first-deploy.md b/HISTORY/2026-08-06-first-deploy.md deleted file mode 100644 index 5ec3360..0000000 --- a/HISTORY/2026-08-06-first-deploy.md +++ /dev/null @@ -1,32 +0,0 @@ -# 2026-08-06 — Первый деплой Flask (v1.0.0) - -## Хронология - -### 09:41 — Деплой v1.0.0 -- `gitPath`: `https://gitea.services.ngcloud.ru/Nail/tf_registry.git` -- `app.py`: минимальный Flask, `GET /` → `

tf_registry v1.0.0

` - -### Ошибка: Init:Error -``` -Cloning into '/tmp/app'... -fatal: could not read Username for 'https://gitea.services.ngcloud.ru' -``` -Причина: gitea — приватный репо, managed-сервис не имеет кредов для git clone. -Предыдущий деплой работал на `github.com/Foxyhhd/Baldurs-Gate-test.git` (публичный). - -### Решение -Репозиторий сделан публичным → передеплой → успешно. - -### Результат -`https://registry.pythonk8s.dev.nubes.ru/` → `tf_registry v1.0.0` ✅ - -## Далее - -По плану (`HISTORY/2026-08-06-plan-review.md`, `plan.md`): - -1. **Git-реорганизация** — `git checkout -b golang` (архив Go), удалить Go-код из master -2. **Полный `app.py`** — все 7 роутов (discovery, versions, download, proxy, docs, healthz, readyz) -3. **Проверка** — curl + terraform init - -## Урок -- gitea.services.ngcloud.ru — приватный. Либо сделать репо публичным, либо вшить `user:token@` в gitPath. diff --git a/HISTORY/2026-08-06-plan-review.md b/HISTORY/2026-08-06-plan-review.md deleted file mode 100644 index d13a6e8..0000000 --- a/HISTORY/2026-08-06-plan-review.md +++ /dev/null @@ -1,91 +0,0 @@ -# 2026-08-06 — Ревизия плана Flask-реестра - -## Контекст - -Переписываем Go-реестр (`server/main.go`) на Python/Flask для managed-сервиса в облаке. -Логика 1:1 — те же эндпоинты, та же S3-структура, тот же GPG-ключ. - -## Файлы прочитаны - -| Файл | Строки | Что | -|---|---|---| -| `server/main.go` | 1-289 | Весь HTTP-сервер: 7 роутов, S3, GPG | -| `server/docs.go` | 1-200 | Docs-сервер с кандидатами ключей | -| `server/gpg_key.go` | 1-50 | Прокси к `registrykeys` пакету | -| `registrykeys/public_key.go` | 1-50 | Константы KeyID + ASCIIArmor | -| `CHAT_SUMMARY_2026-08-06.md` | 1-100 | Контекст: архитектура, S3-структура, ENV | - -## План (из plan.md) — TL;DR - -- **Фаза 1**: git checkout -b golang → удалить Go-код из master -- **Фаза 2**: `app.py` (~250-300 строк Flask) + `requirements.txt` (flask, boto3) -- **Фаза 3**: py_compile → деплой → curl-проверки → terraform init - -### Эндпоинты (из Go-кода): - -| URL | Ответ | -|---|---| -| `GET /.well-known/terraform.json` | `{"providers.v1": "/v1/providers/"}` | -| `GET /v1/providers/{ns}/{name}/versions` | JSON: id, versions[], warnings[] | -| `GET /v1/providers/{ns}/{name}/{ver}/download/{os}/{arch}` | JSON: download_url, shasums_url, sig_url, shasum, signing_keys | -| `GET /v1/proxy?bucket=...&key=...` | Стриминг файла из S3 | -| `GET /docs/{ns}/{name}/{ver}/...` | Статика из S3 (кандидаты ключей) | -| `GET /healthz` | `"ok"` 200 | -| `GET /readyz` | `"ok"` 200 | -| `GET /` | HTML-страница "ONLINE" | - -### S3-ключи: - -``` -{hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{ver}_{os}_{arch}.zip -{hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{ver}_SHA256SUMS -{hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{ver}_SHA256SUMS.sig -docs/{namespace}/{name}/{version}/{path} -``` - -### ENV-переменные: -- `REGISTRY_HOSTNAME` (default: `localhost:8080`) -- `S3_ENDPOINT` -- `S3_ACCESS_KEY` -- `S3_SECRET_KEY` -- `S3_BUCKET` (default: `terraform-registry`) - -## 6 замечаний к плану - -### 1. ⚠️ S3-пагинация (ВАЖНО) -Go: `ListObjects` → канал с авто-пагинацией (все объекты). -boto3: `list_objects_v2` → макс 1000 за раз. -**Надо:** `Paginator` или цикл с `ContinuationToken`. - -### 2. Docs-кандидаты (точность) -Go-логика чуть точнее, чем описано в плане: -- `rest` пустой → только `index.html` -- `rest` не пустой: exact → (если `/` на конце ИЛИ нет расширения → `{rest}/index.html`) → `index.html` -- Для `.css`/`.js` НЕ пробуется `{rest}/index.html` - -### 3. Content-Length при стриминге -Go ставит через `obj.Stat()`. Flask `stream_with_context` — нет. -**Надо:** `head_object` → взять `ContentLength` → выставить вручную. - -### 4. boto3 + MinIO -```python -boto3.client('s3', - endpoint_url=f'https://{s3_endpoint}', - use_ssl=True, - config=Config(signature_version='s3v4') -) -``` -Без `s3v4` могут быть ошибки подписи на MinIO. - -### 5. /readyz -Go: комментарий «Проверить S3», но реально просто `"ok"`. -Делать 1:1 → просто `"ok"`. - -### 6. Порядок роутов во Flask -Flask матчит сверху вниз. `/` должен быть последним, чтобы не перехватить `/docs/`. - -## Решения (подтверждены) -- GPG: только константа, без python-gnupg ✅ -- Прокси: `?bucket=&key=` (НЕ `?url=`) ✅ -- Платформы: только `linux_amd64` + `windows_amd64` ✅ -- Домен: `registry.pythonk8s.dev.nubes.ru` ✅ diff --git a/HISTORY/CHAT_SUMMARY_2026-08-06.md b/HISTORY/CHAT_SUMMARY_2026-08-06.md deleted file mode 100644 index 604b39a..0000000 --- a/HISTORY/CHAT_SUMMARY_2026-08-06.md +++ /dev/null @@ -1,199 +0,0 @@ -# Chat Summary — Реестр Terraform-провайдера Nubes - -> **Дата**: 2026-08-06 -> **Тема**: Разбор архитектуры registry-сервера, план переноса с Go/K8s на Flask managed-сервис в облаке -> **Для нового чата**: прочитай этот файл — и ты в контексте - ---- - -## 1. Что такое провайдер `nubes` - -Кастомный Terraform-провайдер для облака NGCloud. Написан на Go (`~/tf_provider/provider/main.go`). Публикуется в собственном реестре `registry.kube5s.ru`. - -**Terraform-конфиг (как у пользователя)**: -```hcl -terraform { - required_providers { - nubes = { - source = "registry.kube5s.ru/nubes-test/nubes" - version = "5.1.16" - } - } -} - -provider "nubes" { - api_token = var.api_token - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" - # log_level = "debug" # none | info | debug -} -``` - -**Разбор адреса** `registry.kube5s.ru/nubes-test/nubes`: -- `registry.kube5s.ru` — домен реестра (DNS пользователя → IP балансировщика K8s) -- `nubes-test` — **namespace** внутри реестра (для тестовых версий) -- `nubes` — имя провайдера - -**Namespace'ы реестра:** -| Namespace | Где используется | -|---|---| -| `nubes-test` | Тестовый стенд | -| `nubes-dev` | Dev-стенд | -| `nubes` | Прод (PROD) | - ---- - -## 2. Где и как запущен реестр (текущее состояние) - -### Подтверждено через SSH → ВМ → kubectl: -- **ВМ**: `naeel@5.172.178.213` (ключ `~/remote_dev/terraform/secrets/id_ed25519.txt`, или по умолчанию из `~/.ssh`) -- **Кластер**: `iot-naeel` (self-managed K8s, **личный кластер пользователя**) -- **Namespace**: `terra` - -### Деплойменты: -| Компонент | Образ | Статус | -|---|---|---| -| `registry-server` | `naeel/terraform-registry-server:gpg-fix-2` | 1/1 Running | -| `terraform-operator` | `naeel/terraform-registry-operator:latest` | 1/1 Running | -| `cloud-dashboard` | `naeel/cloud-dashboard:v9.52` | 1/1 Running | - -### Ingress `registry-ingress`: -- Хосты: `terra.k8c.ru`, **`registry.kube5s.ru`** -- TLS: `registry-kube5s-tls` (Ready) -- Балансировщик: `185.247.187.151` - -### ENV `registry-server`: -``` -REGISTRY_HOSTNAME = registry.kube5s.ru -S3_ENDPOINT = s3.msk-1.ngcloud.ru -S3_BUCKET = terraform-registry -S3_USE_SSL = true -``` - -### Проверка живого реестра (HTTP 200): -``` -GET /.well-known/terraform.json → {"providers.v1":"/v1/providers/"} -GET /v1/providers/nubes-test/nubes/versions → версии 5.1.0 ... 5.1.16 -``` - ---- - -## 3. Код реестра — `~/tf_registry` - -- **Репозиторий**: `https://gitea.services.ngcloud.ru/Nail/tf_registry.git` -- **Ветка**: `master` -- **Язык**: Go -- **Структура**: - - `server/main.go` — **актуальный код** HTTP-сервера реестра - - `operator/` — Kubernetes Operator - - `k8s/`, `charts/` — манифесты деплоя - - `registrykeys/` — GPG-ключ - -### Архитектура текущего реестра: -``` -registry.kube5s.ru (DNS) - → K8s Ingress (личный кластер iot-naeel) - → Deployment registry-server (Go, Docker) - → S3 bucket terraform-registry/ - └── {REGISTRY_HOSTNAME}/nubes-test/nubes/{version}/ - ├── terraform-provider-nubes_{version}_{os}_{arch}.zip - ├── ..._SHA256SUMS - └── ..._SHA256SUMS.sig -``` - -### Протокол (Terraform Registry Protocol v1): -| Эндпоинт | Назначение | -|---|---| -| `GET /.well-known/terraform.json` | Discovery | -| `GET /v1/providers/{ns}/{name}/versions` | Список версий и платформ | -| `GET /v1/providers/{ns}/{name}/{ver}/download/{os}/{arch}` | URL для скачивания | -| `GET /v1/proxy?url=...` | Прокси из S3 | -| `GET /docs/...` | Документация | - ---- - -## 4. План: перенос реестра на Flask (managed-сервис в облаке) - -### Проблема: -Кубер — **личный** кластер пользователя. Реестр должен быть **чисто облачным**, как managed-сервис (Flask или Node.js), который создаётся через UI облака. - -### Выбор языка: **Flask (Python)** -- `boto3` — лучший S3-клиент -- Уже есть работающий Flask managed-сервис (`tfflaskcrud/`) -- Проще и короче, чем Node.js для этой задачи - -### Новая архитектура: -``` -registry.pythonk8s.dev.nubes.ru (managed-сервис, URL даёт облако) - → Flask app (app.py) - → S3 bucket terraform-registry/ (тот же) -``` - -### Что больше НЕ нужно: -- ❌ K8s-деплой `registry-server` -- ❌ K8s Ingress `registry-ingress` -- ❌ Сертификат `registry-kube5s-tls` + cert-manager -- ❌ Домен `registry.kube5s.ru` (заменяется на managed URL) -- ❌ Docker-образы для реестра -- ❌ Go-код для реестра - -### План реорганизации Git-репозитория: -``` -git checkout -b golang # сохранить Go-код в ветку golang -git checkout master # вернуться в master -# удалить всё лишнее -# оставить только app.py + requirements.txt + README.md -``` - -- **`master`** → Flask-реестр (основная ветка) -- **`golang`** → старый Go-код (архив, можно поправить и задеплоить при необходимости) - -### Имя managed-сервиса: **`registry`** -``` -https://registry.pythonk8s.dev.nubes.ru/ -``` - -### Terraform-конфиг пользователя после миграции: -```hcl -source = "registry.pythonk8s.dev.nubes.ru/nubes-test/nubes" -``` - -### Файлы Flask-реестра: -``` -tf_registry/ -├── app.py # весь код (~300 строк) -├── requirements.txt # Flask, boto3, python-gnupg -└── README.md -``` - ---- - -## 5. Managed-сервисы в облаке - -Пользовательские managed-сервисы (Flask, Node.js, Lucee) создаются через **UI облака** (не через Terraform). Terraform-провайдер `nubes` тоже умеет их создавать (`nubes_flask`, `nubes_nodejs`, `nubes_lucee`), но это вторичный способ. - ---- - -## 6. Ключевые файлы и репозитории - -| Что | Путь | -|---|---| -| Код registry-сервера (Go) | `~/tf_registry/server/main.go` | -| Код провайдера (Go) | `~/tf_provider/provider/main.go` | -| Git реестра | `https://gitea.services.ngcloud.ru/Nail/tf_registry.git` | -| Пример Flask managed-сервиса | `~/tf_provider/tfflaskcrud/site/app.py` | -| Пример Node.js managed-сервиса | `~/tf_provider/tfnodejscrud/server.js` | -| SSH-доступ к ВМ | `naeel@5.172.178.213` | -| Кластер | `iot-naeel`, namespace `terra` | - ---- - -## 7. Следующие шаги (для нового чата) - -1. Прочитать `~/tf_registry/server/main.go` (весь) — понять точную логику -2. Написать `app.py` — Flask-реестр с теми же эндпоинтами -3. Проверить синтаксис Python -4. Создать ветку `golang` из `master` и сохранить Go-код -5. Очистить `master`, оставить только Flask -6. Залить `app.py` в managed-сервис `registry` через UI облака -7. Проверить: `curl https://registry.pythonk8s.dev.nubes.ru/.well-known/terraform.json` -8. Обновить `source` в Terraform-конфигах пользователей diff --git a/HISTORY/REGISTRY_OVERVIEW.md b/HISTORY/REGISTRY_OVERVIEW.md deleted file mode 100644 index 50a1ce1..0000000 --- a/HISTORY/REGISTRY_OVERVIEW.md +++ /dev/null @@ -1,198 +0,0 @@ -# Terraform Registry — Полное описание - -> Этот документ — точка входа для нового чата/агента. Содержит всё необходимое для понимания, сопровождения и доработки реестра провайдера. - ---- - -## Что это такое - -Кастомный Terraform Registry Server для провайдера `nubes` (облако Nubes / ngcloud.ru). - -Когда разработчик пишет в своём `.tf`: -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.18" - } - } -} -``` -...и выполняет `terraform init`, Terraform идёт к **этому** серверу за бинарниками провайдера. - ---- - -## Структура папки - -``` -REGISTRY/ -├── server/ — Go-код HTTP-сервера реестра (АКТУАЛЬНЫЙ) -├── operator/ — Kubernetes Operator (CRD TerraformProviderRelease) + старая копия server-кода в cmd/registry/ -├── k8s/ — Kubernetes манифесты деплоя (namespace, ingress, deployment, service, TLS) -├── registrykeys/ — Go-модуль с публичным GPG-ключом (для верификации провайдера) -├── charts/ — Helm chart для деплоя registry-server -└── scripts/ - └── build-and-push-registry-server.sh — сборка Docker-образа и push в registry -``` - -**Важно:** `server/` и `operator/cmd/registry/` — дублирующийся код. Актуальный и полный — только `server/main.go`. В `operator/cmd/registry/main.go` нет health-эндпоинтов и не удалены darwin-платформы. При правках менять только `server/`. - ---- - -## Как работает registry-server - -### Реализованный протокол - -[Terraform Registry Protocol v1](https://developer.hashicorp.com/terraform/internals/provider-registry-protocol). - -| Эндпоинт | Назначение | -|---|---| -| `GET /.well-known/terraform.json` | Discovery — говорит Terraform, где API реестра | -| `GET /v1/providers/{ns}/{name}/versions` | Список доступных версий и платформ | -| `GET /v1/providers/{ns}/{name}/{version}/download/{os}/{arch}` | URL для скачивания бинарника | -| `GET /v1/proxy?url=...` | Проксирование файлов из S3 (бинарники, SHA, GPG-сигнатура) | -| `GET /docs/{ns}/{name}/{version}/...` | Документация провайдера (статический HTML из S3) | -| `GET /healthz` | Health probe для Kubernetes | -| `GET /readyz` | Readiness probe для Kubernetes | - -### Как определяются версии - -Сервер листит S3 bucket в поиске файлов вида: -``` -////terraform-provider-__linux_amd64.zip -``` -Из имён файлов парсит версию и платформы. Поддерживаемые платформы: `linux_amd64`, `linux_arm64`, `windows_amd64`. - -### Переменные окружения - -| Переменная | Default | Назначение | -|---|---|---| -| `REGISTRY_HOSTNAME` | `localhost:8080` | Домен реестра (используется в URL ответов) | -| `S3_ENDPOINT` | — | Хост S3 без схемы, например `s3.msk-1.ngcloud.ru` | -| `S3_ACCESS_KEY` | — | S3 access key | -| `S3_SECRET_KEY` | — | S3 secret key | -| `S3_BUCKET` | `terraform-registry` | Имя бакета | -| `S3_USE_SSL` | — | Если `true` — HTTPS (в коде Secure: true захардкожено) | - -### S3 структура бакета - -``` -terraform-registry/ ← бакет -└── terra.k8c.ru/ - └── nubes/ - └── nubes/ - └── 5.0.18/ - ├── terraform-provider-nubes_5.0.18_linux_amd64.zip - ├── terraform-provider-nubes_5.0.18_windows_amd64.zip - ├── terraform-provider-nubes_5.0.18_SHA256SUMS - └── terraform-provider-nubes_5.0.18_SHA256SUMS.sig -docs/ -└── nubes/ - └── nubes/ - └── 5.0.18/ - └── index.html (и другие файлы документации) -``` - ---- - -## GPG-ключ - -Terraform верифицирует подпись провайдера через GPG. - -- Публичный ключ **встроен** в `server/main.go` (ASCII Armor, константа в коде). -- Также хранится в `registrykeys/public_key.go` (отдельный go-модуль). -- Приватный ключ — `secrets/private_key.asc` (НЕ в репо, gitignore). - -**При ротации ключей:** -1. Сгенерировать новую пару `gpg --gen-key` -2. Обновить ASCII Armor в `server/main.go` -3. Пересобрать и передеплоить Docker-образ -4. Перезалить все артефакты провайдера, подписанные новым ключом - ---- - -## Деплой в Kubernetes - -### Кластер и namespace - -- Namespace: `terra` -- Домен: `terra.k8c.ru` (планируемая миграция → `registry.nubes.ru`, см. `../docs/ops/DOMAIN_MIGRATION.md`) -- TLS: cert-manager с `letsencrypt-prod` issuer — **НЕ ТРОГАТЬ** сертификат руками! - -### Что задеплоено - -| Ресурс | Kind | Образ | -|---|---|---| -| `registry-server` | Deployment | `naeel/terraform-registry-server:gpg-key-20260208` | -| `registry-server` | Service | ClusterIP :8080 | -| `registry-ingress` | Ingress | host: `terra.k8c.ru` | - -Credentials S3 — из секрета `s3-credentials` (ключи `access-key`, `secret-key`). - -### Применение манифестов (только при смене конфигурации кластера) - -```bash -kubectl apply -f k8s/operator/manifests/00-namespace.yaml -kubectl apply -f k8s/operator/manifests/00-rbac.yaml -kubectl apply -f k8s/operator/manifests/02-crd.yaml -kubectl apply -f k8s/operator/manifests/05-registry-server.yaml -``` - -### Диагностика (read-only) - -```bash -kubectl -n terra get pods,svc,ingress,deploy -kubectl -n terra logs -l app=registry-server --tail=50 -kubectl -n terra get certificate registry-tls -o yaml -``` - ---- - -## Сборка и публикация нового образа - -Скрипт: `scripts/build-and-push-registry-server.sh` - -```bash -cd REGISTRY -./scripts/build-and-push-registry-server.sh -``` - -Собирает Docker-образ из `server/` и пушит в Docker Hub (`naeel/terraform-registry-server:`). - -После push нужно обновить тег образа в `operator/manifests/05-registry-server.yaml` и применить `kubectl apply`. - ---- - -## Когда registry НЕ нужно трогать - -Registry — stateless сервис. При выпуске новой версии провайдера (`nubes`) registry не меняется: - -``` -Новая версия провайдера: - 1. go build → бинарники - 2. devops/03_build_and_upload_provider.sh → бинарники в S3 - 3. devops/04_build_and_publish_docs.sh → документация в S3 - ✅ Registry автоматически начинает отдавать новую версию - ❌ kubectl не нужен - ❌ код registry не меняется - ❌ Docker-образ не пересобирается -``` - -Registry пересобирается только если меняется **сам сервер**: новые эндпоинты, логика, ротация GPG-ключа. - ---- - -## Связь с основным репо провайдера - -Этот код был перемещён из основного репо `terraform/` в папку `REGISTRY/` для последующего выноса в отдельный репозиторий. Код провайдера и код реестра полностью независимы — нет общих go-модулей, нет импортов друг друга. - ---- - -## Ограничения и правила работы - -- **Ручные правки `operator/cmd/registry/`** — не делать, это устаревшая копия. Актуальный код — только `server/`. -- **Let's Encrypt cert-manager** (`letsencrypt-prod`) — не применять `kubectl apply` на Ingress-ресурсы без именённой необходимости (риск бана от CA). -- **docker build** — только с явного разрешения разработчика. -- **kubectl** — только read-only (`get`, `describe`, `logs`) без разрешения. -- **S3 credentials** — никогда не коммитить в репо. Только через секреты k8s или переменные окружения. diff --git a/HISTORY/ceph-s3-setup.md b/HISTORY/ceph-s3-setup.md deleted file mode 100644 index 9bb32ea..0000000 --- a/HISTORY/ceph-s3-setup.md +++ /dev/null @@ -1,59 +0,0 @@ -# Ceph S3 — конфигурация для реестра - -## Инстанс S3 - -| Поле | Значение | -|---|---| -| userName | `naeels3` | -| instanceUid | `332cdb0d-34bf-43bf-864d-4adcc3b556fb` | -| urlConnect | `http://ceph.tst.nubes.ru/` | -| resourceRealm | `ceph.tst.nubes.ru` | - -## Пользователи (users) - -| user_id | Назначение | -|---|---| -| `3709` | Основной владелец | -| `3709:super` | Subuser с повышенными правами | -| `3709:technicalS3Backup` | Subuser для бэкапов | -| `3709:reader` | **(планируется)** Subuser для реестра — только read+list | - -## Subuser `3709:reader` для реестра - -### Права -- `read` — чтение объектов -- `list` — список объектов (нужно для `listVersions`) -- **Без** `write` и `delete` — реестр не может менять данные - -### Креды (после создания) -```json -{ - "S3_ACCESS_KEY": "...", - "S3_SECRET_KEY": "..." -} -``` -Вставить в `jsonEnv` инстанса реестра. - -### Конфигурация реестра под Ceph - -Dockerfile ENV: -```dockerfile -ENV S3_ENDPOINT=ceph.tst.nubes.ru \ - S3_BUCKET=terraform-registry \ - S3_PREFIX=go-registry.containerk8s.dev.nubes.ru \ - REGISTRY_HOSTNAME=go-registry.containerk8s.dev.nubes.ru \ - PORT=5000 -``` - -### Различия с текущим S3 (MinIO) - -| | Старый (MinIO) | Новый (Ceph) | -|---|---|---| -| ENDPOINT | `s3.msk-1.ngcloud.ru` | `ceph.tst.nubes.ru` | -| Креды | Статические | Subuser `3709:reader` | -| Протокол | HTTPS | HTTP (судя по `urlConnect`) | -| Безопасность | Приватный MinIO | Ceph с разделением прав | - -### ⚠️ Если HTTP -В Go-коде сейчас `Secure: true` — для HTTP надо поменять на `Secure: false`. -Лучше через ENV: `S3_USE_SSL=true/false` (сейчас захардкожено). diff --git a/HISTORY/plan-sonnet-full.md b/HISTORY/plan-sonnet-full.md deleted file mode 100644 index a663ecb..0000000 --- a/HISTORY/plan-sonnet-full.md +++ /dev/null @@ -1,123 +0,0 @@ -# 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` |