воскресенье, 15 мая 2016 г.

PortViewer

Продолжая разговор об использовании swtoolz-core плавно переходим к проекту PortViewer. Это инструмент для быстрого и удобного получения информации о портах маршрутизаторов и коммутаторов. В нашей сети примерно 3500 коммутаторов D-Link различных моделей и ревизий. Биллинг "понимает" их и умеет с ними работать. Включить/выключить порт, отобразить состояние порта абонента, продиагностировать кабельную линию - все это можно сделать из системы отслеживания заявок. Однако, помимо коммутаторов доступа в сети имеется около 60 маршрутизаторов и коммутаторов агрегации. И вот с ними беда - разные вендоры, разные модели и модули и т.д. Система отслеживания заявок и биллинг с этими железками "не дружат." А, между тем, там тоже есть много портов, за которыми надо бы как то присматривать. Да, Zabbix всегда напомнит про "упавший" порт, но иногда хочется иметь более наглядную картину. Упал порт на какой то железке? Окей. А сколько у меня на ней вообще портов? В скольки модулях?  Сколько из этих портов должно работать? А сколько работает в данный момент? Сколько есть свободных портов в запасе? На эти вопросы проще всего ответить, имея перед глазами наглядную картину. И эту картину в нашей сети рисует PortViewer.

Казалось бы, а при чем здесь swtoolz-core? А на самом деле очень даже при чем. Несмотря на то, что PortViewer способен отрисовать состояния портов на нескольких десятках различных устройств, поддерживает он при этом, всего одну модель. Некое абстрактное сетевое устройство с заранее заданным набором свойств. Эти свойства описывают модули устройства, состояния портов и их количество. PortViewer запрашивает эти данные у swtoolz-core, после чего интерпретирует их по специальному алгоритму. Иными словами, для PortViewer нет разницы, работает ли он с устройством D-Link, Brocade, Cisco или Eltex. Главное - чтобы само устройство в принципе было способно отдать по SNMP требуемые данные, а также, чтобы для данной модели устройства у swtoolz-core был подготовлен соответствующий модуль. Таким образом, если хочется видеть состояния портов у какой то новой, экзотической железки, то ее нужно "добавлять" не в PortViewer, а в swtoolz-core. Вот такой вот симбиоз. Его преимущества очевидны. Во-первых, разработчику, проектирующему front-end, нет необходимости ломать голову над тем, как получить конкретный параметр с конкретной железки. А, во-вторых, администратор, отвечающий за back-end, не путается в ненужных ему алгоритмах. В данном случае он имеет дело только с конфигурационным файлом, содержащим списки параметров и OID.

Пора, пожалуй, завершить это уже несколько затянувшееся вступление и перейти, собственно, к демонстрации возможностей PortViewer. Поскольку автор на странице проекта не выложил никаких скриншотов, я сделаю это за него. (К сожалению, на этом движке картинки отображаются не очень красиво. Я не собираюсь с этим бороться, и оставляю это на совести Google.)

Рис 1. BigIron RX с 4 модулями по 4 порта. Развернуто выпадающее меню со списком узлов. Один узел раскрыт - можно видеть установленные там устройства и применить к ним одну из трех команд. Рамка вокруг портов 2/1, 3/3 и 3/4 говорит о включенном функционале flow control.

Рис 2. Автономный DGS-3100-24TG. Фон за номером порта указывает на тип порта: оранжевый - медный, голубой - оптический. Серый фон у всего порта говорит о том, что порт выключен административно.

Рис 3. DGS-3000-28SC, собранный в стек. Белый цвет у номера порта говорит о том, что фактическое состояние порта соответствует административному. Порт включен - линк поднят. Порт выключен - линка нет.

Кроме отображения портов PortViewer обладает еще несколькими полезными особенностями:
  • При наведении курсора на определенный порт можно посмотреть список vlan на этом порту.
  • Для Foundry кроме vlan будут отображены еще и ve и соответствующий IP-адрес.
  • Список vlan можно скачать в txt/csv форматах.
  • Каждая уникальная комбинация свойств портов (т.е. если что-то поменялось) записывается в базу данных. Эти уникальные "слепки" устройств потом можно просмотреть в любое время.
  • Благодаря кнопкам "telnet" из интерфейса удобно подключаться к устройству.
PortViewer - молодой проект. На данный момент в нем реализовано еще не все, что задумано. Тем не менее, уже сейчас это неплохой инструмент, помогающий в моей работе каждый день.

Использование swtoolz-core

Проект swtoolz-core продолжает развиваться и совершенствоваться. В новой версии появилась возможность более гибко использовать пользовательские параметры. В первую очередь, это сделано для облегчения работы с snmpset-операциями. Cписок изменений можно посмотреть на страничке проекта, а эту заметку посвятим практическому применению swtoolz-core.

Итак, как можно использовать swtoolz-core на практике? Рассмотрим здесь несколько примеров.

1. Изменить IP-адрес коммутатора D-Link. На практике это зачастую предполагает одновременное изменение еще и шлюза по умолчанию и управляющей vlan. Чтобы при этом не потерять управление устройством, нужно прибегать к некоторым хитростям. Например:
а) зайти на коммутатор с маршрутизатора, чтобы не потерять к нему доступ после изменения IP-адреса или шлюза по умолчанию
б) изменить IP-адрес через веб-интерфейс
в) использовать snmp-команды
г) использовать заранее подготовленные скрипты

Каждый из этих способов имеет свои недостатки. При подключении с маршрутизатора требуются лишние телодвижения, а внутренняя сессия "подвисает" когда у коммутатора меняется адрес. Веб-интерфейс зачастую отключен. SNMP-команды требуют умения ориентироваться в OID и MIB (swL2DevCtrlManagementVlanId относится к vendor-specific OID, т.е. отличается у каждой модели). Скрипты требуется готовить заранее и их может быть достаточно много (см. пример выше про уникальный OID для управляющей vlan).

