fix(postgres): исправлен api_endpoint nubes, try() для vault_secrets, стресс-скрипт, документация ошибок
This commit is contained in:
@@ -4,6 +4,85 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-03-20 — Баг: неверный hostname в api_endpoint провайдера nubes
|
||||||
|
|
||||||
|
### Симптом
|
||||||
|
`terraform apply` на `examples/POSTGRES` падал с HTTP 404 на обоих ресурсах: `nubes_postgres.npg` и `nubes_s3bucket.baba_bucket`.
|
||||||
|
|
||||||
|
### Причина
|
||||||
|
В `examples/POSTGRES/main.tf` был указан UI-домен вместо API-домена:
|
||||||
|
```hcl
|
||||||
|
# НЕПРАВИЛЬНО (UI облака, не API):
|
||||||
|
api_endpoint = "https://deck-test.ngcloud.ru/api/v1"
|
||||||
|
|
||||||
|
# ПРАВИЛЬНО (API Dashboard):
|
||||||
|
api_endpoint = "https://deck-api-test.ngcloud.ru/api/v1/index.cfm"
|
||||||
|
```
|
||||||
|
Аналогично для `nubes_endpoint` в провайдере `sless`.
|
||||||
|
|
||||||
|
### Фикс
|
||||||
|
`deck-test` → `deck-api-test` в обоих провайдерах, добавлен `/index.cfm`.
|
||||||
|
Найдено через `git show cca3a8c:examples/POSTGRES/main.tf`.
|
||||||
|
|
||||||
|
### Правило
|
||||||
|
> `deck-api-test.ngcloud.ru` — API (для Terraform)
|
||||||
|
> `deck-test.ngcloud.ru` — UI облака (только браузер)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-20 — Баг платформы: nubes_postgres_user/database зависают при destroy
|
||||||
|
|
||||||
|
### Симптом
|
||||||
|
`terraform destroy` завершается, но в UI облака операция `delete_user` возвращает:
|
||||||
|
> "Не удалось удалить пользователя из CRD. Производится откат"
|
||||||
|
|
||||||
|
После этого повторный `terraform apply` падает с:
|
||||||
|
> "Нарушена консистентность: Операция вернула duplicate/exist, но объект не найден в state_out"
|
||||||
|
|
||||||
|
### Причина
|
||||||
|
Платформенный баг: delete_user не удаляет CRD в кластере Kubernetes PG-оператора.
|
||||||
|
База `db0` остаётся "мёртвой" — API не видит, но в кластере CRD есть.
|
||||||
|
`adopt_existing_on_create = true` не помогает — провайдер получает `duplicate` но не может прочитать объект обратно.
|
||||||
|
|
||||||
|
### Решение (workaround)
|
||||||
|
Удалить PG-инстанс вручную через UI облака → почистить state → пересоздать через `terraform apply`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/terra/sless/examples/POSTGRES
|
||||||
|
terraform state rm nubes_postgres_database.db
|
||||||
|
terraform state rm nubes_postgres_user.pg_user
|
||||||
|
terraform state rm nubes_postgres.npg
|
||||||
|
terraform apply -auto-approve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Статус
|
||||||
|
Зафиксировано как баг платформы. Передано девопсам для исправления в CRD-операторе PG.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-20 — Invalid index: vault_secrets["users"] на первом apply
|
||||||
|
|
||||||
|
### Симптом
|
||||||
|
```
|
||||||
|
Error: Invalid index
|
||||||
|
on postgres.tf line 7, in locals:
|
||||||
|
7: pg_creds_map = jsondecode(nubes_postgres.npg.vault_secrets["users"])
|
||||||
|
The given key does not identify an element in this collection value.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Причина
|
||||||
|
`vault_secrets["users"]` появляется только **после** создания первого пользователя.
|
||||||
|
На первом `plan/apply` ключ ещё не существует.
|
||||||
|
|
||||||
|
### Фикс
|
||||||
|
```hcl
|
||||||
|
pg_creds_map = try(jsondecode(lookup(nubes_postgres.npg.vault_secrets, "users", "{}")), {})
|
||||||
|
pg_password = try(local.pg_creds_map[local.pg_username]["password"], "")
|
||||||
|
```
|
||||||
|
Пароль подтягивается при следующем `apply` после создания пользователя.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-03-17 — Баг 3: PodLogOptions compile error (v0.1.31)
|
## 2026-03-17 — Баг 3: PodLogOptions compile error (v0.1.31)
|
||||||
|
|
||||||
**Проблема:** Оператор не компилировался. Ошибка:
|
**Проблема:** Оператор не компилировался. Ошибка:
|
||||||
|
|||||||
@@ -51,6 +51,15 @@
|
|||||||
| `naeel/sless-runtime-python3.11:latest` | Base runtime для python3.11 функций |
|
| `naeel/sless-runtime-python3.11:latest` | Base runtime для python3.11 функций |
|
||||||
| `naeel/sless-default-hello:latest` | Пример собранной функции (kaniko) |
|
| `naeel/sless-default-hello:latest` | Пример собранной функции (kaniko) |
|
||||||
|
|
||||||
|
## Nubes Cloud endpoints
|
||||||
|
|
||||||
|
> **Не путать** — оба домена похожи, но разные назначения:
|
||||||
|
|
||||||
|
| URL | Назначение |
|
||||||
|
|-----|------------|
|
||||||
|
| `https://deck-api-test.ngcloud.ru/api/v1/index.cfm` | **API Dashboard** — используется в Terraform-провайдерах (`nubes`, `sless → nubes_endpoint`). Без `/index.cfm` — 404. |
|
||||||
|
| `https://deck-test.ngcloud.ru/` | **UI облака** — только браузер, в Terraform не использовать |
|
||||||
|
|
||||||
## Мониторинг
|
## Мониторинг
|
||||||
|
|
||||||
- Victoria Metrics — в кластере
|
- Victoria Metrics — в кластере
|
||||||
|
|||||||
+28
-1
@@ -1,9 +1,36 @@
|
|||||||
# Прогресс разработки
|
# Прогресс разработки
|
||||||
|
|
||||||
Последнее обновление: 2026-03-20 17:00
|
Последнее обновление: 2026-03-20 21:30
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-03-20 — Восстановление PostgreSQL и отладка провайдера nubes
|
||||||
|
|
||||||
|
### Что произошло
|
||||||
|
1. Старый PG-инстанс (`teststand-pg-2`) был удалён. Девопсы позднее вернули PG под именем `pg-sless-demo`.
|
||||||
|
2. Обнаружен неверный `api_endpoint` в провайдере nubes: `deck-test` вместо `deck-api-test` → 404 на всех ресурсах.
|
||||||
|
3. Исправлен `nubes_endpoint` в провайдере `sless` — та же проблема.
|
||||||
|
4. Обнаружен баг платформы: `delete_user` не удаляет CRD → база/пользователь зависают в кластере → повторный `apply` падает с "нарушена консистентность".
|
||||||
|
5. Workaround: ручное удаление PG через UI + `terraform state rm` + пересоздание.
|
||||||
|
|
||||||
|
### Изменения в файлах
|
||||||
|
| Файл | Что изменено |
|
||||||
|
|------|-------------|
|
||||||
|
| `examples/POSTGRES/main.tf` | Исправлен `api_endpoint` и `nubes_endpoint` → `deck-api-test.ngcloud.ru` в обоих провайдерах |
|
||||||
|
| `examples/POSTGRES/postgres.tf` | `try()`-обёртка для `vault_secrets["users"]`; `resource_name = "pg-sless-demo"` |
|
||||||
|
| `examples/POSTGRES/stress_destroy_apply.sh` | Новый скрипт: 5 итераций destroy+apply с логами и остановкой при ошибке |
|
||||||
|
| `doc/infrastructure/overview.md` | Добавлена таблица Nubes endpoints (API vs UI) |
|
||||||
|
| `doc/errors/log.md` | Задокументированы 3 новые ошибки |
|
||||||
|
|
||||||
|
### Статус
|
||||||
|
- ✅ Провайдер nubes работает с правильным endpoint
|
||||||
|
- ✅ PG пересоздан и managed через terraform
|
||||||
|
- ⏳ Стресс-тест (stress_destroy_apply.sh) — в процессе, выявлен баг платформы
|
||||||
|
- 📋 TODO: убрать `sless_function`, встроить в `sless_job`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-20 — Архитектурный рефакторинг: sless_function + sless_service (ветка feat/function-service-split)
|
## 2026-03-20 — Архитектурный рефакторинг: sless_function + sless_service (ветка feat/function-service-split)
|
||||||
|
|
||||||
### Цель
|
### Цель
|
||||||
|
|||||||
@@ -45,14 +45,18 @@ variable "pg_password" {
|
|||||||
description = "Только для сверки. Реальный пароль из vault_secrets. Должен совпадать с tfvars."
|
description = "Только для сверки. Реальный пароль из vault_secrets. Должен совпадать с tfvars."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Nubes endpoints — не путать:
|
||||||
|
# API Dashboard (для Terraform-провайдеров): https://deck-api-test.ngcloud.ru/api/v1/index.cfm
|
||||||
|
# UI облака (только браузер, не для кода): https://deck-test.ngcloud.ru/
|
||||||
|
# ВАЖНО: nubes и sless провайдеры требуют API endpoint, НЕ UI!
|
||||||
provider "nubes" {
|
provider "nubes" {
|
||||||
api_token = var.api_token
|
api_token = var.api_token
|
||||||
api_endpoint = "https://deck-test.ngcloud.ru/api/v1/index.cfm"
|
api_endpoint = "https://deck-api-test.ngcloud.ru/api/v1/index.cfm"
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "sless" {
|
provider "sless" {
|
||||||
endpoint = "https://sless.kube5s.ru"
|
endpoint = "https://sless.kube5s.ru"
|
||||||
token = var.api_token
|
token = var.api_token
|
||||||
nubes_endpoint = "https://deck-test.ngcloud.ru/api/v1"
|
nubes_endpoint = "https://deck-api-test.ngcloud.ru/api/v1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,20 @@
|
|||||||
|
|
||||||
# Актуальные credentials из vault_secrets (authoritatively) — vault синхронизирован с кластером.
|
# Актуальные credentials из vault_secrets (authoritatively) — vault синхронизирован с кластером.
|
||||||
# Структура vault_secrets["users"]: JSON-строка {"username": {"password": "...", "username": "..."}}
|
# Структура vault_secrets["users"]: JSON-строка {"username": {"password": "...", "username": "..."}}
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
pg_creds_map = jsondecode(nubes_postgres.npg.vault_secrets["users"])
|
# try() нужен: vault_secrets["users"] появляется только ПОСЛЕ создания первого пользователя.
|
||||||
|
# На первом apply ключа ещё нет → пустая map. Пароль подтянется при следующем apply.
|
||||||
|
pg_creds_map = try(jsondecode(lookup(nubes_postgres.npg.vault_secrets, "users", "{}")), {})
|
||||||
pg_username = nubes_postgres_user.pg_user.username
|
pg_username = nubes_postgres_user.pg_user.username
|
||||||
pg_password = local.pg_creds_map[local.pg_username]["password"]
|
pg_password = try(local.pg_creds_map[local.pg_username]["password"], "")
|
||||||
pg_host = nubes_postgres.npg.state_out_flat["internalConnect.master"]
|
pg_host = nubes_postgres.npg.state_out_flat["internalConnect.master"]
|
||||||
pg_database = nubes_postgres_database.db.db_name
|
pg_database = nubes_postgres_database.db.db_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
resource "nubes_postgres" "npg" {
|
resource "nubes_postgres" "npg" {
|
||||||
resource_name = "teststand-pg-2"
|
resource_name = "pg-sless-demo"
|
||||||
# s3_uid = "s01325"
|
# s3_uid = "s01325"
|
||||||
s3_uid = var.s3_uid
|
s3_uid = var.s3_uid
|
||||||
resource_realm = var.realm
|
resource_realm = var.realm
|
||||||
@@ -40,14 +44,14 @@ resource "nubes_postgres" "npg" {
|
|||||||
|
|
||||||
resource "nubes_postgres_user" "pg_user" {
|
resource "nubes_postgres_user" "pg_user" {
|
||||||
postgres_id = nubes_postgres.npg.id
|
postgres_id = nubes_postgres.npg.id
|
||||||
username = "u-user0"
|
username = "user0"
|
||||||
role = "ddl_user"
|
role = "ddl_user"
|
||||||
adopt_existing_on_create = true
|
adopt_existing_on_create = true
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "nubes_postgres_database" "db" {
|
resource "nubes_postgres_database" "db" {
|
||||||
postgres_id = nubes_postgres.npg.id
|
postgres_id = nubes_postgres.npg.id
|
||||||
db_name = "db_terra"
|
db_name = "db0"
|
||||||
db_owner = nubes_postgres_user.pg_user.username
|
db_owner = nubes_postgres_user.pg_user.username
|
||||||
adopt_existing_on_create = true
|
adopt_existing_on_create = true
|
||||||
# suspend_on_destroy = false
|
# suspend_on_destroy = false
|
||||||
|
|||||||
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 2026-03-20
|
||||||
|
# stress_destroy_apply.sh — 5 итераций terraform destroy + apply для проверки lifecycle PG.
|
||||||
|
# Запускать вручную с VM: bash stress_destroy_apply.sh
|
||||||
|
# Логи каждой итерации пишутся в stress_log_N.txt
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ITERATIONS=5
|
||||||
|
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
cd "$DIR"
|
||||||
|
|
||||||
|
echo "=== Старт stress-теста: $ITERATIONS итераций destroy+apply ==="
|
||||||
|
echo "Workdir: $DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for i in $(seq 1 $ITERATIONS); do
|
||||||
|
LOG="stress_log_${i}.txt"
|
||||||
|
echo "--- Итерация $i/$ITERATIONS ---"
|
||||||
|
echo "Лог: $LOG"
|
||||||
|
|
||||||
|
echo "[$i] DESTROY — $(date)" | tee "$LOG"
|
||||||
|
terraform destroy -auto-approve 2>&1 | tee -a "$LOG"
|
||||||
|
DESTROY_CODE=${PIPESTATUS[0]}
|
||||||
|
|
||||||
|
if [ $DESTROY_CODE -ne 0 ]; then
|
||||||
|
echo "[!] destroy завершился с ошибкой (код $DESTROY_CODE), итерация $i. Прерывание." | tee -a "$LOG"
|
||||||
|
exit $DESTROY_CODE
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" | tee -a "$LOG"
|
||||||
|
echo "[$i] APPLY — $(date)" | tee -a "$LOG"
|
||||||
|
terraform apply -auto-approve 2>&1 | tee -a "$LOG"
|
||||||
|
APPLY_CODE=${PIPESTATUS[0]}
|
||||||
|
|
||||||
|
if [ $APPLY_CODE -ne 0 ]; then
|
||||||
|
echo "[!] apply завершился с ошибкой (код $APPLY_CODE), итерация $i. Прерывание." | tee -a "$LOG"
|
||||||
|
exit $APPLY_CODE
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" | tee -a "$LOG"
|
||||||
|
echo "[$i] Итерация завершена успешно — $(date)" | tee -a "$LOG"
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "=== Все $ITERATIONS итераций прошли успешно ==="
|
||||||
Reference in New Issue
Block a user