add: documentation
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Миграция домена terra.k8c.ru → registry.nubes.ru
|
||||
|
||||
## Фаза 1: Dual-domain (параллельная работа)
|
||||
1. Настроить Ingress с двумя hosts: `terra.k8c.ru` + `registry.nubes.ru`
|
||||
2. Оба домена указывают на один Registry Server
|
||||
3. Обновить provider `main.go`: Address → `registry.nubes.ru`
|
||||
4. Старый адрес `terra.k8c.ru` продолжает работать
|
||||
|
||||
## Фаза 2: Миграция клиентов
|
||||
1. Документировать новый registry address для пользователей
|
||||
2. `.terraformrc` mirror config для переходного периода:
|
||||
```hcl
|
||||
provider_installation {
|
||||
direct {
|
||||
exclude = ["terra.k8c.ru/*/*"]
|
||||
}
|
||||
network_mirror {
|
||||
url = "https://registry.nubes.ru/v1/providers/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Фаза 3: Редирект
|
||||
1. `terra.k8c.ru` Ingress → 301 redirect на `registry.nubes.ru`
|
||||
2. Мониторинг: отслеживать запросы на старый домен
|
||||
|
||||
## Фаза 4: Деком (через 6+ месяцев)
|
||||
1. Убрать `terra.k8c.ru` из Ingress
|
||||
2. DNS → удалить A/CNAME запись
|
||||
@@ -0,0 +1,16 @@
|
||||
# Мониторинг
|
||||
|
||||
## Ключевые метрики
|
||||
- `registry_http_requests_total` — кол-во запросов к registry
|
||||
- `registry_http_request_duration_seconds` — latency
|
||||
- `registry_s3_operations_total` — операции с S3
|
||||
- `registry_s3_errors_total` — ошибки S3
|
||||
|
||||
## Алерты (Prometheus)
|
||||
- **RegistryDown**: `up == 0` (>2 min)
|
||||
- **RegistryHighLatency**: `p99 > 5s` (>5 min)
|
||||
- **RegistryS3Errors**: `rate > 0.1/s` (>5 min)
|
||||
- **RegistryPodRestart**: увеличение restart count
|
||||
|
||||
## Grafana Dashboard
|
||||
- Import dashboard ID: (создать при установке мониторинга)
|
||||
@@ -0,0 +1,17 @@
|
||||
# Процедура отката
|
||||
|
||||
## Helm rollback
|
||||
```bash
|
||||
helm rollback terraform-registry <revision>
|
||||
helm history terraform-registry -n terraform-registry
|
||||
```
|
||||
|
||||
## Emergency: Direct image rollback
|
||||
```bash
|
||||
kubectl -n terraform-registry set image deployment/registry-server \
|
||||
registry-server=<HARBOR>/terraform/registry-server:<PREV_TAG>
|
||||
```
|
||||
|
||||
## S3 artifacts (immutable — откат не нужен)
|
||||
Все версии provider binary хранятся бессрочно.
|
||||
Удаление только вручную через `s3cmd`.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Runbook: Terraform Provider Registry
|
||||
|
||||
## Предпосылки
|
||||
- Kubernetes cluster ≥ 1.27
|
||||
- Helm ≥ 3.12
|
||||
- Доступ к S3 (s3.msk-1.ngcloud.ru)
|
||||
- Harbor registry (для образов)
|
||||
|
||||
## Установка
|
||||
```bash
|
||||
helm install terraform-registry ./charts/terraform-registry \
|
||||
-f charts/terraform-registry/values-prod.yaml \
|
||||
-n terraform-registry --create-namespace
|
||||
```
|
||||
|
||||
## Обновление версии
|
||||
1. Собрать новый образ (CI pipeline)
|
||||
2. Обновить tag в values
|
||||
3. `helm upgrade terraform-registry ./charts/terraform-registry -f values-prod.yaml`
|
||||
|
||||
## Проверка здоровья
|
||||
```bash
|
||||
kubectl -n terraform-registry get pods
|
||||
curl https://<REGISTRY_HOST>/healthz
|
||||
curl https://<REGISTRY_HOST>/.well-known/terraform.json
|
||||
```
|
||||
|
||||
## Компоненты
|
||||
- **Registry Server** — HTTP-сервер протокола Terraform Registry
|
||||
- **Operator** — K8s controller для сборки provider binaries
|
||||
- **S3** — хранилище артефактов (бинарники + документация)
|
||||
@@ -0,0 +1,23 @@
|
||||
# Troubleshooting
|
||||
|
||||
## Registry Server не отвечает
|
||||
1. `kubectl -n terraform-registry get pods -l app=registry-server`
|
||||
2. `kubectl -n terraform-registry logs -l app=registry-server --tail=100`
|
||||
3. Проверить ingress: `kubectl get ingress -n terraform-registry`
|
||||
4. Проверить S3: `curl -s https://s3.msk-1.ngcloud.ru` (bucket access)
|
||||
|
||||
## Provider binary не скачивается
|
||||
1. Проверить наличие в S3: `s3cmd ls s3://terraform-registry/terraform-providers/...`
|
||||
2. Проверить SHA256SUMS сигнатуру
|
||||
3. Проверить GPG ключ
|
||||
|
||||
## Operator не создаёт build job
|
||||
1. `kubectl -n terraform-registry get terraformproviderrelease`
|
||||
2. `kubectl -n terraform-registry describe terraformproviderrelease <name>`
|
||||
3. `kubectl -n terraform-registry get jobs`
|
||||
4. Проверить RBAC: operator ServiceAccount должен иметь права на jobs и secrets
|
||||
|
||||
## TLS / Certificate проблемы
|
||||
- Проверить cert-manager: `kubectl get certificates -n terraform-registry`
|
||||
- ⚠️ НЕ пересоздавать certificates с LetsEncrypt issuer (rate limits!)
|
||||
- Для отладки использовать self-signed issuer
|
||||
@@ -0,0 +1,18 @@
|
||||
# Процедура обновления
|
||||
|
||||
## Provider version update (без downtime)
|
||||
1. CI собирает новый provider binary
|
||||
2. Создать TerraformProviderRelease CR с новой версией
|
||||
3. Operator создаёт build job → артефакты в S3
|
||||
4. Старые версии остаются доступны (immutable artifacts)
|
||||
|
||||
## Registry Server update (rolling)
|
||||
1. Обновить image tag в Helm values
|
||||
2. `helm upgrade --set registry.image.tag=<new> terraform-registry ./charts/...`
|
||||
3. Проверить: `kubectl rollout status deployment/registry-server -n terraform-registry`
|
||||
4. Rollback: `helm rollback terraform-registry 1`
|
||||
|
||||
## Operator update
|
||||
1. Обновить operator image tag
|
||||
2. `helm upgrade ...`
|
||||
3. Проверить CRD compatibility: `kubectl get crd terraformproviderreleases.terra.core.nubes.ru`
|
||||
@@ -0,0 +1,168 @@
|
||||
# План: валидация параметров с выбором из списка
|
||||
|
||||
Дата составления: 2026-03-25
|
||||
Версия провайдера на момент анализа: **5.0.38**
|
||||
|
||||
---
|
||||
|
||||
## 1. Типы "списочной" валидации в провайдере
|
||||
|
||||
В YAML-метаданных сервисов существует три механизма указания допустимых значений параметра:
|
||||
|
||||
| Механизм в YAML | Где проверяется в коде | Статус |
|
||||
|---|---|---|
|
||||
| `value_list: [...]` | `appendLocalPlanInputDiagnostics` | ✅ Работает |
|
||||
| `ref_svc_id: N` | `appendRemotePlanInputDiagnostics` → `ListRefServiceInstances` | ✅ Работает (исправлено в 5.0.38) |
|
||||
| `func: getAvailableResourceRealms` | `ListAvailableResourceRealms` | ❌ Отключено (баг бэкенда) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Инвентаризация: какие сервисы и параметры затронуты
|
||||
|
||||
### 2.1 Параметры с `ref_svc_id` (живые данные из API)
|
||||
|
||||
| YAML файл | Ресурс | Param code | Param ID | ref_svc_id | Что ссылается |
|
||||
|---|---|---|---|---|---|
|
||||
| `13_s3bucket.yaml` | s3bucket | `s3UserUid` | 124 | **12** (S3) | UUID корневого S3-инстанса |
|
||||
| `23_vc_vm.yaml` | vc_vm | `vappUid` | — | **26** (vApp) | UUID vApp-инстанса |
|
||||
| `28_vc_vm_v3.yaml` | vc_vm_v3 | `vappUid` | — | **26** (vApp) | UUID vApp-инстанса |
|
||||
| `29_vc_vdc_group.yaml` | vc_vdc_group | `vdcUid` | 618 (create) | **21** (VDC) | UUID VDC-инстанса |
|
||||
| `29_vc_vdc_group.yaml` | vc_vdc_group | `vdcUid` | 619 (add_vdc) | **21** (VDC) | UUID VDC-инстанса |
|
||||
| `90_postgres.yaml` | postgres | `s3Uid` | — | **12** (S3) | UUID S3-инстанса под backup |
|
||||
| `99_gitea.yaml` | gitea | `psqlUid` | 238 | **90** (Postgres) | UUID Postgres-инстанса |
|
||||
| `111_dnsrecord.yaml` | dnsrecord | `zoneUid` | 75 | **110** (DNS Zone) | UUID DNS-зоны |
|
||||
|
||||
**Итого уникальных svcId в ref_svc_id:** 12 (S3), 21 (VDC), 26 (vApp), 90 (Postgres), 110 (DNS Zone)
|
||||
|
||||
### 2.2 Параметры с `value_list` (статический enum)
|
||||
|
||||
| YAML файл | Ресурс | Параметры |
|
||||
|---|---|---|
|
||||
| `13_s3bucket.yaml` | s3bucket | `readAll`, `listAll`, `corsAll`, `placement` |
|
||||
| `23_vc_vm.yaml` | vc_vm | `templateName` (образ ВМ) |
|
||||
| `28_vc_vm_v3.yaml` | vc_vm_v3 | аналогично |
|
||||
| `90_postgres.yaml` | postgres | множество: версия PG, тип развёртки, charset, пр. |
|
||||
| `111_dnsrecord.yaml` | dnsrecord | `recordType` (A, AAAA, CNAME, MX, PTR...) |
|
||||
| `113_vc_complex.yaml` | vc_complex | есть |
|
||||
| `116_kafka.yaml` | kafka | `resourceInstances` (1-5), `needExternalAddressMaster` |
|
||||
|
||||
### 2.3 Параметры с `func: getAvailableResourceRealms`
|
||||
|
||||
| YAML файл | Param code | Статус |
|
||||
|---|---|---|
|
||||
| `116_kafka.yaml` | `resourceRealm` | ❌ Не проверяется — бэкенд-баг |
|
||||
| (возможно другие) | `resourceRealm` | ❌ Аналогично |
|
||||
|
||||
---
|
||||
|
||||
## 3. Текущие проблемы и риски
|
||||
|
||||
### 3.1 ⚠️ КРИТИЧЕСКИЙ РИСК: `explainedStatus` в paginated list
|
||||
|
||||
**Проблема:** В 5.0.38 добавлен фильтр:
|
||||
```go
|
||||
if item.IsDeleted || !strings.EqualFold(strings.TrimSpace(item.ExplainedStatus), "running") {
|
||||
continue
|
||||
}
|
||||
```
|
||||
|
||||
`ListRefServiceInstances` использует endpoint `/instances?page=X&size=100` — это **paginated list**, а не individual GET.
|
||||
|
||||
**Вопрос под верификацию:** Возвращает ли `/instances?page=1&size=100` поле `explainedStatus` для каждого элемента?
|
||||
|
||||
- Если **ДА** — 5.0.38 работает корректно.
|
||||
- Если **НЕТ** — `ExplainedStatus` будет `""` для всех элементов, условие `"" != "running"` → `true`, все инстансы будут отфильтрованы → план покажет **пустой список** для любого `ref_svc_id` параметра.
|
||||
|
||||
**Как проверить:**
|
||||
```bash
|
||||
TOKEN=$(cat secrets/test.token)
|
||||
curl -s -H "Authorization: Bearer $TOKEN" \
|
||||
"https://deck-api-test.ngcloud.ru/api/v1/index.cfm/instances?page=1&size=5" \
|
||||
| python3 -m json.tool | grep -E "instanceUid|explainedStatus|isDeleted" | head -20
|
||||
```
|
||||
|
||||
**Возможные решения при негативном результате:**
|
||||
- **Вариант A (рекомендуется):** Убрать фильтр по `explainedStatus`, оставить только `isDeleted=false` в query-параметре. Простое и надёжное решение.
|
||||
- **Вариант B:** Добавить `svcId=N` в запрос (если API поддерживает) — тогда можно запросить только нужный сервис + isDeleted=false, и не нужен фильтр по статусу.
|
||||
- **Вариант C:** Делать individual GET `/instances/{uid}` для каждого найденного инстанса — тяжело, не масштабируется.
|
||||
|
||||
### 3.2 `resource_realm` валидация отключена (ожидает бэкенд-фикса)
|
||||
|
||||
**Статус:** Удалена в 5.0.36, TODO в `resource_diagnostics_required.go`.
|
||||
|
||||
**Когда: после того как бэкенд исправит `available_resource_realms.cfc` строка 79:**
|
||||
```cfml
|
||||
<cfset "out.arпuments"=#arguments#/> ← заменить "п" на "p"
|
||||
```
|
||||
|
||||
**Действие:** Восстановить realm-блок в `appendRemotePlanInputDiagnostics`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Что уже работает сейчас (5.0.38)
|
||||
|
||||
| Механизм | Работает? | Поведение |
|
||||
|---|---|---|
|
||||
| `value_list` — ошибочное значение | ✅ | `AddError` + список допустимых |
|
||||
| `value_list` — верное значение | ✅ | Нет ошибок |
|
||||
| `ref_svc_id` — ошибочный UUID | ✅ | `AddError` + список UUID (только running) |
|
||||
| `ref_svc_id` — верный UUID | ✅ | `AddWarning` с описанием (показывает список) |
|
||||
| `ref_svc_id` — API недоступно | ✅ | `AddWarning` "проверка пропущена" |
|
||||
| `resource_realm` | ❌ | Не проверяется, TODO |
|
||||
|
||||
---
|
||||
|
||||
## 5. Шаги для выполнения (упорядочены по приоритету)
|
||||
|
||||
### Шаг 1: Верифицировать 5.0.38 — `explainedStatus` в paginated list
|
||||
**Приоритет: ВЫСОКИЙ (перед любыми следующими шагами)**
|
||||
|
||||
Запустить curl (см. п. 3.1). По результату:
|
||||
- Если `explainedStatus` есть → 5.0.38 корректен, идти к шагу 2.
|
||||
- Если `explainedStatus` отсутствует → применить Вариант A или B из п. 3.1, выпустить 5.0.39.
|
||||
|
||||
### Шаг 2: Добавить `svcId` фильтр в `ListRefServiceInstances`
|
||||
**Приоритет: СРЕДНИЙ (оптимизация)**
|
||||
|
||||
Сейчас функция запрашивает `/instances?page=X&size=100` — ВСЕ инстансы всех сервисов, потом фильтрует в Go по `ServiceId`. Это неэффективно при большом количестве инстансов.
|
||||
|
||||
Лучше: `/instances?page=X&size=100&svcId=N&isDeleted=false`
|
||||
|
||||
Правка в: `universal_rebuild/internal/core/refsvc_resolve.go`
|
||||
```go
|
||||
// Было:
|
||||
path := fmt.Sprintf("/instances?page=%d&size=100&isDeleted=false", page)
|
||||
// Стало:
|
||||
path := fmt.Sprintf("/instances?page=%d&size=100&svcId=%d&isDeleted=false", page, serviceId)
|
||||
```
|
||||
|
||||
**Нужно верифицировать, что API поддерживает `svcId` в paginated endpoint** (не только в flat list).
|
||||
|
||||
### Шаг 3: Восстановить `resource_realm` валидацию
|
||||
**Приоритет: НИЗКИЙ (зависит от бэкенда)**
|
||||
|
||||
После исправления бэкендом:
|
||||
1. Убрать TODO в `appendRemotePlanInputDiagnostics`
|
||||
2. Восстановить блок realm-проверки
|
||||
3. Проверить что `/resourceRealms/available?svcId=N` возвращает 200
|
||||
4. Выпустить следующую версию
|
||||
|
||||
---
|
||||
|
||||
## 6. Файлы, которые не требуют изменений
|
||||
|
||||
- `value_list` — работает идеально, код трогать не нужно
|
||||
- `params_validation_mapping.go` — структура корректна
|
||||
- `resource_diagnostics_required.go` — логика верна кроме realm-блока
|
||||
- Все `resources_gen/*` — не трогать (генерируются)
|
||||
|
||||
---
|
||||
|
||||
## 7. Связанные файлы коде
|
||||
|
||||
| Файл | Роль |
|
||||
|---|---|
|
||||
| `universal_rebuild/internal/core/refsvc_resolve.go` | `ListRefServiceInstances` — запрос инстансов для ref_svc_id |
|
||||
| `universal_rebuild/internal/resources_core/resource_diagnostics_required.go` | Логика всех plan-проверок |
|
||||
| `universal_rebuild/internal/resources_core/params_validation_mapping.go` | Загрузка YAML-метаданных валидации |
|
||||
| `devops/profiles/test/generated/resources_yaml/` | YAML-метаданные всех сервисов |
|
||||
Reference in New Issue
Block a user