Netpulse_SasS/db/profiles/README.md
byrsapty 205dd5e079 Пакування: runner міграцій і вшитий у бінарник фронтенд
netpulse-migrate замість PowerShell-скрипта: у контейнері немає ані
psql, ані PowerShell, а тягнути клієнт Postgres в образ заради одного
запуску — це половина дистрибутива на порожньому місці.

Міграції вшиті через embed і переїхали в server/migrations: embed не
бачить нічого за межами кореня свого модуля, а міграції поруч із
бінарником, який їх накочує, не можуть розійтися версіями.

Накочування під advisory-блокуванням: два інстанси при rolling update
інакше застосували б ту саму міграцію двічі. Кожен файл в одній
транзакції разом із записом у schema_migrations; виняток — continuous
aggregates, які TimescaleDB забороняє в транзакції. Змінена вже
застосована міграція зупиняє запуск: у різних інсталяціях інакше
опиниться різна схема під одним номером.

Перевірено на чистій базі: 23 міграції, 101 таблиця, повторний запуск
каже «схема актуальна».

Веб віддає сам API через embed: на self-hosted це прибирає з інструкції
встановлення цілий компонент. Три політики кешування — назавжди для
assets із хешем у імені, ніколи для index.html, коротко для решти.

Знайдено живим прогоном: невідомий шлях під /api/ віддавав 200 з
index.html, і клієнт падав на розборі HTML як JSON замість чесного 404.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 01:01:55 +03:00

4.1 KiB
Raw Blame History

Каталог команд збору конфігу

catalog.json — джерело істини про те, як зняти конфіг із кожної підтримуваної платформи. 148 платформ, 67 вендорів.

Міграція server/migrations/0014_ncm_profiles.sql породжується з каталогу, а не правиться руками: два описи одного й того самого розійшлися б із першою ж правкою, і невідомо було б, який справжній.

python build.py            # перезібрати міграцію
python build.py --check    # звірити, чи вона актуальна

Будова

{
  "families": {
    "cisco": {
      "pager": "terminal length 0",       // чим вимкнути посторінковий вивід
      "prompt": "[>#]\\s*$",              // за чим ловити кінець виводу
      "enable_required": true,            // чи потрібен привілейований режим
      "scrub": ["^Building configuration"],  // вирізати з diff — шум, що змінюється щоразу
      "redact": ["(password|secret) \\S+"]   // замаскувати перед записом у Git
    }
  },
  "vendor_family": { "bdcom": "cisco" },   // чий CLI успадкував вендор
  "profiles": [
    {
      "key": "cisco-ios",
      "name": "Cisco IOS",
      "vendor": "cisco",
      "family": "cisco",
      "config": "show running-config",      // головна команда
      "startup": "show startup-config",     // необовʼязково
      "prepare": ["undo terminal monitor"], // необовʼязково: підготовка консолі
      "strip_lines": 3,                     // скільки службових рядків відкинути
      "alternatives": ["show config current_config"]  // для інших моделей родини
    }
  ]
}

Як додати платформу

  1. Додай запис у profiles. Мінімум — key, name, vendor, family, config.
  2. Якщо CLI не схожий на жодну наявну родину — заведи нову у families.
  3. python build.py.
  4. Накоти міграцію (ON CONFLICT DO NOTHING, тож повторний накат безпечний).

Родини

Родина описує поведінку консолі, а не вендора: bdcom, arista, brocade та ще з десяток говорять діалектом Cisco, h3c і 3com — діалектом Huawei. Тримати це один раз на родину, а не копіювати в кожен профіль, — різниця між правкою в одному місці й правкою в сорока.

Родина generic — запасний варіант: промпт [>#]\s*$, без вимкнення пейджера, з обережним маскуванням паролів і community.

Про промпти

prompt і pager задані за родиною й перевіряються на живому залізі. Одна родина покриває десятки платформ, і дрібні відхилення трапляються: прошивка може давати інший символ запрошення або не розуміти команду вимкнення пейджера. Команди збору конфігу натомість специфічні для платформи й узяті точно.

Чому не в БД

Каталог — код, а не дані клієнта: він однаковий для всіх інсталяцій, має переглядатись у code review і їхати разом із релізом. Тенант може завести власний профіль (ncm.profiles із заповненим tenant_id) — вбудовані при цьому лишаються недоторканими.