Files
tf_provider/HISTORY/OPUS/3006_0_answers.md
T

353 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ответы на дополнительные вопросы (сессия 2)
Read memory [](file:///home/naeel/.vscode-server/data/User/globalStorage/github.copilot-chat/memory-tool/memories/naeel/.vscode-server/data/User/workspaceStorage/358cf615179442f06eab7245b983b753/GitHub.copilot-chat/memory-tool/memories/MmM3MzY3ZGQtNmQ3Zi00OGI0LTg0ZDAtMjViYmIwNmY3Y2Zi/plan.md)
Created [](file:///home/naeel/tf_provider/HISTORY/OPUS/3006_1_questions.md)
Готово: 3006_1_questions.md
## 8 дополнительных вопросов
| # | Тема | Что нового (после его анализа) |
|---|------|-------------------------------|
| 1 | **Расхождение версий** | Регистр отдаёт 5.0.55, код — 5.0.51. Откуда 53-55? |
| 2 | **Полный аудит isDeleted** | Все ли GET /instances фильтруют deleted? Особенно `findInstanceUidByDisplayNameRefSvc` |
| 3 | **Gitea 413** | Где nginx-конфиг Gitea в репо? Можно ли увеличить лимит через чарты? |
| 4 | **Suspend-сервисы** | Полный список кто поддерживает suspend/resume. Есть ли баги (suspend без resume)? |
| 5 | **Terraform Operator** | Почему перезапустился 2 дня назад? Хватает ли компонентов? Где GPG/S3 конфиг? |
| 6 | **Тестовые стенды** | Какие реально используются? Legacy или Universal? Дубликаты? |
| 7 | **auth.k8s.ngcloud.ru** | OIDC-конфиг, обновление токенов, Keycloak HAR |
| 8 | **Orphan PVC/STS** | Откуда `storage-check-*` PVC? PostgreSQL 0/0 28 дней — почему? |
Все вопросы — **только чтение файлов в репо**, никаких правок. Opus может ответить на большинство из них. Вопросы 3 и 8 частично требуют данных из кластера (не из репо) — он это честно отметит.
Внесены изменения.
Список задач обновлен
Read [](file:///home/naeel/tf_provider/HISTORY/OPUS/3006_1_questions.md)
Исследую все 8 вопросов через чтение файлов репозитория. Запущу параллельный сбор данных.
Searched for regex `/instances\?|/instances"|GET.*instances|page=|isDeleted` (`**/universal_rebuild/internal/core/*.go`), 20 results
Searched for regex `findInstanceUidByDisplayNameRefSvc|ListRefServiceInstances`, 20 results
Searched for files matching `**/devops/profiles/**/profile.env`, 3 matches
Read [](file:///home/naeel/tf_provider/universal_rebuild/internal/core/refsvc_resolve.go)
Нашёл ключевое для вопроса 2 — прочитаю функцию `findInstanceUidByDisplayNameRefSvc` и файлы версий.
Searched for regex `VERSION|version|5\.0\.` (`**/devops/03_build_and_upload_provider.sh`), 13 results
Read [](file:///home/naeel/tf_provider/universal_rebuild/internal/core/client.go#900-900), lines 900 to 1010
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/profile.env)
Read [](file:///home/naeel/tf_provider/devops/profiles/test/profile.env)
Вопросы 1 и 2 почти закрыты. Соберу данные по остальным: инфраструктура, suspend-аудит, стенды, auth, orphan-ресурсы.
Searched for regex `auth\.k8s\.ngcloud\.ru|keycloak|shturval|client_max_body_size|gitea|storage-check`, 20 results
Searched for regex `getInstanceDisplayNameByUidRefSvc|findInstanceDisplayNameByUidRefSvc` (`**/universal_rebuild/internal/core/*.go`), 6 results
Read [](file:///home/naeel/tf_provider/charts)
Read [](file:///home/naeel/tf_provider/cloud-dashboard/k8s)
Searched for regex `storage-check|terraform-operator|registry-server|operator`, 20 results
Searched for files matching `**/{operator,registry-server,registry-server-build,k8s}/**`, 3 matches
Read [](file:///home/naeel/tf_provider/universal_rebuild/internal/core/client.go#1057-1057), lines 1057 to 1140
Read [](file:///home/naeel/tf_provider/cloud-dashboard/k8s/ingress.yaml)
Аудит suspend/resume сервисов
Аудит тестовых стендов
Read [](file:///home/naeel/tf_provider)
Searched for regex `kubeconfig|OIDC|oidc|kube-apiserver|kubectl|HOW_TO_SSH|auth\.k8s`, 20 results
Searched for files matching `**/TEST_STAND/**/*.tf`, 11 matches
Searched for files matching `**/PROD_STAND/**/*.tf`, 10 matches
Searched for files matching `**/RABBIT/**/*.tf`, 6 matches
Read [](file:///home/naeel/tf_provider/TEST_STAND)
Read [](file:///home/naeel/tf_provider/PROD_STAND)
Read [](file:///home/naeel/tf_provider/RABBIT)
Searched for files matching `tf_provider` · `universal_rebuild/resources_yaml/**/*.yaml`, no matches
Searched for files matching `tf_provider` · `devops/profiles/prod/generated/resources_yaml/**/*.yaml`, no matches
Searched for files matching `tf_provider` · `devops/profiles/test/generated/**/*.yaml`, no matches
Searched for files matching `tf_provider` · `universal_rebuild/resources_yaml/embed.go`, 1 match
Read [](file:///home/naeel/tf_provider/universal_rebuild/resources_yaml)
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated)
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml)
Read [](file:///home/naeel/tf_provider/devops/profiles/test/generated)
Read [](file:///home/naeel/tf_provider/universal_rebuild/resources_yaml/embed.go)
Read [](file:///home/naeel/tf_provider/devops/profiles/test/generated/resources_yaml)
Read [](file:///home/naeel/tf_provider/TEST_STAND/LUCEE/resources.tf#1-1), lines 1 to 50
Read [](file:///home/naeel/tf_provider/TEST_STAND/MARIA_DB/resources.tf#1-1), lines 1 to 50
Read [](file:///home/naeel/tf_provider/TEST_STAND/POSTGRES/main.tf)
Read [](file:///home/naeel/tf_provider/TEST_STAND/POSTGRES/resources.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/PG1/resources.tf#1-1), lines 1 to 100
Read [](file:///home/naeel/tf_provider/PROD_STAND/POSTGRES/resources.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/RABBIT/main.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/RABBIT/resources.tf#1-1), lines 1 to 100
Read [](file:///home/naeel/tf_provider/RABBIT/main.tf)
Read [](file:///home/naeel/tf_provider/RABBIT/resources.tf)
Read [](file:///home/naeel/tf_provider/TEST_STAND/LUCEE/main.tf)
Read [](file:///home/naeel/tf_provider/TEST_STAND/MARIA_DB/main.tf)
Read [](file:///home/naeel/tf_provider/TEST_STAND/S3_EVENT_FUNCTION_POC/versions.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/PG1/main.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/POSTGRES/main.tf)
Searched for regex `suspend|resume` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/**/*.yaml`), 20 results
Read [](file:///home/naeel/tf_provider/TEST_STAND/S3_EVENT_FUNCTION_POC/main.tf#1-1), lines 1 to 50
Read [](file:///home/naeel/tf_provider/TEST_STAND/POSTGRES/luceUNDnode.tf#1-1), lines 1 to 60
Read [](file:///home/naeel/tf_provider/PROD_STAND/POSTGRES/flask_disabled.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/PG1/vm.tf)
Read [](file:///home/naeel/tf_provider/PROD_STAND/RABBIT/rabbit_worker_disabled.tf)
Searched for regex `suspend|resume` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/**/*.yaml`), 187 results
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml/90_postgres.yaml#1-1), lines 1 to 20
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml/90_postgres.yaml#459-459), lines 459 to 469
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml/115_mariadb.yaml#1-1), lines 1 to 20
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml/115_mariadb.yaml#238-238), lines 238 to 248
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml/91_redis.yaml#1-1), lines 1 to 20
Read [](file:///home/naeel/tf_provider/devops/profiles/prod/generated/resources_yaml/117_nifi.yaml#1-1), lines 1 to 20
Searched for regex `- name:|kind:|action:` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/91_redis.yaml`), 6 results
Searched for regex `- name:|kind:|action:` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/117_nifi.yaml`), 9 results
Searched for regex `- name:|kind:|action:` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/112_tenant.yaml`), 9 results
Searched for regex `- name:|action:` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/22_vc_nsxt.yaml`), 8 results
Searched for regex `- name:|action:` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/29_vc_vdc_group.yaml`), 10 results
Searched for regex `- name:|action:` (`tf_provider` · `devops/profiles/prod/generated/resources_yaml/100_openwhisk.yaml`), 4 results
Проверю наличие `operator/`/`k8s/`, прочитаю отчёт по gitea/registry и README про реестр.
Searched for files matching `**/operator/**`, no matches
Searched for files matching `**/k8s/**`, 3 matches
Read [](file:///home/naeel/tf_provider/README.md#40-40), lines 40 to 127
Read [](file:///home/naeel/.vscode-server/data/User/workspaceStorage/358cf615179442f06eab7245b983b753/GitHub.copilot-chat/chat-session-resources/2c7367dd-6d7f-48b4-84d0-25bbb06f7cfb/toolu_01RGa2BMVk2W3EiaCRQTaSMg__vscode-1782817912438/content.txt)
Финальная проверка: наличие `registry-server-build/`, детали оператора/S3/GPG в кластере, keycloak HAR.
Searched for files matching `**/registry-server-build/**`, no matches
Searched for files matching `**/HAR/*keycloak*`, no matches
Searched for regex `S3_ENDPOINT|s3.msk-1|terraform-registry|S3_BUCKET|\.s3cfg`, 20 results
Read [](file:///home/naeel/tf_provider/docs/50_history/00_system_mechanics.md)
Все 8 вопросов исследованы. Ниже ответы в формате **находка → файлы → вывод → рекомендация**.
---
## Вопрос 1: Откуда версии 5.0.535.0.55?
**Находка.** Версия билда берётся **не из main.go**, а из профиля стенда:
- 03_build_and_upload_provider.sh: `VERSION = $1 → иначе $PROVIDER_VERSION/$RELEASE_VERSION (из profile.env) → иначе grep из main.go (fallback)`.
- profile.env: `PROVIDER_VERSION="5.0.55"`.
- profile.env: `PROVIDER_VERSION="2.1.23"` (!).
- main.go хранит `5.0.51` — это лишь **последний fallback**, который почти никогда не срабатывает.
**Вывод.** 5.0.53/54/55 — это **ручные билды с тестового стенда**: оператор вручную bump-ит `PROVIDER_VERSION` в `profiles/test/profile.env` и запускает `03_build...sh`. main.go при этом не обновляется (README прямо просит обновлять, но на практике это не делается — отсюда рассинхрон). Важно: **prod-профиль застрял на 2.1.23**, а test ушёл на 5.0.55 — это две независимые линейки версий. Мой прошлый анализ (3006_0.md) цитировал версии из кода (5.0.51/5.0.52), а регистр отдаёт версию из profile.env (5.0.55) — поэтому они не совпадают.
**Рекомендация.** Сделать profile.env единственным источником версии и автоматически прописывать её в main.go при сборке (или вычислять main.go-версию из env через ldflags `-X`). Сейчас 3 источника версии (main.go, test, prod) живут врозь.
---
## Вопрос 2: Полный аудит фильтрации `isDeleted`
**Находка.** Все функции, делающие GET к `/instances`:
| Функция | Файл | `isDeleted=false` в URL | Проверка в коде | Статус |
|---|---|---|---|---|
| `FindInstanceByDisplayName` | client.go | ✅ (search) / ❌ (fallback) | ✅ `isInstanceDeleted()` | OK |
| `ListRefServiceInstances` | refsvc_resolve.go | ✅ | ✅ `IsDeleted` + только running | OK |
| `findInstanceUidByDisplayNameRefSvc` | client.go | ❌ | ✅ `if item.IsDeleted {continue}` + `status=="deleted"` | **OK (исправлен!)** |
| `findInstanceDisplayNameByUidRefSvc` | client.go | ❌ | ❌ нет | приемлемо |
| `getInstanceDisplayNameByUidRefSvc` | client.go | — (GET по UID) | — | n/a |
| `GetInstanceState/Raw/Details` | client.go / instance_outputs.go | — (GET по UID) | ✅/частично | n/a |
**Вывод.**
- **`findInstanceUidByDisplayNameRefSvc` УЖЕ исправлен** — он пропускает deleted в коде (строки client.go) и предпочитает running>suspended. Замечание в 24_ai_analysis_pipeline_architecture_2026_06_30.md («НЕ ИСПРАВЛЕН?») **устарело** — баг класса #23 здесь закрыт. Единственный недочёт — нет `isDeleted=false` в URL (лишний трафик, но не баг корректности).
- **`findInstanceDisplayNameByUidRefSvc` (1058)** — единственная функция БЕЗ фильтра deleted ни в URL, ни в коде. Но она ищет по **точному `instanceUid`** (уникальному) и возвращает displayName — это обратный маппинг для чтения state, не выбор «того/не того» инстанса. Класс багов #23 здесь не применим. Риск минимальный: вернёт имя deleted-инстанса, если в state остался его UID.
**Рекомендация.** Косметика: добавить `&isDeleted=false` в URL `findInstanceUidByDisplayNameRefSvc` (1057) и `findInstanceDisplayNameByUidRefSvc` (1060) для экономии трафика. Корректность уже обеспечена. Обновить вывод в файле 24 (он сеет ложную тревогу).
---
## Вопрос 3: Gitea 413 (`client_max_body_size`)
**Находка.**
- charts — **пустая** (list_dir: folder empty).
- Манифесты в репо есть только для dashboard: ingress.yaml — ingress для `terra.k8c.ru/dashboard`, аннотаций `client_max_body_size`/`proxy-body-size` нет, и это **не Gitea**.
- `gitea-naeel.giteak8s.services.ngcloud.ru` упоминается только как `git_path` в resources.tf и закомментированно в luceUNDnode.tf. Сам Gitea — это **управляемый сервис Nubes** (см. svcs.json: «Gitea», «Комплексная услуга по созданию gitea», service_id 99/114), развёрнутый в кластере `giteak8s`, а не из этого репо.
**Вывод.** **Конфигурация nginx Gitea в этом репозитории отсутствует.** `client_max_body_size=1MB` задаётся на ingress управляемого Gitea в кластере `giteak8s.services.ngcloud.ru`**внешняя конфигурация**, недоступная для правки из этого репо.
**Рекомендация.** Лимит правится за пределами репо — на ingress Gitea-инстанса: аннотация `nginx.ingress.kubernetes.io/proxy-body-size: "0"` (или, например, `512m`). Это требует доступа к namespace Gitea в кластере giteak8s. Из репо проблему не решить. *(Требует данных кластера — отмечаю честно.)*
---
## Вопрос 4: Полный список suspend/resume-сервисов
**Находка.** YAML-спеки в devops/profiles/prod/generated/resources_yaml/ (43 файла, test идентичен), встроены через `//go:embed *` в embed.go.
**26 сервисов с suspend И resume** (service_id): `1 dummy, 2 template, 12 s3, 19 vc_org, 20 vc_org_saas, 21 vc_vdc, 23 vc_vm, 26 vapp, 27 vc_vm_v2, 28 vc_vm_v3, 50 nextcloud, 89 flask, 90 postgres, 92 mongodb, 93 rabbitmq, 94 lucee, 95 nodejs, 96 pgadmin, 98 http, 99 gitea, 115 mariadb, 116 kafka, 119 akhq, 120 clickhouse, 149 valo_tenant, 150 k8s_shturval`.
**17 сервисов без suspend/resume**: `13 s3bucket, 22 vc_nsxt, 25 vcexternalip, 29 vc_vdc_group, 32 vmpostgre, 81 superset, 82 harbor, 88 ziti, 91 redis, 97 nodered, 100 openwhisk, 110 dnszone, 111 dnsrecord, 112 tenant, 113 vc_complex, 114 gitea_complex, 117 nifi`.
**Вывод.**
- **Асимметрии нет**: suspend и resume всегда идут парой (26/26). Сервисов «suspend без resume» — **0**.
- `suspend_on_destroy_default` **идеально совпадает** с правилом `hasSuspend → true`: 26 suspend-сервисов = `true`, 17 = `false`. Расхождений нет.
- Логика разделения здравая: stateless (DNS, external IP, tenant) — без suspend; stateful (БД, приложения, VM) — с suspend.
**Рекомендация.** По этому пункту всё чисто. Стоит лишь добавить в генератор `validateSpec()`-проверку «если есть suspend, обязан быть resume» как защиту на будущее (сейчас инвариант соблюдён случайно — генератор его не enforce-ит).
---
## Вопрос 5: Terraform Operator — состояние и health
**Находка — ключевая.** Директорий `operator/`, `registry-server-build/`, корневого `k8s/` **НЕТ в этом checkout** (file_search: «No files found»), хотя они активно упоминаются в README.md, REPO_CONTENTS.md, build-registry-image.yml (`operator/build/Dockerfile.registry`) и deploy-dev.sh (`k8s/overlays/dev`).
Что есть в репо — описание в 00_system_mechanics.md:
- 3 компонента: **Operator** (watch CRD → spawn Job), **Registry API** (Discovery protocol over S3), **Builder Job** (`golang:1.24-alpine`: clone→build→upload S3). Это совпадает с тремя deployment'ами, что вы видели.
- **S3**: бакет артефактов `terraform-providers`, схема пути `{hostname}/{namespace}/{provider}/{version}/{file}`, `REGISTRY_HOSTNAME=terra.k8c.ru`. Эндпойнт `s3.msk-1.ngcloud.ru` (upload_provider_s3.py, REPO_CONTENTS.md).
- **GPG в кластере — ФЕЙКОВЫЙ**: 00_system_mechanics.md — «GPG Signing: Сейчас фейковое (создаётся пустой `.sig`)». Реальная подпись private_key.asc используется только в **локальном** `03_build...sh`, а не в operator-Job.
- **Перезапуск оператора — штатная операция**: в cheat-sheet прямо есть `kubectl rollout restart deploy/terraform-operator -n terra`.
**Выводы по вопросам:**
1. **Перезапуск 2 дня назад** — скорее всего ручной `rollout restart` (документированная команда подхвата изменений `manifests/03-build-script.yaml`), а не краш. Подтвердить можно только по `kubectl describe pod`/`--previous` логам в кластере. *(Требует кластера.)*
2. **Трёх deployment'ов достаточно** для registry+CI (operator+registry-server+builder-job). Отдельного docs-server нет и не нужен: доки — статика в S3 (`terraform-registry/docs/...`), publish-docs.sh. cloud-dashboard — отдельный UI, не часть registry.
3. **GPG-ключи**: в кластере подпись фейковая (tech debt из system_mechanics); реальный ключ только локально в secrets. **S3-доступ** оператора — через ENV `S3_*`/`REGISTRY_HOSTNAME` в Deployment (должны быть в Secret `terraform-operator`).
4. **S3-конфиг бакета в репо** — только переменные и схема путей; манифест Secret/Deployment отсутствует (он в недостающей папке `operator/`/`k8s/`).
**Рекомендация.** Критично: **внедрить реальную GPG-подпись в operator-Job** (смонтировать private_key.asc как K8s Secret) — сейчас артефакты из кластера подписаны пустышкой, Terraform может ругаться `authentication signature from unknown issuer`. Также — вернуть `operator/`+`k8s/` в этот репо или явно задокументировать, что они в отдельном репозитории (сейчас CI ссылается на отсутствующие пути).
---
## Вопрос 6: Тестовые стенды — что реально используется
**Находка.** Все `.tf` используют **только Universal** (`source = "terra.k8c.ru/nubes/nubes"`), Legacy (`registry.terraform.io/nubes/nubes`) **не используется нигде**.
| Стенд | Version | Endpoint | Активные ресурсы |
|---|---|---|---|
| TEST_STAND/LUCEE | 2.0.6 | test | postgres, lucee |
| TEST_STAND/MARIA_DB | 2.0.8 | test | mariadb, lucee, flask |
| TEST_STAND/POSTGRES | **5.0.52** | test | postgres + user + database |
| TEST_STAND/S3_EVENT_POC | 2.1.23 | — | s3bucket ×2 |
| PROD_STAND/PG1 | 2.1.26 | prod | postgres, lucee, nodejs, s3bucket |
| PROD_STAND/POSTGRES | 2.1.12 | prod | postgres, lucee, nodejs |
| PROD_STAND/RABBIT | 5.0.19 | **test ⚠️** | rabbitmq |
| RABBIT/ (корень) | 2.1.10 | prod | rabbitmq, lucee, nodejs, s3bucket |
**Выводы:**
1. Все стенды активны (с реальными ресурсами); часть компонентов закомментирована (VM в PG1, flask в PROD/POSTGRES, http-worker в RABBIT).
2. **Сильный разброс версий**: test — 2.0.6…5.0.52, prod — 2.1.10…2.1.26. Каждый стенд пинит свою версию.
3. **TEST/POSTGRES не дублирует PROD/POSTGRES**: разные версии (5.0.52 vs 2.1.12), имена (`pg4tf033` vs `pg-tst0`), TEST модульный (только БД+user+database с `var.realm`), PROD связный (БД+lucee+nodejs, хардкод realm). Это разные конфигурации, не дубль.
4. **Аномалия**: PROD_STAND/RABBIT/main.tf указывает на **test-endpoint** (`deck-api-test.ngcloud.ru`), хотя лежит в PROD_STAND — вероятно ошибка/недо-миграция.
**Рекомендация.** Привести версии стендов к двум канонам (одна test, одна prod), исправить endpoint в RABBIT, удалить мёртвые закомментированные `.tf` или вынести в `examples/`.
---
## Вопрос 7: auth.k8s.ngcloud.ru / Keycloak / shturval
**Находка.** Поиск `auth.k8s.ngcloud.ru`, `shturval`, `OIDC`, `kubeconfig` по репо: совпадения **только в самом файле вопросов** 3006_1_questions.md. В коде/конфигах — ничего.
- HAR `keycloak.nubes.ru.har` существует локально, но **gitignored** (`HAR/*.har` в .gitignore) — и это Keycloak **`keycloak.nubes.ru`** (для управляемых сервисов Nubes), а **не** `auth.k8s.ngcloud.ru`.
- Инструкции по доступу — только HOW_TO_SSH.md (SSH, не kubeconfig/OIDC).
- `kubectl`-команды в docs (deploy-dev.sh, ops/*.md) предполагают **готовый** kubeconfig, способ его получения не описан.
**Вывод.** **Конфигурации OIDC кластера, скриптов обновления токена и инструкций по kubeconfig в репо НЕТ.** `auth.k8s.ngcloud.ru` (realm `shturval`) — внешняя система аутентификации кластера, никак не отражённая в репозитории. HAR относится к другому Keycloak (сервисный, `keycloak.nubes.ru`).
**Рекомендация.** Если доступ к кластеру через `auth.k8s.ngcloud.ru` нужен регулярно — добавить в secrets (gitignored) инструкцию/скрипт `kubelogin`/OIDC token refresh, по аналогии с `HOW_TO_SSH.md`. Сейчас это «племенное знание» вне репо. *(Детали OIDC-эндпойнта — за пределами репо.)*
---
## Вопрос 8: Orphan PVC `storage-check-*` и PostgreSQL 0/0
**Находка.** Поиск `storage-check` по всему репо: совпадения **только в файле вопросов**. Ни одного `.tf`, манифеста или упоминания в docs/HISTORY, создающего `storage-check-local`/`storage-check-vcd`. Никаких упоминаний проблемных PostgreSQL-тенантов `509145c3`/`dc5db45d`.
**Вывод.**
- `storage-check-*` PVC **не создаются Terraform-конфигами из этого репо**. Имена (`storage-check-local`/`storage-check-vcd` = local/vCD storage classes) характерны для **тестов доступности StorageClass** — это типичные probe-PVC, которые создаёт **облачная платформа/CSI или сам terraform-operator-Job** при проверке хранилища, а не пользовательский TF. Подтвердить, что их делает именно operator, по репо нельзя (код оператора отсутствует в checkout, см. Q5).
- PostgreSQL `0/0 28 дней` с висящими PVC/Service — это **suspended/недо-удалённые инстансы**: StatefulSet масштабирован в 0 (suspend), но PVC и Service остаются (платформа не чистит при suspend). Это согласуется с семантикой `suspend_on_destroy` (Q4) и багом 20_destroy_detach_semantics: `state_only`/suspend оставляет ресурсы в облаке.
**Рекомендация.** Источник `storage-check-*` и orphan-StatefulSet'ов нужно искать **в кластере**: `kubectl get pvc storage-check-local -o yaml` → смотреть `ownerReferences`/`annotations` (кто создатель). Если owner — `terraform-operator` SA или CSI healthcheck, чистить через него. Из репозитория эти ресурсы не управляются. *(Требует доступа к кластеру.)*
---
## Сводка
| # | Вопрос | Ответ из репо? | Главный вывод |
|---|---|---|---|
| 1 | Версии 53-55 | ✅ Полностью | Из `profiles/*/profile.env`, ручной bump; main.go — fallback. prod=2.1.23, test=5.0.55 |
| 2 | Аудит isDeleted | ✅ Полностью | Все критичные функции фильтруют; `findInstanceUidByDisplayNameRefSvc` **уже исправлен** (файл 24 врёт) |
| 3 | Gitea 413 | ⚠️ Частично | Конфига nginx Gitea в репо нет — внешняя config кластера giteak8s |
| 4 | Suspend-сервисы | ✅ Полностью | 26 suspend+resume, 0 асимметрий, default совпадает идеально |
| 5 | Operator health | ⚠️ Частично | `operator/`+`k8s/` отсутствуют в checkout; GPG в кластере фейковый; рестарт = штатный redeploy |
| 6 | Стенды | ✅ Полностью | Везде Universal, Legacy не используется; разброс версий; RABBIT prod→test endpoint |
| 7 | auth.k8s | ❌ Нет в репо | Ни OIDC, ни kubeconfig-скриптов; HAR — другой Keycloak (nubes.ru) |
| 8 | Orphan PVC | ❌ Нет в репо | `storage-check-*` не из TF; orphan PG = suspended-остатки; искать в кластере |
**Требуют данных вне репо** (честно): Q3 (ingress Gitea в giteak8s), Q5 (логи рестарта оператора, Secret S3/GPG), Q7 (OIDC-эндпойнт auth.k8s), Q8 (`ownerReferences` PVC в кластере).
Сохранить эти ответы в `HISTORY/OPUS/3006_1.md` или оставить в чате?
Создано задач: 6