Netpulse_SasS/deploy/docker-compose.sandbox.yml
byrsapty ca143a616b
Some checks failed
CI / hygiene (push) Successful in 8s
CI / web (push) Successful in 59s
CI / server (push) Failing after 3m27s
CI / agent (push) Successful in 3m3s
Білінг, SLA, вбудовані правила, пісочниця установника, тести сторінок
П'ять паралельних задач. Найцінніше в них — не можливості, а знайдене.

0069 БІЛІНГ. Аудит 0009 показав, що перевірка ліміту не спрацювала б
жодного разу: isPlanLimit шукала слово «ліміт», а тригер писав
"device limit reached" англійською. Перше ж досягнення стелі дало б
клієнту 500 замість пояснення. Плюс три діри: тригер лише на INSERT
(стеля в 15 обходилась за чотири дії через архів), max_maps/max_agents/
max_users не перевіряло ніщо — тобто рівно те, чим відрізняються плани,
і license_keys була закрита політикою tenant_isolation з 0011, хоча
tenant_id там NULLABLE навмисно: головний сценарій self-hosted був
недосяжний.

Після закінчення ліцензії не вимикається нічого — замерзає лише ріст.
Моніторинг, що перестав моніторити через несплачений рахунок, це
аварія в мережі клієнта, спричинена нами.

0070 SLA. Джерелом обрано ts.icmp_1h, а не device_status_history:
остання не вміє сказати «ми не знали» — перехід пишеться лише при
зміні стану, тож доба мовчання зонда виглядає як доба роботи. Час
розкладено на чотири частини, і «немає даних» не додається ні до чого;
замість вибору між двома брехнями звіт каже, яку частку періоду він
бачив. Закритий період тримає тригер, а не домовленість у Go.

0071 ВІДПОВІДНІСТЬ. 20 правил, кожне прив'язане до родини: об'єднаний
вираз, що покриває Cisco й не покриває MikroTik, дав би «0 порушень» і
сховав сліпу пляму. Вендор не входить у перелік, доки для нього немає
зразка конфігу в тесті. TestBuiltinRulesAreNotAlwaysGreen вимагає, щоб
у кожного правила був конфіг, де воно спрацювало, І де ні.

ПІСОЧНИЦЯ УСТАНОВНИКА — та сама установка в ізольованому проєкті
compose. Знайшла дві справжні вади з трьох спроб:
  * healthcheck бази ходив unix-сокетом, а споживачі по TCP. При
    первинній ініціалізації Postgres слухає лише сокет — compose
    вважав базу здоровою, migrate отримував connection refused. На
    створеній базі цієї фази немає, тож вада чекала на першого клієнта;
  * у білому переліку модулів API не було traps і filecfg — зонд із
    приймачем трапів неможливо було зареєструвати взагалі.

ТЕСТИ СТОРІНОК: 137 → 252. Мережевий шар, права доступу, незворотні
дії, фільтри з адресного рядка. Підмінюється лише fetch і WebSocket —
api/client.ts працює справжній.
2026-08-27 21:17:23 +03:00

118 lines
7.1 KiB
YAML
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.

