API ВЕГА
English

Проверяйте изменения в сети до их внедрения в production.

Netdryrun — инструмент с открытым исходным кодом (Apache-2.0), который проверяет изменения в сети в реальной лаборатории containerlab и выдает результат «пройдено/не пройдено» с подтверждающими данными. Он работает как CLI, GitHub Action и MCP-сервер для AI-агентов.

Команды разработки не выпускают код, не запустив тесты. Изменения в сети заслуживают того же подхода: примените их в реальной лаборатории, проверьте поведение сети и внедряйте только после успешной проверки. Netdryrun позволяет выполнить такую проверку одной командой, одним шагом CI или одним вызовом инструмента для AI-агента.

Уже есть лаборатория containerlab? Добавьте в нее Netdryrun за 10 минут: зафиксируйте ее штатное состояние, добавьте одно правило проверки и запускайте тесты при каждом pull request.

Netdryrun™ разворачивает топологию как настоящую виртуальную сеть (containerlab), применяет конфигурации и проверяет фактическое поведение сети: BGP-сессии, количество префиксов, маршруты и доступность. Инструмент выявляет описанные в проверках ошибки, например утечку маршрута, до того, как изменение попадет в production. При этом он сохраняет команды и исходный вывод, чтобы проверяющий мог их изучить.

$ netdryrun run examples/frr-bgp-broken
Deploying lab ndr-frr-broken (3 nodes)...
  [PASS] r1: BGP session to 10.0.12.2 is established -- state is established (6.3s)
  [PASS] r1: ping 192.168.3.1 from 192.168.1.1 expects success -- 3/3 replies (2.3s)
  ... (3 more passing checks trimmed)
  [FAIL] r1: route 0.0.0.0/0 via bgp is absent -- unexpectedly present via bgp (not selected) (0.1s)
FAILED: 5 passed, 1 failed (6 checks)

Этот запуск выявил утечку маршрута по умолчанию, который был получен, но не выбран. Одних проверок ping и состояния сессий в этом случае недостаточно: все сессии установлены, все адреса отвечают. (Статический анализатор, например Batfish, также выявит именно эту утечку. На странице Batfish показан другой случай: его пропускает анализатор, но выявляет лабораторная проверка.)

Статус: v0.4.0. Работает в Linux и WSL2. Поддерживает драйверы для FRR, Nokia SR Linux, SONiC (docker-sonic-vs), Arista EOS (cEOS, образ необходимо предоставить самостоятельно) и Juniper cJunosEvolved (бета-версия, образ необходимо предоставить самостоятельно). На наборе тестов v1 (30 реалистичных изменений BGP: 19 опасных и 11 безопасных) Netdryrun правильно оценил 24 из 30 случаев, проверки только с помощью ping — 20 из 30, а проверки, требующие, чтобы все сессии были установлены, — 15 из 30. Netdryrun одобрил 5 из 19 опасных изменений (проверки только с помощью ping — 10 из 19) и заблокировал 1 из 11 безопасных. В v2 (18 случаев, составленных после v1 для проверки ошибок, допущенных в v1) Netdryrun правильно оценил 16 из 17 детерминированных случаев, проверки только с помощью ping — 9 из 17, а проверки состояния всех сессий — 7 из 17. Результат 18-го случая зависит от запуска в этой лаборатории, поэтому он не включен в оценку; на странице приведены повторные запуски. Ожидаемые результаты были зафиксированы до проведения проверок на одной топологии FRR. Это сравнение методов тестирования, а не оценка надежности в production. Методика, каждый пропущенный случай и повторный запуск одной командой описаны на странице набора тестов. Данные о происхождении результатов: оба набора проверок запускались в Netdryrun 0.3.1.

