639 lines
22 KiB
Markdown
639 lines
22 KiB
Markdown
# План миграции в Nubes Managed Kubernetes — Инструкции для агента
|
||
|
||
**Создан:** 2026-03-13 (Opus 4.6)
|
||
**Исполнитель:** Sonnet 4.6
|
||
**Статус:** Ожидает исполнения
|
||
|
||
> **ВАЖНО:** Этот документ — пошаговый план. Каждый пункт содержит:
|
||
> - ЧТО делать (цель)
|
||
> - ГДЕ делать (файлы)
|
||
> - КАК делать (конкретные инструкции)
|
||
> - ОГРАНИЧЕНИЯ (что нельзя трогать)
|
||
|
||
---
|
||
|
||
## Контекст
|
||
|
||
Terraform-провайдер Nubes Cloud сейчас работает на self-managed K8s (registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> <!-- ⛔ LEGACY: registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru -->).
|
||
Цель: подготовить инфраструктуру к передаче в Nubes Managed Kubernetes под управление их DevOps.
|
||
|
||
Nubes (nubes.ru) — российский cloud-провайдер, собственный DC Tier III (Москва), имеет Managed K8s, Harbor, S3.
|
||
|
||
**Репозиторий:** `/home/naeel/remote_dev/terraform`
|
||
|
||
**Обязательно прочитать перед работой:**
|
||
- `REPO_CONTENTS.md` — карта репозитория
|
||
- `.github/copilot-instructions.md` — правила работы (IMMUTABILITY POLICY)
|
||
- `docs/CODEBASE_ANALYSIS_AND_ROADMAP.md` — анализ кодовой базы
|
||
|
||
---
|
||
|
||
## Группа A: Подготовительные задачи (делать ПЕРВЫМИ)
|
||
|
||
### A1. Helm Chart для всех K8s-манифестов
|
||
|
||
**Цель:** Конвертировать raw YAML манифесты в Helm chart.
|
||
|
||
**Исходные файлы (ТОЛЬКО ЧИТАТЬ, НЕ МЕНЯТЬ):**
|
||
- `k8s/registry-deployment-new.yaml`
|
||
- `k8s/registry-ingress-new.yaml`
|
||
- `operator/manifests/00-namespace.yaml`
|
||
- `operator/manifests/00-rbac.yaml`
|
||
- `operator/manifests/02-crd.yaml`
|
||
- `operator/manifests/03-build-script.yaml`
|
||
- `operator/manifests/04-operator-deployment.yaml`
|
||
- `operator/manifests/05-registry-server.yaml`
|
||
- `operator/manifests/06-registry-server-docs.yaml`
|
||
|
||
**Создать:**
|
||
```
|
||
charts/
|
||
terraform-registry/
|
||
Chart.yaml
|
||
values.yaml
|
||
values-dev.yaml
|
||
values-prod.yaml
|
||
templates/
|
||
_helpers.tpl
|
||
namespace.yaml
|
||
rbac.yaml
|
||
crd.yaml
|
||
build-script-configmap.yaml
|
||
operator-deployment.yaml
|
||
registry-server-deployment.yaml
|
||
registry-server-service.yaml
|
||
docs-server-deployment.yaml (optional)
|
||
ingress.yaml
|
||
pdb.yaml
|
||
networkpolicy.yaml
|
||
```
|
||
|
||
**Требования к `values.yaml`:**
|
||
```yaml
|
||
global:
|
||
registryHostname: "registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru -->" # Переопределяется при миграции
|
||
namespace: "terraform-registry"
|
||
|
||
registry:
|
||
image:
|
||
repository: "naeel/terraform-registry-server" # → Harbor при миграции
|
||
tag: "latest"
|
||
pullPolicy: IfNotPresent
|
||
replicas: 1 # → 2 в prod
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 128Mi
|
||
limits:
|
||
cpu: 500m
|
||
memory: 256Mi
|
||
service:
|
||
port: 80
|
||
targetPort: 8080
|
||
healthcheck:
|
||
enabled: true
|
||
path: /healthz
|
||
port: 8080
|
||
|
||
operator:
|
||
image:
|
||
repository: "naeel/terraform-registry-operator"
|
||
tag: "latest"
|
||
replicas: 1
|
||
resources:
|
||
requests:
|
||
cpu: 50m
|
||
memory: 64Mi
|
||
limits:
|
||
cpu: 500m
|
||
memory: 128Mi
|
||
|
||
ingress:
|
||
enabled: true
|
||
className: "nginx"
|
||
host: "registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru -->" # Переопределяется
|
||
tls:
|
||
enabled: true
|
||
issuer: "letsencrypt-prod" # НЕ ТРОГАТЬ LetsEncrypt issuer!
|
||
secretName: "registry-tls"
|
||
annotations:
|
||
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||
|
||
s3:
|
||
endpoint: "s3.msk-1.ngcloud.ru"
|
||
bucket: "terraform-registry"
|
||
useSSL: true
|
||
# credentials через existingSecret
|
||
existingSecret: "s3-credentials"
|
||
accessKeyField: "access-key"
|
||
secretKeyField: "secret-key"
|
||
|
||
pdb:
|
||
enabled: false # → true в prod
|
||
minAvailable: 1
|
||
|
||
networkPolicy:
|
||
enabled: false # → true при миграции
|
||
```
|
||
|
||
**Требования к `values-dev.yaml`:**
|
||
```yaml
|
||
global:
|
||
registryHostname: "registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru -->"
|
||
registry:
|
||
replicas: 1
|
||
pdb:
|
||
enabled: false
|
||
```
|
||
|
||
**Требования к `values-prod.yaml`:**
|
||
```yaml
|
||
global:
|
||
registryHostname: "registry.nubes.ru" # Целевой домен
|
||
registry:
|
||
image:
|
||
repository: "pearlharbor.registryk8s.services.ngcloud.ru/terraform/registry-server"
|
||
replicas: 2
|
||
operator:
|
||
image:
|
||
repository: "pearlharbor.registryk8s.services.ngcloud.ru/terraform/registry-operator"
|
||
pdb:
|
||
enabled: true
|
||
minAvailable: 1
|
||
networkPolicy:
|
||
enabled: true
|
||
```
|
||
|
||
**Ограничения:**
|
||
- НЕ менять исходные YAML в `k8s/` и `operator/manifests/` (они могут ещё использоваться)
|
||
- НЕ трогать CRD-ресурсы с LetsEncrypt issuerRef
|
||
- НЕ запускать `helm install/upgrade` — только создать файлы
|
||
- Helm chart — НОВЫЕ файлы в `charts/` (APPEND ONLY)
|
||
|
||
---
|
||
|
||
### A2. Externalize hardcoded values
|
||
|
||
**Цель:** Убрать все hardcoded пути и домены, заменить на env vars.
|
||
|
||
**Файл 1: `internal/core/client.go` строка ~18**
|
||
```go
|
||
// СЕЙЧАС:
|
||
f, err := os.OpenFile("/home/naeel/terra/debug_nubes.log", ...)
|
||
|
||
// НОВЫЙ КОД (добавить новую функцию в КОНЕЦ файла):
|
||
func debugLogPath() string {
|
||
if p := os.Getenv("NUBES_DEBUG_LOG"); p != "" {
|
||
return p
|
||
}
|
||
return filepath.Join(os.TempDir(), "nubes_debug.log")
|
||
}
|
||
```
|
||
|
||
**Ограничение:** НЕ менять строку 18 напрямую. Добавить функцию `debugLogPath()` в КОНЕЦ файла. Спросить оператора перед заменой вызова.
|
||
|
||
**Файл 2: `internal/provider/provider.go` строка ~103**
|
||
```go
|
||
// СЕЙЧАС:
|
||
InsecureSkipVerify: true,
|
||
|
||
// НУЖНО: Сделать конфигурируемым через provider schema + env var
|
||
```
|
||
|
||
**Инструкция:**
|
||
1. Добавить атрибут `insecure` в schema провайдера (Optional, bool, default false)
|
||
2. Добавить чтение env var `NUBES_INSECURE`
|
||
3. InsecureSkipVerify = config_value || env_value || false
|
||
4. Код добавлять В КОНЕЦ секции Configure(), не рефакторить существующий
|
||
|
||
**Файл 3: `universal_rebuild/internal/provider/provider.go`**
|
||
- Проверить аналогичную проблему с InsecureSkipVerify
|
||
- Применить тот же паттерн
|
||
|
||
**Ограничения:**
|
||
- НЕ менять сигнатуры существующих функций
|
||
- Новый код — APPEND ONLY
|
||
- InsecureSkipVerify=false по умолчанию (breaking change для текущих юзеров — СПРОСИТЬ оператора)
|
||
|
||
---
|
||
|
||
### A3. Health endpoints для registry-server
|
||
|
||
**Цель:** Добавить `/healthz`, `/readyz`, `/metrics` endpoints.
|
||
|
||
**Файл:** `registry-server-build/main.go`
|
||
|
||
**Инструкция:**
|
||
1. Прочитать текущий `main.go` полностью
|
||
2. Добавить в КОНЕЦ файла (новые handler-функции):
|
||
```go
|
||
func healthzHandler(w http.ResponseWriter, r *http.Request) {
|
||
w.WriteHeader(http.StatusOK)
|
||
w.Write([]byte("ok"))
|
||
}
|
||
|
||
func readyzHandler(w http.ResponseWriter, r *http.Request) {
|
||
// Проверить доступность S3
|
||
w.WriteHeader(http.StatusOK)
|
||
w.Write([]byte("ok"))
|
||
}
|
||
```
|
||
3. Зарегистрировать handlers в main() — СПРОСИТЬ оператора перед добавлением в mux
|
||
|
||
**Ограничения:**
|
||
- НЕ менять существующие handlers
|
||
- НЕ запускать docker build
|
||
- Новые функции — APPEND ONLY
|
||
|
||
---
|
||
|
||
### A4. Operaционная документация
|
||
|
||
**Цель:** Создать набор операционных документов для DevOps Nubes.
|
||
|
||
**Создать файлы:**
|
||
|
||
**`docs/ops/RUNBOOK.md`:**
|
||
```markdown
|
||
# Runbook: Terraform Provider Registry
|
||
|
||
## Предпосылки
|
||
- Kubernetes cluster ≥ 1.27
|
||
- Helm ≥ 3.12
|
||
- Доступ к S3 (s3.msk-1.ngcloud.ru)
|
||
- Harbor registry (для образов)
|
||
|
||
## Установка
|
||
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
|
||
|
||
## Проверка здоровья
|
||
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 — хранилище артефактов (бинарники + документация)
|
||
```
|
||
|
||
**`docs/ops/TROUBLESHOOTING.md`:**
|
||
```markdown
|
||
# 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
|
||
```
|
||
|
||
**`docs/ops/MONITORING.md`:**
|
||
```markdown
|
||
# Мониторинг
|
||
|
||
## Ключевые метрики
|
||
- 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: (создать при установке мониторинга)
|
||
```
|
||
|
||
**`docs/ops/UPGRADE.md`:**
|
||
```markdown
|
||
# Процедура обновления
|
||
|
||
## 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
|
||
```
|
||
|
||
**`docs/ops/ROLLBACK.md`:**
|
||
```markdown
|
||
# Процедура отката
|
||
|
||
## Helm rollback
|
||
helm rollback terraform-registry <revision>
|
||
helm history terraform-registry -n terraform-registry
|
||
|
||
## Emergency: Direct image rollback
|
||
kubectl -n terraform-registry set image deployment/registry-server \
|
||
registry-server=<HARBOR>/terraform/registry-server:<PREV_TAG>
|
||
|
||
## S3 artifacts (immutable — откат не нужен)
|
||
Все версии provider binary хранятся бессрочно.
|
||
Удаление только вручную через s3cmd.
|
||
```
|
||
|
||
---
|
||
|
||
## Группа B: Инфраструктурная подготовка
|
||
|
||
### B1. Dockerfile оптимизация
|
||
|
||
**Цель:** Убедиться что Dockerfile для registry-server и operator готовы к Harbor.
|
||
|
||
**Инструкция:**
|
||
1. Прочитать `registry-server-build/` и `operator/build/`
|
||
2. Проверить что Dockerfile использует multi-stage build
|
||
3. Проверить что нет hardcoded путей
|
||
4. Убедиться что base image — official (golang:1.24 + alpine/scratch)
|
||
5. НЕ запускать docker build — только проверить файлы
|
||
|
||
**Создать (если отсутствует):** `registry-server-build/.dockerignore`, `operator/.dockerignore`
|
||
|
||
---
|
||
|
||
### B2. CI Pipeline definition
|
||
|
||
**Цель:** Создать файл CI pipeline (GitLab CI / Tekton) для автосборки.
|
||
|
||
**Создать:** `devops/ci/pipeline.yaml`
|
||
|
||
```yaml
|
||
# GitLab CI - пример (адаптировать под конкретный CI Nubes)
|
||
stages:
|
||
- test
|
||
- build
|
||
- sign
|
||
- publish
|
||
|
||
variables:
|
||
HARBOR_HOST: "pearlharbor.registryk8s.services.ngcloud.ru"
|
||
S3_BUCKET: "terraform-registry"
|
||
PROVIDER_NAME: "nubes"
|
||
PROVIDER_NAMESPACE: "nubes"
|
||
|
||
test:
|
||
stage: test
|
||
image: golang:1.24
|
||
script:
|
||
- cd universal_rebuild
|
||
- go test ./...
|
||
- go vet ./...
|
||
|
||
build-provider:
|
||
stage: build
|
||
image: golang:1.24
|
||
script:
|
||
- cd universal_rebuild
|
||
- GOOS=linux GOARCH=amd64 go build -o bin/terraform-provider-${PROVIDER_NAME}_linux_amd64
|
||
- GOOS=darwin GOARCH=amd64 go build -o bin/terraform-provider-${PROVIDER_NAME}_darwin_amd64
|
||
- GOOS=windows GOARCH=amd64 go build -o bin/terraform-provider-${PROVIDER_NAME}_windows_amd64.exe
|
||
artifacts:
|
||
paths: [universal_rebuild/bin/]
|
||
|
||
build-images:
|
||
stage: build
|
||
script:
|
||
- docker build -t ${HARBOR_HOST}/terraform/registry-server:${CI_COMMIT_TAG} registry-server-build/
|
||
- docker build -t ${HARBOR_HOST}/terraform/registry-operator:${CI_COMMIT_TAG} operator/
|
||
- docker push ${HARBOR_HOST}/terraform/registry-server:${CI_COMMIT_TAG}
|
||
- docker push ${HARBOR_HOST}/terraform/registry-operator:${CI_COMMIT_TAG}
|
||
|
||
sign:
|
||
stage: sign
|
||
script:
|
||
- cd universal_rebuild/bin
|
||
- sha256sum terraform-provider-* > SHA256SUMS
|
||
- gpg --import $GPG_PRIVATE_KEY
|
||
- gpg --detach-sign SHA256SUMS
|
||
|
||
publish-to-s3:
|
||
stage: publish
|
||
script:
|
||
- s3cmd put bin/* s3://${S3_BUCKET}/terraform-providers/...
|
||
```
|
||
|
||
---
|
||
|
||
### B3. NetworkPolicy template
|
||
|
||
**Цель:** Подготовить NetworkPolicy для изоляции namespace.
|
||
|
||
**Включить в Helm chart:** `charts/terraform-registry/templates/networkpolicy.yaml`
|
||
|
||
```yaml
|
||
{{- if .Values.networkPolicy.enabled }}
|
||
apiVersion: networking.k8s.io/v1
|
||
kind: NetworkPolicy
|
||
metadata:
|
||
name: {{ include "terraform-registry.fullname" . }}-netpol
|
||
namespace: {{ .Values.global.namespace }}
|
||
spec:
|
||
podSelector: {}
|
||
policyTypes:
|
||
- Ingress
|
||
- Egress
|
||
ingress:
|
||
- from:
|
||
- namespaceSelector:
|
||
matchLabels:
|
||
kubernetes.io/metadata.name: ingress-nginx
|
||
ports:
|
||
- port: {{ .Values.registry.service.targetPort }}
|
||
protocol: TCP
|
||
egress:
|
||
- to: []
|
||
ports:
|
||
- port: 443 # S3, Vault
|
||
protocol: TCP
|
||
- port: 53 # DNS
|
||
protocol: UDP
|
||
- port: 53
|
||
protocol: TCP
|
||
{{- end }}
|
||
```
|
||
|
||
---
|
||
|
||
## Группа C: Domain Migration Plan
|
||
|
||
### C1. Domain migration (порядок действий)
|
||
|
||
**Это НЕ код — это инструкция для DevOps. Записать в `docs/ops/DOMAIN_MIGRATION.md`:**
|
||
|
||
```markdown
|
||
# Миграция домена registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> → registry.nubes.ru
|
||
|
||
## Фаза 1: Dual-domain (параллельная работа)
|
||
1. Настроить Ingress с двумя hosts: registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> + registry.nubes.ru
|
||
2. Оба домена указывают на один Registry Server
|
||
3. Обновить provider main.go: Address → registry.nubes.ru
|
||
4. Старый адрес registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> продолжает работать
|
||
|
||
## Фаза 2: Миграция клиентов
|
||
1. Документировать новый registry address для пользователей
|
||
2. .terraformrc mirror config для переходного периода:
|
||
provider_installation {
|
||
direct {
|
||
exclude = ["registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru -->/*/*"]
|
||
}
|
||
network_mirror {
|
||
url = "https://registry.nubes.ru/v1/providers/"
|
||
}
|
||
}
|
||
|
||
## Фаза 3: Редирект
|
||
1. registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> Ingress → 301 redirect на registry.nubes.ru
|
||
2. Мониторинг: отслеживать запросы на старый домен
|
||
|
||
## Фаза 4: Деком (через 6+ месяцев)
|
||
1. Убрать registry.kube5s.ru <!-- ⛔ LEGACY: registry.kube5s.ru ЗАКРЫТ. Актуальный хост: tf-registry.containerk8s.services.ngcloud.ru --> из Ingress
|
||
2. DNS → удалить A/CNAME запись
|
||
```
|
||
|
||
---
|
||
|
||
## Группа D: Code Quality (из CODEBASE_ANALYSIS_AND_ROADMAP.md)
|
||
|
||
### D1. Deprecated-маркеры для legacy CreateGenericInstance
|
||
|
||
**Файл:** `internal/core/client.go`
|
||
|
||
**Инструкция:** Добавить КОММЕНТАРИИ (не код) перед каждым методом V1-V5:
|
||
```go
|
||
// Deprecated: Use CreateGenericInstanceUniversalV5 instead.
|
||
// This method is kept for backward compatibility and will be removed in v3.0.
|
||
func (c *UniversalClient) CreateGenericInstance(...) ...
|
||
```
|
||
|
||
**Методы для пометки:**
|
||
- `CreateGenericInstance` (V1)
|
||
- `CreateGenericInstanceUniversal` (V2)
|
||
- `CreateGenericInstanceUniversalV2` (V3)
|
||
- `CreateGenericInstanceUniversalV3` (V4)
|
||
- `CreateGenericInstanceUniversalV4` (V5)
|
||
|
||
**Ограничения:** ТОЛЬКО комментарии. НЕ менять код методов. НЕ удалять.
|
||
|
||
---
|
||
|
||
### D2. .gitignore для secrets
|
||
|
||
**Файл:** `.gitignore` (корень репозитория)
|
||
|
||
**Добавить в КОНЕЦ файла:**
|
||
```gitignore
|
||
# Secrets (should be in Vault, not in git)
|
||
secrets/*.asc
|
||
secrets/*.token
|
||
secrets/*.key
|
||
!secrets/.gitkeep
|
||
```
|
||
|
||
**Создать:** `secrets/.gitkeep` (пустой файл, чтобы директория осталась в git)
|
||
|
||
---
|
||
|
||
### D3. Unit tests для core layer
|
||
|
||
**Цель:** Создать минимальный набор тестов.
|
||
|
||
**Создать файлы:**
|
||
- `universal_rebuild/internal/core/client_test.go`
|
||
- `universal_rebuild/internal/resources_core/crud_test.go`
|
||
|
||
**Минимальные тесты для `client_test.go`:**
|
||
- `TestNormalizeValue_EmptyString`
|
||
- `TestNormalizeValue_NullString`
|
||
- `TestNormalizeValue_MapType`
|
||
- `TestNormalizeValue_ArrayType`
|
||
- `TestNormalizeValue_TrimSpace`
|
||
|
||
**Минимальные тесты для `crud_test.go`:**
|
||
- `TestIsStatusSuspended`
|
||
- `TestIsStatusNonAdoptable`
|
||
- `TestDeleteBehaviorDefault`
|
||
|
||
**Ограничения:**
|
||
- Тесты — НОВЫЕ файлы (не менять существующие)
|
||
- Использовать стандартный `testing` пакет Go
|
||
- НЕ запускать тесты (`go test`) без разрешения оператора
|
||
|
||
---
|
||
|
||
## Порядок выполнения
|
||
|
||
```
|
||
ФАЗА 0 (быстрые wins):
|
||
D1 → Deprecated комментарии [5 мин]
|
||
D2 → .gitignore для secrets [2 мин]
|
||
A2 → debugLogPath() function [10 мин]
|
||
|
||
ФАЗА 1 (Helm chart):
|
||
A1 → Полный Helm chart [30-60 мин]
|
||
|
||
ФАЗА 2 (Ops docs):
|
||
A4 → RUNBOOK, TROUBLESHOOTING и др. [20 мин]
|
||
C1 → DOMAIN_MIGRATION.md [10 мин]
|
||
|
||
ФАЗА 3 (Code quality):
|
||
D3 → Unit tests [30 мин]
|
||
A3 → Health endpoints [15 мин]
|
||
|
||
ФАЗА 4 (CI/CD):
|
||
B2 → CI pipeline definition [15 мин]
|
||
B1 → Dockerfile audit [10 мин]
|
||
```
|
||
|
||
---
|
||
|
||
## Правила для агента (напоминание)
|
||
|
||
1. **IMMUTABILITY POLICY** — НЕ менять существующий рабочий код
|
||
2. **APPEND ONLY** — новый код только в конец файла
|
||
3. **Комментарии — ЭТО НЕ ПРАВКА КОДА**, их можно и нужно добавлять
|
||
4. **НЕ запускать** docker build, kubectl apply, helm install
|
||
5. **НЕ трогать** ресурсы с LetsEncrypt issuerRef
|
||
6. **Спрашивать разрешения** перед изменением сигнатур функций
|
||
7. **Secrets в коде** — КАТЕГОРИЧЕСКИ нет
|
||
8. **Перед любой работой** — прочитать `REPO_CONTENTS.md`
|
||
9. **Файлы в `internal/resources_gen/`** — НЕ МЕНЯТЬ ВРУЧНУЮ (только через генератор)
|
||
10. **Минимальные ресурсы** — при создании K8s ресурсов ставить минимальный CPU/memory
|