# Пісочниця NetPulse — накладка на docker-compose.yml.
#
# Це НЕ окремий стек і не спрощена копія. Це той самий docker-compose.yml,
# накритий рівно тими правками, без яких повна установка на робочій
# машині або конфліктує з наявною, або з'їдає машину. Усе інше —
# порядок служб, міграції, ролі під RLS, зонд — лишається тим самим, бо
# інакше пісочниця перевіряла б не установку, а власну вигадку.
#
# Запускати руками не треба: `./netpulse sandbox` підставляє і цей файл,
# і ім'я проєкту, і окремий .env.sandbox.
#
# docker compose -p netpulse-sandbox \
# -f docker-compose.yml -f deploy/docker-compose.sandbox.yml \
# --env-file .env.sandbox <команда>
#
# ---------------------------------------------------------------------
# ЩО САМЕ ТУТ МІНЯЄТЬСЯ І ЧОМУ
#
# 1. Порти. Базовий файл публікує 80, 443, 9443 і 162/udp числами. Друга
# інсталяція на тій самій машині впирається в них першою ж командою
# `up`, і виглядає це як «пісочниця поклала бойову систему» — рівно та
# шкода, від якої вона мала захистити. Тому проксі публікується на
# зсунуті порти І ЛИШЕ на 127.0.0.1: пісочниця не має бути видною з
# мережі навіть випадково, у ній стоїть відомий пароль і самопідписаний
# сертифікат.
#
# 2. Трапи. Зонд у пісочниці піднімається (без нього не перевірити
# реєстрацію в колекторі — а це єдиний шлях, якого HTTP-перевірки не
# бачать зовсім), але 162/udp назовні не виставляє взагалі. Порт без
# автентифікації, відкритий заради перевірки, — це не перевірка.
#
# 3. Стелі пам'яті. Без них пісочниця конкурує з рештою машини на рівних
# і виграє: Postgres резервує буфери одразу, а ядро вбиває не того,
# хто попросив забагато, а того, хто підвернувся. Стеля перетворює
# «машина стала» на «контейнер пісочниці впав», і друге видно одразу.
# Цифри взяті з запасом: стеля тут — запобіжник, а не режим економії,
# і впертись у неї на порожній базі не має ніщо. Якщо все ж уперлось,
# `./netpulse sandbox status` це називає прямо, щоб причину не шукали
# в коді.
#
# 4. restart: "no". У бойовому стеку `unless-stopped` правильний: служба
# має пережити перезавантаження хоста. Для пісочниці це протилежність
# потрібного — забута пісочниця не має воскресати після ребуту й
# мовчки тримати порт і том. Побічний наслідок корисний: контейнер,
# який падає в циклі, тут одразу видно як мертвий, а не як «щось
# довго стартує».
#
# ---------------------------------------------------------------------
# ЧОМУ ПОТРІБЕН COMPOSE 2.24.4
#
# Списки `ports` при накладанні файлів compose ДОДАЄ, а не замінює: без
# явного тега `!override` базові «80:80» лишилися б на місці поруч зі
# зсунутими, і пісочниця все одно вчепилась би в порт бойового проксі.
# Тег `!override` з'явився у docker compose 2.24.4.
#
# Ця вимога зникає одним рядком у docker-compose.yml — якщо базові порти
# зробити змінними зі значенням за замовчуванням:
#
# ports:
# - "${NETPULSE_BIND:-0.0.0.0}:${NETPULSE_PORT_HTTP:-80}:80"
# - "${NETPULSE_BIND:-0.0.0.0}:${NETPULSE_PORT_HTTPS:-443}:443"
# - "${NETPULSE_BIND:-0.0.0.0}:${NETPULSE_PORT_GRPC:-9443}:9443"
#
# Тоді пісочниці вистачить .env.sandbox, накладка портів стає не
# потрібна, а мінімальна версія compose лишається 2.0 — як у решті
# установника. Поки цього немає, `./netpulse sandbox` перевіряє версію і
# відмовляється працювати на старішій, а не мовчки бере не ті порти.
# Ім'я проєкту продубльовано тут навмисно. `./netpulse sandbox` і так
# передає -p, але якщо цей файл колись запустять руками без -p, ізоляція
# має лишитись: інше ім'я проєкту — це інші контейнери, інша мережа й,
# найголовніше, ІНШІ ТОМИ. Без нього `down -v` у пісочниці знищив би
# базу бойової інсталяції.
name: netpulse-sandbox
services:
db:
mem_limit: 768m
restart: "no"
cache:
mem_limit: 320m
restart: "no"
migrate:
mem_limit: 256m
cli:
mem_limit: 256m
api:
mem_limit: 384m
restart: "no"
collector:
mem_limit: 256m
restart: "no"
proxy:
mem_limit: 128m
restart: "no"
# Порти пише установник у .env.sandbox, попередньо переконавшись, що
# вони вільні. Значення за замовчуванням тут — щоб файл не був
# непрацездатним сам по собі, а не щоб на них покладатись.
ports: !override
- "127.0.0.1:${NETPULSE_SB_HTTP:-18080}:80"
- "127.0.0.1:${NETPULSE_SB_HTTPS:-18081}:443"
- "127.0.0.1:${NETPULSE_SB_GRPC:-18082}:9443"
agent:
mem_limit: 192m
restart: "no"
# Порожньо, а не інший порт: 162/udp не має автентифікації, і
# відкривати його заради перевірки означало б купити перевірку ціною
# дірки. Усе, що перевіряє зонд — обмін запрошення на токен, gRPC до
# колектора, поява рядка в core.agents, — відбувається вихідними
# з'єднаннями й публікації порту не потребує.
ports: !override []