clean: удалена устаревшая документация (kube5s, тестовый Ceph, старые планы)
This commit is contained in:
@@ -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 /` → `<h1>tf_registry v1.0.0</h1>`
|
|
||||||
|
|
||||||
### Ошибка: 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.
|
|
||||||
@@ -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` ✅
|
|
||||||
@@ -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-конфигах пользователей
|
|
||||||
@@ -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 в поиске файлов вида:
|
|
||||||
```
|
|
||||||
<hostname>/<namespace>/<name>/<version>/terraform-provider-<name>_<version>_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:<tag>`).
|
|
||||||
|
|
||||||
После 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 или переменные окружения.
|
|
||||||
@@ -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` (сейчас захардкожено).
|
|
||||||
@@ -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` |
|
|
||||||
Reference in New Issue
Block a user