doc: HISTORY/ARCHITECTURE.md — архитектура, S3, GPG, сборка провайдера

This commit is contained in:
“Naeel”
2026-08-06 22:04:26 +04:00
parent c235db00de
commit efa7c5e085
+168
View File
@@ -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` (можно пересоздать)