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>
4.1 KiB
Каталог команд збору конфігу
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"] // для інших моделей родини
}
]
}
Як додати платформу
- Додай запис у
profiles. Мінімум —key,name,vendor,family,config. - Якщо CLI не схожий на жодну наявну родину — заведи нову у
families. python build.py.- Накоти міграцію (
ON CONFLICT DO NOTHING, тож повторний накат безпечний).
Родини
Родина описує поведінку консолі, а не вендора: bdcom, arista,
brocade та ще з десяток говорять діалектом Cisco, h3c і 3com —
діалектом Huawei. Тримати це один раз на родину, а не копіювати в кожен
профіль, — різниця між правкою в одному місці й правкою в сорока.
Родина generic — запасний варіант: промпт [>#]\s*$, без вимкнення
пейджера, з обережним маскуванням паролів і community.
Про промпти
prompt і pager задані за родиною й перевіряються на живому
залізі. Одна родина покриває десятки платформ, і дрібні відхилення
трапляються: прошивка може давати інший символ запрошення або не
розуміти команду вимкнення пейджера. Команди збору конфігу натомість
специфічні для платформи й узяті точно.
Чому не в БД
Каталог — код, а не дані клієнта: він однаковий для всіх інсталяцій,
має переглядатись у code review і їхати разом із релізом. Тенант може
завести власний профіль (ncm.profiles із заповненим tenant_id) —
вбудовані при цьому лишаються недоторканими.