Network diagram as code / Схема сети как код
В последние пару лет стал больше заниматься документацией. Написать поясняющий текст о том, как работает та или иная система — в целом, это достаточно просто. Нарисовать схему, на которой будут отображены все ключевые объекты, связи между этими объектами, тоже вполне легко.
Но самый проблемный момент — это поддерживать эту документацию в актуальном состоянии. И ладно бы текст, но схемы… Т.к. вся документация онлайн, т.е. в формате html, то к тексту прилагаются картинки gif/jpeg/png, на которых собственно изображены схемы. А схемы рисуются в различных программах типа Visio или онлайн-сервисах а-ля draw.io. Затем экспортируешь схему в графический формат и прилагаешь к html. Все просто.
В чем проблема?
Схемы обычно простые. Точнее, не сильно сложные. Да, количество объектов десяток-два, количество связей примерно столько же. Плюс подписи, какие-то обозначения. Простые схемы и на словах описать можно, а слишком сложные, кх-м… (с) «не поймут-с». Схем много, изменения в них нужно вносить периодически-эпизодически, т.е. постоянно, т.к. они идут вслед за разработкой наших продуктов.
Можно же встраивать html сервиса. Пробовал?
Да, конечно. Мне, например, нравятся графики gliffy.com. Но для изменений надо идти в сторонний сервис, там править. И сложнее делегировать сделать поправки коллеге.
Недавно на гитхабе мне попался в рекомендациях репозиторий github.com/RaoulMeyer/diagram-as-code. Диаграмма как код. Т.е. мы описываем на js нужную нам схему. Этот js мы пишем прямо в том же html, где и прочий текст документации.
К слову сказать, но я пишу документацию не совсем в html. Обычно документация — это набор файлов с markdown-текстом, который затем конвертируется в полноценный сайт документации каким-нибудь движком, например wintersmith. Или wiki-система.
Получается очень удобно: вот мы написали текст, затем открывается тег script и в нем описан js код схемы.
Что опять не так?
Этот репозиторий мне понравился, но это не единственный пример когда диаграмму рисуют с помощью кода или текстового представления. (В конце статьи будут ссылки проектов и статей, которые нагуглил по теме diagram as code.)
И ведь я не один правлю документацию. Иногда свою лепту вносят и коллеги — слово поправить, описание изменить, новые картинки вставить.
Поэтому хотелось бы диаграмму видеть в читаемом понятном текстовом формате, которому бы не пришлось долго обучаться. А местами даже просто copy-paste сделать для ускорения добавления новой схемы.
А еще один коллега заметил, что код это, конечно, хорошо, но если использовать структуру, все может быть очень строго и выразительно.
Поэтому я попробовал представить схему как набор нескольких небольших массивов, которые описывают узлы, связи, группы узлов, а также расположение узлов. Получилось на мой скромный взгляд достаточно удобно, хотя, конечно, на вкус и цвет…
Как это диаграмма в массиве?
- Каждый узел описывается идентификатором, который однозначно определяет узел.
- Также к узлу можно добавить иконку, добавить надпись.
- Между двумя узлами можно указать связь.
- Для связи на схеме можно задать цвет, надпись.
- Направление связи определяется как от источника к цели. А источник и цель указываются идентификаторами узла.
- Один и более узлов можно добавить в группу.
- Связь также можно указать и от группы, и к группе.