Почему Netdryrun

  • Проверяет поведение, а не синтаксис. Разница между конфигурациями показывает, что изменилось, но не позволяет понять, установится ли BGP и какие маршруты в итоге получит каждый маршрутизатор. Реальная плоскость управления показывает, как ведет себя ПО маршрутизации.

  • Создан для CI. Один GitHub Action, код завершения «пройдено/не пройдено», сводка в формате Markdown в задании, JUnit XML и JSON-файл с подтверждающими данными — всеми командами и исходным выводом.

  • Ожидает сходимости по заданным правилам. Положительная проверка считается пройденной после двух успешных измерений с интервалом 3 секунды, выполненных до истечения тайм-аута. Отрицательные проверки («этот маршрут должен отсутствовать») и проверки атрибутов наилучшего маршрута ожидают, пока все настроенные BGP-сессии на узле не будут установлены, а количество префиксов не стабилизируется. Сессии, которые, согласно проверке, должны быть отключены, не учитываются. Затем выдерживается 10-секундный период стабилизации, после чего условие должно оставаться верным в течение 10 секунд. Период стабилизации и время подтверждения можно настроить. Если до истечения тайм-аута на узле по-прежнему не обнаружены соседи BGP, проверки все равно выполняются, а результат сообщает, что сходимость BGP не была подтверждена. В сценарии сбоя проверки начинаются только после того, как сбой проявится в BGP; в противном случае запуск завершается с кодом 2. Положительные проверки также должны оставаться успешными в течение заданного времени. Код завершения 0 означает, что проверки пройдены; 1 — что проверки завершились с ошибками; 2 — что тестирование не проводилось из-за проблемы с конфигурацией или лабораторией; 3 — что результат не определен. Правила основаны на измерениях; подробности см. в разделе семантика сходимости.

Быстрый старт

Попробуйте в браузере (без установки)

В Codespace уже установлены Docker, containerlab и Netdryrun. Когда в терминале появится Ready, выполните:

bash examples/agent-demo/demo.sh

Изменение, вызывающее утечку маршрута, будет отклонено, а после исправления все проверки пройдут. Для работы используются бесплатные часы Codespaces, доступные в вашей учетной записи GitHub (машина с 2 ядрами). Подробнее.

На собственном компьютере

Требования: Linux или WSL2, Docker, containerlab, Python 3.10+. В Ubuntu 24.04 и Debian 12 обычная команда pip install вне виртуального окружения запрещена из-за сообщения «externally managed environment». Используйте pipx: sudo apt install pipx && pipx ensurepath, затем откройте новый терминал. Также подойдут uv tool install netdryrun или pip install netdryrun в активированном виртуальном окружении.

pipx install netdryrun
git clone https://github.com/netdryrun/Netdryrun netdryrun && cd netdryrun
netdryrun run examples/frr-bgp          # 3 FRR routers, should pass
netdryrun run examples/srl-frr          # SR Linux + FRR, should pass
netdryrun run examples/frr-bgp-broken   # a bad change, should fail

На собственной топологии containerlab (3 команды)

netdryrun record my-lab/topology.clab.yml --deploy   # snapshot today's behavior into my-lab/netdryrun.yml
# ...edit your configs (the change you want to test)...
netdryrun run my-lab                                   # re-run the checks in my-lab/netdryrun.yml

Команда record создает проверки для каждой установленной BGP-сессии, задает для каждой из них допустимый диапазон количества префиксов — от текущего значения до значения, превышающего его на 20%, но не менее 2, — запрещает получение через BGP маршрута по умолчанию или подсети канала связи и записывает до 50 маршрутов BGP для каждого узла. Сессии, отключенные на момент записи, в проверки не добавляются.

Рекомендация (0.3.3 и 0.4.0): заданный диапазон позволяет пропустить утечку одного или двух дополнительных префиксов от соседа. До выхода версии 0.4.1 используйте при записи параметр --exact-prefixes и добавляйте проверки present: false для префиксов, которые не должны поступать. Рекомендация. Проверьте созданные правила: удалите условия для параметров, которые могут изменяться, и добавьте отрицательные проверки, например present: false. Зафиксируйте результат в репозитории — после этого каждое последующее изменение можно будет проверять по этим правилам локально или в CI. Успешный результат означает только то, что указанные проверки пройдены.

netdryrun.yml

lab: topology.clab.yml      # your containerlab topology
timeout: 90                 # seconds a positive check may wait for convergence

