User clarification: «у все должно быть общее представление, где что живёт, а у админа — полное представление, на чём всё едет». Расширение scope существующей таски (создана несколькими минутами ранее с single-page подходом): - Deliverable A — light в projects-wiki/concepts/infrastructure-inventory.md (audience: все агенты, разрабы, босс). Канонические hostnames + IP-map + anti-aliases. Mental map для design-conversations. - Deliverable B — heavy в .admin/.wiki/concepts/infrastructure-stack.md (audience: только админ). Per-stack: версии, internal IPs, volumes, depends-on graph, backup paths, DR runbook pointers. На чём всё едет. Probing-фаза общая, потом split по level of detail. A и B cross-references.
87 lines
8.5 KiB
Markdown
87 lines
8.5 KiB
Markdown
# infra-inventory
|
||
|
||
## Goal
|
||
|
||
Полная инвентаризация инфраструктуры kzntsv на **двух уровнях detail**:
|
||
|
||
1. **Public-вид** — все (босс в `.workshop`, агенты в любом проекте, разрабы) видят общую карту: «где что живёт». Канонические hostnames, IP-карта, anti-aliases. Light, без секретов и внутренней topology.
|
||
2. **Admin-вид** — админ видит полную картину «на чём всё едет»: стэки + версии, internal IPs, network topology, volumes, backup paths, depends-on graph, restart policies, pointer'ы на bootstrap-concept'ы каждой машины, runbook'и куда лезть если упало. Heavy.
|
||
|
||
**Без этой карты любой агент / разраб угадывает hostname по software name** (последний инцидент: ляпнул `gitea.kzntsv.site` вместо `git.kzntsv.site`, перепутал source/destination IP в traefik access-логах, построил неверную причину 404).
|
||
|
||
## Deliverable A — public inventory
|
||
|
||
**Где:** `OpeItcLoc03/projects-wiki/concepts/infrastructure-inventory.md` через `mcp__projects-meta__knowledge_ingest`.
|
||
|
||
**Audience:** агенты во всех проектах, разрабы, босс. Single source of truth для canonical hostnames.
|
||
|
||
**Содержит:**
|
||
|
||
- Таблица **машин**: имя | физ. расположение / провайдер | public IP | назначение (high-level — «VDS Rusonyx, прод-площадка»; БЕЗ internal IP, версий, volumes)
|
||
- Таблица **subdomain → host**: subdomain | public IP | какая машина | что обслуживает (high-level — «Gitea», без версии)
|
||
- Раздел **canonical hostnames** — авторитетный список (`git.kzntsv.site`, `registry.kzntsv.site`, `board.kzntsv.site`, и т.д.) с пометкой «не угадывать по software name»
|
||
- Раздел **anti-aliases** — hostnames которые звучат правильно но не существуют: `gitea.kzntsv.site` ❌ (use `git.kzntsv.site`), и другие если найдутся
|
||
- Раздел **wildcard / apex** — что апекс `kzntsv.site` и `*.kzntsv.site` указывают на 94.19.247.14 (НЕ VDS); не пускать сюда production traffic
|
||
- Pointer на admin-detailed концепт (без раскрытия её содержимого)
|
||
|
||
## Deliverable B — admin-detailed stack
|
||
|
||
**Где:** `~/projects/.admin/.wiki/concepts/infrastructure-stack.md` (admin-local; commit + push в `OpeItcLoc03/admin`).
|
||
|
||
**Audience:** только админ. Полный context на чём всё едет.
|
||
|
||
**Содержит:**
|
||
|
||
- Per-machine sub-section: hostname, public IP, internal IP, OS, ssh access (как, ключи где), ops-MCP endpoint
|
||
- Per-stack sub-section на каждой машине: имя стэка | путь на хосте (`/opt/stacks/<name>/`) | docker-compose файл | сервисы (имя + образ + версия) | внешние ports | internal network | volumes (paths + что хранит) | env vars / secrets pointers (где лежит, не value) | restart policy | depends-on graph
|
||
- Network topology: какие docker networks (`proxy`, etc.), какие хосты в них, как traefik видит контейнеры
|
||
- Backup-карта: что бэкапится, куда, какой cron / rsync source, где runbook
|
||
- Disaster-recovery pointers: на bootstrap-concept каждой машины (vds-kzntsv-bootstrap, etc.), где restore-инструкции
|
||
- Per-stack runbook pointer: «если упало X — см. концепт Y, секцию Z»
|
||
|
||
## Acceptance criteria
|
||
|
||
- (A) `projects-wiki/concepts/infrastructure-inventory.md` ingested, доступен через `mcp__projects-meta__knowledge_get({slug: "concepts/infrastructure-inventory"})`
|
||
- (B) `.admin/.wiki/concepts/infrastructure-stack.md` commited + pushed, перечислен в `.admin/.wiki/index.md`
|
||
- (A) ↔ (B) cross-references: public ссылается на admin как «detailed context for admin», admin ссылается на public как «if you need the high-level picture»
|
||
- Pointer в `.admin/.wiki/CLAUDE.md` Domain conventions: «Перед любым hostname-mention свериться с public infra-inventory; для ops-decisions — admin infrastructure-stack»
|
||
- Pointer в `~/projects/claude-skills/skills/using-vds-ops/SKILL.md` body и `using-synology-ops/SKILL.md` body (когда тот skeleton получит body): «Canonical hostnames — projects-wiki/concepts/infrastructure-inventory»
|
||
- Smoke: на тестовый вопрос «какой hostname у Gitea?» любой агент в любом проекте находит `git.kzntsv.site` через `knowledge_search` или `knowledge_ask`
|
||
|
||
## Источники для probing-фазы
|
||
|
||
- `mcp__projects-meta__knowledge_search` по existing bootstrap-concept'ам (vds-kzntsv-bootstrap, vds-ntfy-push, vds-backup-rsync-kreknin, owncloud-vds-deploy, mssql-vds-migration, minio-imgproxy-vds-migration, portainer-stack-management-vds, etc.)
|
||
- `mcp__vds-ops__ops_docker_ps` — что running на VDS (имена контейнеров → имена стэков через `com.docker.compose.project` label)
|
||
- `mcp__vds-ops__ops_docker_inspect <container>` для каждого — образ+версия, network, mounts, env (env masked, но keys видны)
|
||
- `mcp__synology-ops__ops_docker_ps` + inspect — то же для NAS
|
||
- `nslookup` для known subdomain'ов (probe-list: `git`, `registry`, `traefik.vds`, `mssql`, `board`, `imgproxy.vds`, `opsmcp.vds`, `opsmcp`, owncloud-host, и любые другие найденные в проектах)
|
||
- `rg -F "kzntsv.site"` по `~/projects/` — каноничный список где упоминаются hostnames
|
||
- `git remote -v` на любом clone → `git_base_url` для Gitea canonical
|
||
- `~/.config/projects-mcp/auth.toml` → подтверждение Gitea base URL
|
||
- `~/projects/.admin/.tasks/STATUS.md` header — какие deploy'и закрыты, что live
|
||
|
||
## Pending
|
||
|
||
- [ ] Probing-фаза (общая для A и B): собрать сырые данные через MCP probes + nslookup + rg
|
||
- [ ] Write deliverable A (light) — таблицы + canonical + anti-aliases
|
||
- [ ] Ingest A через `knowledge_ingest`
|
||
- [ ] Write deliverable B (heavy) — per-machine, per-stack, networks, backups, DR pointers
|
||
- [ ] Commit B в `.admin/.wiki/concepts/infrastructure-stack.md` + update `.wiki/index.md`
|
||
- [ ] Cross-references A↔B
|
||
- [ ] Pointer в `.admin/.wiki/CLAUDE.md` Domain conventions
|
||
- [ ] Pointer в using-vds-ops / using-synology-ops skill bodies (когда у них появится body)
|
||
|
||
## Decisions log
|
||
|
||
- 2026-05-22: таска создана из incident'а (агент перепутал `gitea.` vs `git.`, source vs destination IP в traefik access-логах, построил неверный root-cause 404 для board-viewer deploy). User: «никакого `gitea.kzntsv.site` нет, есть только `git.kzntsv.site`, нужна инвентаризация чтобы и боссы и агенты и разрабы знали железо».
|
||
- 2026-05-22: расширена scope — было «single page», стало two-tier (public + admin-detailed). User: «у все должно быть общее представление, где что живёт, а у админа — полное представление, на чём всё едет». Public = mental map для всех, admin = runbook на чём всё едет.
|
||
|
||
## Notes
|
||
|
||
- Это не оперативная таска (не блокирует deploy). Но без неё каждый новый агент/сессия рискует повторить ту же ошибку. Приоритет — высокий по latency: чем дольше нет inventory, тем больше circular incident'ов.
|
||
- A и B shared probing-фазу делают один раз; potом разносятся по нужным level of detail.
|
||
- B содержит pointer'ы на secrets locations (pass-store paths), но НЕ сами secrets.
|
||
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 -->
|
||
<!-- scope-expanded: 2026-05-22 — single-page → two-tier (public + admin-detailed) per user clarification -->
|