Понятно, что один раз сменить адрес не является проблемой. Но если адреса надо поменять у нескольких десятков или даже сотен коммутаторов, то придется искать способ упростить эту операцию. На днях мне понадобилось изменить IP-адреса у 200 коммутаторов. Пришлось научить делать это swtoolz-core. В модуль для каждой модели был добавлен новый метод:
set_IpifCfg = [
#     .1.3.6.1.2.1.16.19.11.1.1                                         netConfigIPAddress
    ['.1.3.6.1.2.1.16.19.11.1.1', '5121', '{1}', 'IPADDR'],
#     .1.3.6.1.2.1.16.19.11.1.2                                         netConfigSubnetMask
    ['.1.3.6.1.2.1.16.19.11.1.2', '5121', '{2}', 'IPADDR'],
#     .1.3.6.1.2.1.16.19.12                                             netDefaultGateway
    ['.1.3.6.1.2.1.16.19.12', '0', '{3}', 'IPADDR'],
#     .1.3.6.1.4.1.171.11.113.5.1.2.1.2.16                              swL2DevCtrlManagementVlanId
    ['.1.3.6.1.4.1.171.11.113.5.1.2.1.2.16', '0', '{4}', 'INTEGER'],
    ]
После этого понадобилось лишь обратиться к API с нужными параметрами (выделены жирным) и дело сделано:

http://host.domain:7377/<user>/<device_ip>/<community_index>/set_IpifCfg/<IP>/<mask>/<gateway>/<mvlan>

2. Создать новую vlan. Выше уже было сказано, что новый IP-адрес зачастую предполагает новую vlan для управления. Создавать ее вручную не обязательно. Это можно сделать при помощи метода:
set_CreateVlan = [
#     .1.3.6.1.2.1.17.7.1.4.3.1.1                                       dot1qVlanStaticName
    ['.1.3.6.1.2.1.17.7.1.4.3.1.1', '{1}', '{2}', 'OCTETSTR'],
#     .1.3.6.1.2.1.17.7.1.4.3.1.2                                       dot1qVlanStaticEgressPorts
    ['.1.3.6.1.2.1.17.7.1.4.3.1.2', '{1}', '{3}', 'OCTETSTR'],
#     .1.3.6.1.2.1.17.7.1.4.3.1.5                                       dot1qVlanStaticRowStatus
    ['.1.3.6.1.2.1.17.7.1.4.3.1.5', '{1}', '4', 'INTEGER'],
    ]
Создание VLAN с ID 500, именем testvlan и member-портами 25-28:
/set_CreateVlan/500/testvlan/%f0

Поскольку в данном примере не используются vendor-specific OID, то данный метод будет работать для любого коммутатора D-Link.

3. Сохранить настройки коммутатора. Сохранение настроек - вещь важная и нужная. Да и делается легко:
set_SaveConfig = [
#     .1.3.6.1.4.1.171.12.1.2.18.4                                      agentBscFileSystemSaveCfg
    ['.1.3.6.1.4.1.171.12.1.2.18.4', '0', '2', 'INTEGER'],
    ]
Сама команда вызывается без параметров:
/set_SaveConfig
Примечание: в конфигурации swtoolz-core желательно убрать дополнительные попытки опроса (retries) для этого метода. Делается это просто:
no_retries = ['set_SaveConfig']
4. Изменить статус порта (включить/выключить). Для управления состоянием портов есть свой метод:
set_AdminStatus = [
#     .1.3.6.1.4.1.171.11.63.6.2.2.2.1.3                                swL2PortCtrlAdminState
    ['.1.3.6.1.4.1.171.11.63.6.2.2.2.1.3.%s', '100', '%s', 'INTEGER'],
    ]
Установить порт в состояние status:
/set_AdminStatus/<>/<status>
Сам список статусов можно получить так:
/AdminStatus

5. Изменить административную скорость порта. Для этого тоже есть свой метод:
set_AdminSpeed = [
#     .1.3.6.1.4.1.171.11.63.6.2.2.2.1.4                                swL2PortCtrlNwayState
    ['.1.3.6.1.4.1.171.11.63.6.2.2.2.1.4.%s', '100', '%s', 'INTEGER'],
    ]
Установить скорость speed для порта №:
/set_AdminSpeed/<>/<speed>
Список возможных вариантов доступен при вызове:
/AdminSpeed

Список можно продолжать, но основная идея заключается в том, что требуемый функционал всегда можно добавить самостоятельно. Главное - чтобы у данного устройства этот функционал был доступен для управления по SNMP.

Возвращаясь к теме изменения IP-адреса у 200 коммутаторов, можно подвести итог. Итак, сначала я сделал список соответствия старого и нового IP-адресов. После этого был написан простой скрипт, который вычислял адрес шлюза по умолчанию и подставлял этот и другие параметры в URL, примеры которых даны выше. Получившиеся ссылки сам же скрипт и вызывал. Первая ссылка содержала команду на создание управляющей vlan, вторая меняла DHCP Relay Remote ID, третья изменяла IP-адрес интерфейса, помещая последний в новую vlan, а четвертая сохраняла настройки. В итоге все коммутаторы (разных моделей и ревизий) были перенастроены довольно быстро, а главное - мне не пришлось заходить на каждый. :)

Здесь мы рассмотрели только snmpset-операции, как дающие заметный и понятный эффект. Выключили порт - он погас. Изменили IP-адрес коммутатора - и потеряли управление им он стал доступен по новому и т.д. Но если мы работаем с get/walk-операциями, то мы получаем, прежде всего, данные. И с этими данными надо что-то сделать. Об этом в следующей статье.