А описывается она следующим js-кодом. Основное здесь — это объект elements. В котором указаны nodes — узлы, edges — связи.
const elements = < nodes: [ // описываем узлы < id: 'client', type: 'smartphone', label: 'Mobile App'>, < id: 'server', type: 'server', label: 'Main Server'>, < id: 'db1', type: 'database', label: 'DB 1'>, < id: 'db2', type: 'database', label: 'DB 2'>, ], edges: [ // указываем связи < source: 'client', target: 'server', label: 'request' >, < source: 'server', target: 'db1', label: 'request' >, < source: 'server', target: 'db2', label: 'request' >, ], >; Diagram('scheme1', elements);
Конечно, отрисовку схемы я придумал не сам, а воспользовался библиотекой cytoscape.js — очень мощный инструмент визуализации. Толику возможностей которой в своем решении использую лишь.
Понятно, это простой пример. Можно посложнее?
Да, пожалуйста. Для указания позиций — мы используем positions, для указания групп — указываем список групп в groups, а у самих элементов атрибут group.

Такая схема с одной стороны — это почти пара экранов кода на ноуте, с другой структура а-ля json позволяет заполнять все данные по аналогии, быстро и можно copy-paste.
А почему positions вынесены отдельно от узлов?
Так удобнее. Сначала мы указываем nodes. Затем можем указать пару-тройку групп и указать их в узлах. Затем обозначаем связи. А уж затем, когда основные объекты и связи между ними есть, беремся за расположение этих объектов на схеме. Или наоборот.
А можно без positions?
Можно и без positions. Но это будет немного скомкано, в примерах можно посмотреть такой вариант. Это обусловлено тем, что для cytoscape есть алгоритм расположения узлов fcose, который также учитывает наличие групп. Указание positions делает схему более контролируемой, но на стадии первого наброска схемы можно и без positions.
Также positions можно указывать в стиле Морского боя. Т.е. один узел располагается в a1, а другой в d5. Особенно помогает, что cytoscape формирует объекты на canvas подвижными, т.е. мы можем их подвигать, посмотреть разные варианты расположения, а затем зафиксировать в коде понравившееся расположение элементов.
В целом, понятно. Можно попробовать?
Конечно, для быстрого создания схем сделал себе небольшой редактор, который сам обновляет схему и в браузере хранит последний вариант (в localStorage).
Попробовали? Можно теперь и к себе на страницу добавить.
1. Подключаем скрипт
2. Добавляем в html код
3. правим код до нужной нам схемы (думаю, это проще чем нарисовать сову 🙂
Еще подробнее на странице проекта на гитхабе.
Что в итоге?
Своих целей я достиг — сделать добавление схем inline в документацию, формат достаточно простой и понятный. Для суперсхем не подойдет, а для небольших схем, поясняющих структуру связей — очень даже ничего. Всегда можно быстро подправить и что-то с течением времени поменять. Да, и коллеги могут в доке сами что-то подправить, как минимум подписи к объектам без особого обучения ))
Что можно улучшить?
Тут вариантов, конечно, масса. Сделать добавление дополнительных иконок (все имеющиеся добавлены inline в скрипт). Подобрать более выразительный набор иконок. Сделать возможность указания стиля линии связей. Добавить фоновое изображение.
А что думаете вы?
У меня уже есть несколько идей на реализацию в issues, вы также добавьте свои в комментарии.
- Репозиторий
- Примеры
- Онлайн-редактор
- Хорошая подборка
- Шикарный сервис (9 типов графиков онлайн-редактор)
- Конечно, mermaid.js
- И если вам любы супер детальные и сложные схемы — то вас определенно восхитит этот проект: go.drawthe.net
Как сгенерировать L3 network map
Многие из вас читали статью «Как создавать понятные логические (L3) схемы сети», после которой возникало непреодолимое желание задокументировать своё сетевое хозяйство. Два-три подхода, потом легко удавалось договориться с собой что изменения будут внесены в конце недели, месяца и т.д. По прошествии некоторого количества времени приходило понимание, что точечными изменениями уже не обойтись — надо так много двигать и компоновать, что проще всё сделать заново. Очередной этап принятия (и даже можно себя похвалить что «умеем, могём рисовать схемы, просто это пока не нужно»), но пора переходить на следующий уровень.
Да, программы которые по сути сами документируют и рисуют картинку сети, благо железяки сейчас все интеллектуальные и охотно рассказывают о свой начинке и немного о соседях. Неполный перечень софта приведён в статье «Network Maps. Краткий обзор софта для построения карт сети». Разочарование приходит довольно быстро — достаточно пощупать пару-тройку программ или даже почитать описание. Для примера тот-же Zabbix – великолепен, как система мониторинга и сбора метрик со всего, до чего можно дотянуться, но его так называемые «карты сети» таковыми называться не имеют права. Это скорее «мнемосхемы». Создавать и поддерживать их в живом состоянии тяжело и неинтересно. Другая крайность — рисовать на карте всё что шевелится имеет ip-адрес. Разумеется в презентации, где нарисованы сервера, 3 рабочие станции и коммутатор, это выглядит великолепно. В реальной жизни имеет вид безобразного месива.
В предыдущем абзаце я написал что список софта не полон. Имею личный опыт работы с HP OpenView NetworkNodeManager (ещё с прошлого века :)). Это энтерпрайз и довольно дорогой. Не буду топить за него т. к. вроде более 10 лет назад он завершил своё существование версией 6.22 и уже не продаётся (но это не точно — пока готовил статью, наткнулся на упоминание HP OV NNMi community edition версии 7 – скачать правда не удалось). Собственно исходя из опыта использования и знания внутренней структуры пока считаю OpenView эталоном в части построения карты сети. Разработчики и программа «росли» вместе с мировыми представлениями о сетях, вместе с развитием технологий. Да что там говорить – HP сама их активно создавала. В общем инженеры знали своё дело, молодцы. Даже когда реализация некоторых вещей в OpenView казалась неудобной и нелогичными, после прочтения документации и некоторого осмысления приходило понимание что делать надо было именно так. Скриншотик этой красоты прилагается