checks:
  - type: bgp_session       # session reaches a state (default: established)
    node: r1
    neighbor: 10.0.12.2
  - type: bgp_prefixes      # accepted prefix count within a range
    node: r1
    neighbor: 10.0.12.2
    min: 1
    max: 10
  - type: route             # route present (or absent), optionally via a protocol
    node: r1
    prefix: 192.168.3.0/24
    protocol: bgp
  - type: ping              # reachability, optionally from a source address
    node: r1
    source: 192.168.1.1
    target: 192.168.3.1
  - type: route             # negative check: must stay absent after convergence
    node: r1
    prefix: 0.0.0.0/0
    protocol: bgp
    present: false

Сценарии отказа имитируют неисправность, проверяют, что сеть продолжает работать, а затем восстанавливают исходное состояние. Они могут отключать каналы связи или, начиная с версии 0.3.1, заставлять соседа FRR анонсировать маршруты, которые он анонсировать не должен. Так можно проверить, что ограничение max-prefix или фильтр импорта действительно работает:

scenarios:
  - name: r1-r2 link fails
    link_down: {node: r1, interface: eth1}
    checks:
      - {type: ping, node: r1, source: 192.168.1.1, target: 192.168.2.1}   # rerouted via r3
      - {type: bgp_session, node: r1, neighbor: 10.0.12.2, state: down}
  - name: customer floods 200 prefixes
    inject_routes: {node: ce1, count: 200, from: 10.100.16.0/24}
    checks:
      - {type: bgp_prefixes, node: up1, neighbor: 10.0.2.1, max: 51}   # the limit stops the flood

Для каждой проверки можно также задать name, timeout и vrf. Для проверки ping доступны параметры expect: failure и count. Драйверы определяются по топологии; при необходимости задайте их явно: nodes: {r1: {driver: frr}}. Для узлов, которые настраиваются после запуска (SONiC), предусмотрены команды setup: nodes: {sonic1: {setup: [...]}}.

ПроверкаFRRSR LinuxArista EOS (cEOS)SONiC (VS)
bgp_session✅✅✅✅
bgp_prefixes (принятое количество = полученные префиксы минус отклонённые политикой)✅✅✅✅
route — маршрут присутствует / отсутствует✅✅✅✅
bgp_route — атрибуты лучшего маршрута: communities (стандартные, большие, общеизвестные), AS path (точное совпадение или регулярное выражение), local preference, MED, next hop✅✅✅✅
ping — успешная / неуспешная проверка связи✅✅✅✅
Как выполняется проверкаЛабораторная среда запускается в CI при каждом pushЛабораторная среда запускается в CI при каждом pushПарсеры проверяются на выводе, полученном в работающих лабораторных средах; в CI лабораторная среда не запускаетсяПарсеры проверяются на выводе, полученном в работающих лабораторных средах; в CI лабораторная среда не запускается

Команды

КомандаНазначение
netdryrun run [path]Развернуть лабораторную среду, выполнить проверки и удалить среду. Добавьте --keep, чтобы оставить её запущенной для отладки
netdryrun check [path]Выполнить проверки в уже запущенной лабораторной среде
netdryrun validate [path]Проверить netdryrun.yml и топологию, не запуская лабораторную среду
netdryrun record topology.clab.ymlСохранить снимок заведомо исправной лабораторной среды в качестве базовой конфигурации netdryrun.yml, чтобы не задавать проверки вручную

Отчёты: --json FILE (полные данные проверки), --markdown FILE, --junit FILE. В GitHub Actions сводка автоматически добавляется на страницу задания. Коды завершения: 0 — проверки пройдены, 1 — проверка не пройдена, 2 — результат не определён (ошибка конфигурации или лабораторной среды, неисправность не проявилась либо произошла внутренняя ошибка; добавьте --debug, чтобы получить трассировку), 3 — результат неубедителен (лабораторная среда не достигла состояния, пригодного для проверки, поэтому запуск ничего не говорит об изменении), 130/143/129 — выполнение прервано сигналом SIGINT/SIGTERM/SIGHUP после очистки лабораторной среды.

GitHub Action

name: Network dry run
on: pull_request
jobs:
  dryrun:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: netdryrun/Netdryrun@v0.4.0
        with:
          path: network/        # folder containing netdryrun.yml

