From efa7c5e0857cf33a4a71f9a88129a59bf2ac8ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Thu, 6 Aug 2026 22:04:26 +0400 Subject: [PATCH] =?UTF-8?q?doc:=20HISTORY/ARCHITECTURE.md=20=E2=80=94=20?= =?UTF-8?q?=D0=B0=D1=80=D1=85=D0=B8=D1=82=D0=B5=D0=BA=D1=82=D1=83=D1=80?= =?UTF-8?q?=D0=B0,=20S3,=20GPG,=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B0=D0=B9=D0=B4=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY/ARCHITECTURE.md | 168 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 HISTORY/ARCHITECTURE.md diff --git a/HISTORY/ARCHITECTURE.md b/HISTORY/ARCHITECTURE.md new file mode 100644 index 0000000..eadb804 --- /dev/null +++ b/HISTORY/ARCHITECTURE.md @@ -0,0 +1,168 @@ +# tf_registry — Архитектура и рабочий процесс + +## Что такое этот реестр + +Собственный реестр Terraform-провайдеров по протоколу HashiCorp Provider Registry Protocol. +Позволяет публиковать и распространять кастомные Terraform-провайдеры без HashiCorp Registry. + +**Текущий URL:** `https://go-registry.containerk8s.dev.nubes.ru` + +--- + +## Как это работает + +### Загрузка провайдера (пользователь) + +```hcl +terraform { + required_providers { + nubes = { + source = "go-registry.containerk8s.dev.nubes.ru/nubes-test/nubes" + version = "5.1.16" + } + } +} +``` + +Terraform сам делает: +1. `GET /.well-known/terraform.json` → узнаёт API-путь +2. `GET /v1/providers/nubes-test/nubes/versions` → список версий и платформ +3. `GET /v1/providers/.../download/linux/amd64` → JSON с URL для скачивания +4. Скачивает zip, проверяет SHA256, проверяет GPG-подпись +5. Всё — провайдер установлен + +Никакой аутентификации не нужно. + +--- + +## S3-структура + +Все данные хранятся в S3 (`terraform-registry`). Никакой БД нет. + +``` +{префикс}/{namespace}/{name}/{version}/ +├── terraform-provider-{name}_{ver}_{os}_{arch}.zip — бинарник провайдера +├── terraform-provider-{name}_{ver}_SHA256SUMS — контрольные суммы +└── terraform-provider-{name}_{ver}_SHA256SUMS.sig — GPG-подпись сумм + +docs/{namespace}/{name}/{version}/ +├── index.html — документация провайдера +└── ... — любые статические файлы +``` + +**Важно:** префикс (первая часть пути в S3) сейчас — `registry.kube5s.ru` (временный хардкод). +Планируется либо сменить на свой домен, либо убрать префикс совсем. + +--- + +## GPG-подпись + +### Зачем +Terraform требует, чтобы SHA256SUMS были подписаны GPG. Это гарантирует, что провайдер не подменён. + +### Как работает +1. **Приватный ключ** — хранится у того, кто заливает провайдер (`secrets/private_key.asc`) +2. **Публичный ключ** — вшит в код реестра (`gpg_key.go` → `/v1/providers/.../download` отдаёт его) +3. Terraform при `init` сверяет подпись SHA256SUMS с публичным ключом + +### Текущие ключи +| Key ID | Роль | +|---|---| +| `3EC4673EB798238A` | Основной (текущий) | +| `CB3A0DF161ECC416` | Legacy (старый) | + +Оба отдаются в `signing_keys.gpg_public_keys` — Terraform пробует каждый. + +--- + +## Как залить новый провайдер + +### Скрипт `build-provider.sh` + +Находится в `server/build-provider.sh`. Делает: +1. Компилирует Go-провайдер под linux/windows/darwin × amd64 +2. Упаковывает в zip +3. Генерирует SHA256SUMS +4. Импортирует приватный GPG-ключ из `secrets/private_key.asc` +5. Подписывает SHA256SUMS +6. Заливает zip + SHA256SUMS + .sig в S3 + +### Требования +```bash +# Переменные окружения +S3_ENDPOINT=s3.msk-1.ngcloud.ru +S3_ACCESS_KEY=... +S3_SECRET_KEY=... +S3_BUCKET=terraform-registry + +# GPG +secrets/private_key.asc # приватный ключ для подписи + +# Исходники провайдера +universal_rebuild/ # директория с Go-кодом провайдера +``` + +### Запуск +```bash +VERSION=5.1.17 ./server/build-provider.sh +``` + +--- + +## Документация + +Эндпоинт `/docs/{ns}/{name}/{ver}/...` отдаёт статику из S3: +``` +docs/{ns}/{name}/{ver}/index.html +``` + +Работает как статический веб-сервер: HTML, CSS, JS, изображения — всё, что положишь в `docs/` в S3. +Логика поиска (1:1 с Go-кодом): +1. Точный путь (`docs/ns/name/ver/style.css`) +2. Если нет расширения — `{путь}/index.html` +3. Fallback — `docs/ns/name/ver/index.html` + +--- + +## Эндпоинты + +| Метод | URL | Ответ | +|---|---|---| +| GET | `/` | HTML с версией | +| 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, shasum, GPG ключи | +| GET | `/v1/proxy?bucket=...&key=...` | Стриминг файла из S3 | +| GET | `/docs/{ns}/{name}/{ver}/...` | Статика из S3 | +| GET | `/healthz`, `/readyz` | `"ok"` 200 | + +--- + +## CI/CD + +```bash +# Сборка образа +docker build -t gitea.services.ngcloud.ru/nail/tf_registry:latest . + +# Пуш в Gitea Docker Registry +docker push gitea.services.ngcloud.ru/nail/tf_registry:latest + +# Редеплой — через UI modify (меняет только CPU/memory/replicas, подхватывает :latest) +``` + +--- + +## Платформы + +Детектятся по имени zip-файла: +- `_darwin_amd64.zip` → macOS Intel +- `_linux_amd64.zip` → Linux +- `_windows_amd64.zip` → Windows + +--- + +## Текущие проблемы + +1. **S3_PREFIX** — хардкод `registry.kube5s.ru` (TODO в коде) +2. **modify** — нельзя менять `jsonEnv` в UI (надо просить devops) +3. **Домен** — `go-registry` вместо `registry` (можно пересоздать)