Впрочем довольно воспоминаний — переходим к сути.
Автоматически нарисовать карту L3 просто. Даже не надо спецсредств — будет достаточно компьютера под linux, доступ по snmp ко всем сетевым устройствам. Минимальный набор требуемого софта имеется во всех дистрибутивах. Первым этапом просканируем сеть на наличие живых устройств (fping/nmap), вторым этапом собираем с них информацию (snmpwalk). Этап три — нормализовать информацию с использованием bash/awk/sed/python/perl/php – кому что ближе. Генерация карты также реализуется программно, например через graphviz.
Этап номер 1. Можно не делать, но лучше пингануть т.к. таймауты при snmp-опросе довольно большие. Может так случиться что за время опроса поймаем network reconfiguration. Чем больше сеть, тем больше шансов.
Обсудим этап два. В какие веточки snmp-агента надо смотреть? System — обязательно, также потребуется ip.ipAddrTable , interfaces.ifTable . Таблицы маршрутизации берём из ip.ipRouteTable (или из IP-FORWARD-MIB ). Значения из system предлагаю хранить все т.к. например SNMPv2-MIB::sysObjectID.0 позволит прилепить к сетевому объекту иконку, соответствующую реальному типу оборудования а также дополнительно заглянуть в соответствующие vendor MIB. А разглядывая 3-й бит SNMPv2-MIB::sysServices.0 можно отделить маршрутизирующее оборудование от L2 или конечных хостов.
Этап три — нормализация. Тоже довольно просто. И прежде всего, надо удалить дубликаты т. к. мы сканируем все доступные адреса, а оборудование может охотно отзываться со всех своих сетевых интерфейсов. Возможно захочется привести имена интерфейсов к единому виду (кто работал с cisco поймёт). Также надо законопатить «чёрные дыры» — если, например, две сети соединены через железяку по каким-либо причинам не желающую с нами сотрудничать и не отзывающуюся по snmp, то мы можем вручную в определённом файле это описать с необходимыми интерфейсами/адресами/метаданными и наш «нормализатор» учтёт эту информацию при формирования топологии. Нужно почистить интерфейсы loopback и маршруты к ним прилагающиеся. В таблицах маршрутизации интерес представляют только статические маршруты. Можно посмотреть какие интерфейсы сконфигурированы, но опущены административно. В общем много тут нужно сделать, и я однозначно что-нибудь пропустил.
Рисование карты. Как уже писал ранее можно сразу и быстро сгенерировать gv-файл и получить картинку с помощью graphvis. Если просто нарисовать каждый сетевой объект как квадратик, сеть как круг(эллипс) и объединить устройства и сети линиями, то результат вас скорее всего не обрадует. Требуется более тонкая работа по чистке карты сети:
1. Сокрытие конечных устройств. Понятно, что вроде как сеть должна состоять из сетевых устройств, но часть из них абсолютно не нужны на карте. Это например рабочие станции, периферийное оборудование и прочие девайсы имеющие только один интерфейс. Их рисовать не надо, схема станет на порядок чище (HP OpenView на верхний уровень не выносил хосты и также позволял вручную скрыть объекты). Наглядно постарался отразить на картинке: слева — до (как выглядит схема без учёта данного правила), справа — после (т.е. правило мы принимаем).

как это сделано
всё очень просто. Делаем текстовый файлик test.gv примерно такого содержания:
graph method1
упоминаемые по тексту картинки кладём рядышком и утилиткой neato генерируем картинку:
$ neato -Tsvg -O test.gv
подробности по синтаксису входного файла и командной строки netato (и не только) ищите на https://graphviz.org
также прошу обратить внимание что правая и левая картинки здесь и далее отличаются по взаимному положению элементов. Это не специально, просто утилита генерирует оптимальное расположение элементов. Их количество меняется, значит и разместить надо по-другому. Конечно можно зафиксировать координаты объектов вручную, но мы ведь изначально планировали уйти от подобных методов 🙂
2. Агрегирование локальных сетей. Вот здесь у OpenView было то, что мне уже не нравилось 🙂 каждая сеть — отображалась отдельно. На заре развития сетевых технологий это было нормально, но при появлении 802.1q и активном использовании vlan на картах стало совсем тесно. А вот если собрать все эти «конечные» сети в один объект то работать с этим станет значительно легче. Можно ещё контур нарисовать потолще.