Action устанавливает containerlab, выполняет проверки и загружает отчёты JSON и JUnit как артефакт. Если какая-либо проверка не пройдена, задание завершается с ошибкой. Выходные параметры: status, passed, failed, inconclusive-reason.

Для AI-агентов (MCP)

Сервер внесён в официальный реестр MCP (io.github.netdryrun/netdryrun), а также опубликован на Glama; навык агента доступен и на Smithery.

AI может предлагать изменения в сети. Netdryrun проверяет их результат. Агенты: ознакомьтесь с файлом AGENTS.md.

Агенты для программирования не ищут средства проверки самостоятельно: в нашем тестировании они не стали искать такое средство. Подключите Netdryrun к рабочему процессу агента за две минуты — как проверку pull request, правило в AGENTS.md или MCP-сервер: Добавьте его туда, где работает ваш агент.

AI-агенты начинают вносить изменения в сети. Netdryrun служит для них защитным барьером: это сервер MCP, который позволяет агенту проверить изменение в работающей лабораторной среде и продолжить работу, только если все проверки пройдены.

pipx install netdryrun   # or uv tool install netdryrun

Добавьте сервер в свой MCP-клиент, например Claude Code:

claude mcp add netdryrun -- netdryrun mcp

Инструменты: dry_run (развернуть среду, выполнить проверки, удалить среду и вынести вердикт), run_checks (выполнить проверки в уже запущенной среде), record_baseline (сохранить снимок заведомо исправной среды в виде проверок), validate, check_types. Каждый результат содержит отдельное поле verdict: CHECKS PASSED (only what the checks cover), DO NOT APPLY THIS CHANGE или INCONCLUSIVE: the lab did not reach a testable state; ..., если лабораторная среда не запустилась. Вердикт CHECKS PASSED (only what the checks cover) означает лишь, что в лабораторной среде пройдены все проверки из файла, и сам по себе не подтверждает безопасность изменений. Изменение может нарушить работу того, что не проверяется, и всё равно получить такой результат: в нашей оценке AI-агентов агент добавил redistribute connected в рамках «чистого рефакторинга» и прошёл проверку, поскольку дополнительные маршруты не проверялись. Если изменение не должно менять поведение, сначала сохраните базовую конфигурацию. Начиная с версии 0.3.2 строки вердиктов зафиксированы (в версии 0.3.1 при успешной проверке выводилось SAFE TO PROCEED; ориентируйтесь на status, а не на текст). В результатах с ошибками перечисляются все непройденные проверки, причины, фрагмент данных проверки и одна команда для следующей диагностики, доступная только для чтения. Формат результата опубликован в виде JSON Schema: mcp-result-v1.json.

Демонстрация (examples/agent-demo): в задаче сказано, что новый блок адресов заказчика должен быть доступен со стороны вышестоящего узла и пира. Очевидное решение проходит все проверки задачи, включая проверку сессии и ping, но приводит к утечке маршрутов, поэтому Netdryrun его отклоняет. Исправление из двух строк проходит те же проверки. (Сценарий воспроизводит обе попытки; он запускается в CI.)

Навык агента

Файл skills/netdryrun/SKILL.md описывает правила для агента, работающего с кодом: перед применением изменений маршрутизации проверять их в dry-run, приводить вердикт, останавливаться при неубедительном результате, не создавать и не ослаблять проверки ради успешного прохождения и использовать record_baseline, если проверок нет. Установите навык из Git URL репозитория (начиная с версии 0.3.2):

git clone --depth 1 https://github.com/netdryrun/Netdryrun /tmp/netdryrun
mkdir -p ~/.claude/skills && cp -r /tmp/netdryrun/skills/netdryrun ~/.claude/skills/   # Claude Code, every project

Чтобы сделать навык доступным всем, кто работает в одном репозитории, скопируйте папку в .claude/skills/netdryrun/ и добавьте её в репозиторий. Другие клиенты, поддерживающие Agent Skills (папку с файлом SKILL.md), используют ту же папку. Для работы навыка требуется MCP-сервер, описанный выше; без него агент использует CLI.