3. Соединения точка-точка. Тут я думаю ни у кого возражений не будет. Зачем на ppp-каналах рисовать сеть, когда к ней никаких дополнительных подключений не будет? Значит вместо сети рисуем линию.

4. Мультилинки. Есть и такие случаи. Не всегда удаётся объединить каналы на физическом уровне и осуждать тут некого. Но ворох линий заменим на одну жирненькую.

5. Соединение точка-точка без второго узла. Про существование этого узла можно догадаться по маске /30 на интерфейсе. Можно конечно не рисовать (см. правило №1), но вдруг это то, о чём мы слегка запамятовали? Исходя из маски и ip-адреса интерфейса на нашей стороне посчитаем какой адрес будет у соседа. Нарисуем серым цветом, с прямым подключением разумеется — на финальной картинке увидим, вспомним и возможно исправим.

почему это не совсем правильно
есть нюансы. Например для ppp можно ставить адреса абсолютно из разных диапазонов, даже более того — можно и адреса не ставить. Но мы полагаемся на вековые традиции старейшин.
6. Статический маршрут. Это уже косвенная информация из таблицы маршрутизации. Статический маршрут на маршрутизаторе R1 вида (это кусок с линукса, но важна суть а не форма):
10.10.1.0/24 via 10.10.1.10 dev enp0s3
При попытке снять с шлюза информацию напрямую, по snmp, мы потерпели фиаско, но всё равно имеем возможность отобразить и его и сеть, которая за ним скрывается. Это разумеется не совсем достоверная информация, поэтому мы покажем её серым цветом и штрихами.

7. Агрегирование сетей с идентичными подключениями. Частный случай пункта №2. Решил его описать отдельно, ибо так безобразно выглядят сетки/vlan-ы которые маршрутизируют несколько коммутаторов Cisco с hsrp. На OpenView это тоже выглядит устрашающе (у меня было 3 «шеститонника» с горсткой vlan-ов – просто жуть).

8. Отображение шлюза по умолчанию (default gateway). Да, также из таблицы маршрутизации. Может стоит отображать не серым цветом? Тут я ещё не определился.

9. Маркировка. Подписи объектов требуют особого осмысления. В OpenView по умолчанию показывались только имена сетевых объектов и адрес сети(без маски). По отдельной кнопке включались подписи всех линков и интерфейсов. Неудобно, но других вариантов я не припомню.
Если убрать избыточную информацию со схемы, то будет примерно такой вид:

Его конечно можно ещё почистить — например можно не указывать неизменную часть префикса сети (192.168) или, если деление было крупным, заменять на мнемонические названия. Другой вариант — дополнительная информация появляется при определённых степенях масштабирования картинки (graphviz-ом это не сделать).
Вот в принципе и всё что требуется для автоматического создания карты сети L3. Понятно, что ковыряя vendor-MIB можно добыть больше информации, вплоть до L2 (кстати, тоже очень интересная тема, начал тоже фантазировать на эту тему). Также пока нет понимания что делать с асимметричным роутингом, с криптошлюзами/файрволами/туннелями, трансляцией адресов и т.д. Если есть готовые рецепты — пишите, я статью дополню. Также хочу сказать что gfaphviz это для затравки 🙂 Можно и нужно всё делать более современными и интерактивными методами, с базой данных, многопоточным опросом, отрисовкой через web. Масштабирование, редактирование, перемещение объектов — и всё это мышкой с удобными менюшками и формами. Вдобавок можно через api брать состояние девайсов от того же zabbix-а. Красивоe!
Ну и в качестве примера — немного обфусканая карта реальной сети.
Сделано было не по всем описанным канонам, вместо картинок объектов просто квадратики (в формате svg картинки подтягиваются по ссылкам, а png получается слишком большим). Также отсутствуют подписи интерфейсов. Сама карта рассыпалась — следствие того, что не убраны «чёрные дыры». Всё дело в том, что это был один pet-проект, который уже лет 5 лежит у меня на жёстком диске, и полагаю готов там умереть. Сейчас у меня даже нет доступа к полигону (писать минимальный эмулятор сети неохота, а, к примеру, gns такие масштабы не вытащит). Если кто созреет на разработку, готов с радостью подключиться.
- Системное администрирование
- IT-инфраструктура
- Сетевые технологии
- Прототипирование
- Подготовка технической документации
Как создать схему электрической цепи
Принципиальная схема, электронная схема или схема электрической цепи — как бы ни назывался этот графический ресурс, без него не обойтись ни одному инженеру-электрику. В этой статье мы рассмотрим, как создать эффективную электрическую схему и какие функции Lucidchart помогут нам в этом процессе.
Читается за 5 мин.
Хотите создать схему электрической цепи самостоятельно? Попробуйте Lucidchart! Быстро, удобно и совершенно бесплатно.
Почему Lucidchart идеально подходит для проектирования принципиальных схем
Если вы ищете приложение для создания электрических схем и других видов диаграмм, у вас множество вариантов. Однако мы не сомневаемся, что Lucidchart уверенно обойдет конкурентов по нескольким причинам. Прежде всего, над нашим приложением постоянно трудится команда блестящих специалистов, которые регулярно радуют пользователей Lucidchart новыми функциями и доработками. Кроме того, мы предлагаем бесплатные учетные записи для физических лиц, студентов и преподавателей, а также лицензии для целых команд по доступным ценам. Бесплатная учетная запись позволяет создать схему электрической цепи с применением до 60 объектов. Сам же процесс построения схемы одинаков для всех пользователей независимо от уровня подписки, а полная библиотека фигур для электрических схем открыта даже обладателям бесплатного аккаунта. Если вы подумываете перейти на премиум-подписку, ее сначала можно попробовать бесплатно — без всякого подвоха!
Как создать схему электрической цепи в Lucidchart
НАЧАЛО РАБОТЫ
Электрические схемы редко создаются с нуля, особенно если за работу взялся новичок. Поэтому, пока вы не набьете руку, рекомендуем брать за основу изображение готовой схемы. Его можно позаимствовать у преподавателя или руководителя, а можно просто найти в интернете. Благодаря функции импортирования вы также можете загрузить в Lucidchart готовую схему из Visio и «плясать» от нее.
1. Зарегистрируйте учетную запись в Lucidchart.
2. Откройте раздел «Мои документы».
3. Нажмите «Создать» > «Создать документ».
4. Выберите подходящий шаблон схемы электрической цепи в UML-разделе нашей библиотеки или создайте документ Lucidchart.
ФИГУРЫ И СИМВОЛЫ
5. Четко сформулируйте цель построения схемы. Объединить несколько цепей в одну? Дополнить готовую схему новыми компонентами? Также убедитесь, что вы ясно представляете масштаб проекта, включая время на его выполнение.
6. Настало время начертить схему. Начните с общего вида соединений проводки. Кстати, чтобы нарисовать в Lucidchart линии для обозначения связей, достаточно нажать клавишу L на клавиатуре, щелкнуть мышкой и протянуть линию в нужном направлении. Чтобы отформатировать линию, нажмите по ней правой кнопкой мышки, предварительно выделив линию на холсте, либо выберите необходимый параметр на панели настроек в верхней части страницы.
7. Добавьте остальные компоненты. Ознакомьтесь с полной библиотекой фигур для электрических схем и убедитесь, что в ней есть все необходимые элементы. Если чего-то не хватает, недостающий объект можно легко загрузить в виде изображения с компьютера или найти в коллекции значков нашего редактора.
8. Если вы перетащили на холст значок источника питания, выделите его щелчком мышки. Перед вами откроется меню, где можно указать метку, ориентацию и заряд. Проверьте, правильно ли указаны значения по каждому компоненту.
9. Продолжайте добавлять элементы, пока на схеме не появятся все связи между устройствами, включая соединения для передачи питания и сигналов. Не забывайте, что электрические схемы, как правило, не отражают реальное расположение компонентов цепи в пространстве.
ПРОВЕРКА
10. Схема почти готова. Но прежде чем пустить ее в дело, задайте себе следующие вопросы:
- Широко ли доступны компоненты схемы?
- Ведет ли себя цепь так, как ожидалось?
- Легко ли читается схема?
В качестве последнего шага предлагаем показать полученную схему кому-то, кто разбирается в электрических цепях, и спросить, всё ли устроено логично. Свежий взгляд на проект очень пригодится вам в работе.
Бесконечные варианты изображений и значков
Для точного результата вам потребуется полная библиотека фигур для электрических схем. Желательно, чтобы эти фигуры также было легко форматировать. К счастью, Lucidchart предлагает широчайшую коллекцию стандартных фигур плюс возможность импортировать собственные объекты, например, наборы элементов из Visio или файлы SVG. Кроме того, значки и изображения можно п