Модель безопасности:

  • Сервер никогда не обращается к рабочей сети. У него нет инструментов для отправки конфигурации куда-либо: он только создаёт и проверяет лабораторные среды.

  • Результаты работы инструментов содержат нормализованные результаты проверок, а не полный вывод устройств. Поле detail может включать фрагмент текста из лабораторной среды, например баннер или описание маршрута. Начиная с версии 0.3.2 для каждой непройденной проверки также приводится короткий фрагмент данных: каждый фрагмент занимает одну строку и ограничен по длине. Ни один из них не меняет значения status или verdict. Необработанные данные сохраняются в JSON-отчёте.

  • Лабораторная среда — это код: containerlab запускает контейнеры с привилегированным доступом. Указывайте серверу только те топологии, которым доверяете, и используйте его на машине, на которой вы готовы запускать Docker.

Сравнение с другими инструментами

Netdryrun дополняет эти инструменты, а не заменяет их.

ИнструментДля чего подходит лучше всегоВ чём помогает Netdryrun
BatfishСтатический анализ конфигураций без запуска оборудования; быстро и с широким охватомNetdryrun запускает реальный control plane и проверяет поведение во время работы: сходимость, фактически установленные сессии и маршруты, которые действительно попали в RIB
pyATS / GenieПолноценная тестовая среда с глубокими парсерами CiscoNetdryrun — это небольшой декларативный YAML-файл и один GitHub Action: писать тестовый код не нужно
containerlabЗапускает лабораторную средуNetdryrun управляет containerlab, но не заменяет его

Netdryrun добавляет ожидание сходимости перед положительными проверками; отрицательные проверки выполняются только после сходимости и должны оставаться истинными. Маршруты, которые получены, но не выбраны, считаются присутствующими. Каждый запуск формирует итоговый результат «пройдено/не пройдено» и файл с доказательствами.

Ограничения

  • Маршрутизаторы в лабораторной среде — не ваши производственные маршрутизаторы. Успешная проверка на FRR, SR Linux, SONiC VS или Arista cEOS — весомое подтверждение корректности логики протоколов и намерений, заложенных в политике, но не доказательство поведения оборудования, работы в масштабе или особенностей конкретной версии. Для тестирования реального кода Arista используйте собственный лицензированный образ cEOS.

  • Проверки охватывают одноадресный BGP для IPv4/IPv6 (сессии, количество префиксов, атрибуты лучшего маршрута), маршруты и ping, а также сценарии отказа: отключение канала, изоляцию узла и внедрение маршрута (только FRR). Проверки маршрутов уже поддерживают маршруты из любых протоколов (protocol: ospf, isis, static, connected, ...); проверки соседства OSPF/IS-IS и пути/traceroute появятся позже.

  • В выпущенной версии пока нет драйверов для Cisco и Juniper. Для их лабораторных образов нужна учётная запись у производителя, а сами образы нельзя распространять. Поэтому для этих драйверов, как и для cEOS, потребуется собственный образ. Следующими в плане развития идут Juniper и Cisco NX-OS.

О том, как проверяются и выпускаются результаты и какие доказательства подтверждают каждое утверждение: Как это устроено.

План развития

Это направление развития, а не обязательство: версия выпускается, когда все условия её релиза выполнены, а не к определённой дате.

  • 0.4.1 (текущая): исправление GHSA-cg9f-xjw5-38ph, бета-версии Cisco NX-OS и MikroTik, усиление защиты цепочки поставок

  • Позже: контракт состояния маршрутизатора для всех драйверов, бета-версия Cumulus, надёжность проверок и подписанные подтверждения результатов, бета-версия размещённой проверки, затем OSPF/IS-IS, пути, EVPN и MPLS — по мере спроса

Полный план развития: netdryrun.com/roadmap.

Если Netdryrun помог вам обнаружить проблему, поставьте ⭐ — так другим инженерам и агентам будет проще найти этот проект.

Лицензия

Apache-2.0. «Netdryrun» и логотип Netdryrun являются товарными знаками; подробности см. в файле TRADEMARKS.md.