Что делать на работе, если не знаешь, чем бы еще заняться? Конечно же писать на Хабр!
Благодаря нашим доблестным законодателям, дальнейшее развитие бизнеса самостоятельно нерентабельно и мы уходим под более крупного оператора. Вот у меня и сложилась такая ситуация, что смысла дорабатывать, переписывать и исправлять свои старые проекты — нет, у «крупняка» все сервисы свои. Сижу, курю. А потом думаю, а чего сидеть-то, напишу-ка я на Хабр. Статья прошла модерацию, «И тут Остапа понесло…».
Итак, о чем будет эта статья. Все кто занимаются сетями, рано или поздно сталкиваются с MIB. Для тех, кому лень переходить по ссылке, это такая база данных, содержащая информацию об объекте, в нашем случае — сетевом устройстве. На хабре было несколько статей, посвященным работе с MIB и возникающим при этом вопросах. Мне понравилась статья SNMP MIBs и как их готовить, где автор для работы с MIB использовал инструмент от D-Link — утилиту D-View. Сразу скажу, зная качество MIB от этого вендора — использовать в реальных проектах D-View не рекомендую. Однако она дает представление, о типичном интерфейсе подобного программного обеспечения. Как ни странно, программ для работы непосредственно с MIB, сходных по функционалу хотя бы с D-View — не так много. Я бы даже сказал — очень мало. Описывать все их плюсы и минусы я не собираюсь. Здесь я хочу показать мою реализацию, наверняка не самую лучшую, но писалось «для себя» и функционал допиливался по мере необходимости.
Итак, вся серверная часть будет на Perl и библиотеке SNMP.pm. Пожалуй разобью статью на две части, — во второй будет описание клиентской части. Начнем пожалуй с загрузки нужных нам MIB:
sub load_mibs { my ($attr, $Nms) = @_; #Если MIB Вашего оборудования располагаются в каталоге, отличном от #стандартного(с моей точки зрения - это правильный подход), указываем здесь my $MIB_search_path = '../modules/Nms/mibs'; #Добавляем свой путь во внутренний лист библиотеки SNMP::addMibDirs($MIB_search_path); SNMP::addMibDirs($MIB_search_path . '/private'); #Здесь уже можно загрузить все модули, но при работе с реальным уст-ом #я загружаю только нужные мне. if ( $attr->{ALL} ) { SNMP::addMibFiles( glob( $MIB_search_path . '/private' . '/*' ) ); SNMP::initMib(); } #Пусть это будет DES3200-28 elsif ( $attr->{SYS_ID} ) { my @mods = ('EQUIPMENT-MIB', 'DES3200-28-L3MGMT-MIB', 'CABLE-DIAG-MIB'); #Здесь, в отличии от первого варианта, загрузятся только нужные MIB SNMP::loadModules(@mods); SNMP::initMib(); } return 1; }
Сразу несколько пояснений: — первое, загрузка только нужных модулей, значительно ускоряет дальнейшую работу с деревом OID; — второе, не обязательно указывать все необходимые модули, в правильно «приготовленном» MIB используются ссылки на нужные модули, и они подгрузятся автоматически, например так:
IMPORTS MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, OBJECT-IDENTITY, Counter32, Gauge32, Integer32, mib-2 FROM SNMPv2-SMI DisplayString, TimeStamp, TimeInterval, TestAndIncr, AutonomousType, TEXTUAL-CONVENTION FROM SNMPv2-TC MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF;
то есть указывается, что и откуда импортировать.
Поехали дальше, дерево с OID у нас уже есть и находится в хеше %SNMP::MIB. В принципе, можно его уже в таком виде отдать клиенту, и распарсить какой-нибудь JS библиотекой. Но мы добрые, — не дадим зависнуть клиентской машинке и приготовим данные сервером. Для отрисовки дерева я буду использовать библиотеку jsTree, следующий код подготавливает данные:
sub mibs_tree { my ($attr) = @_; my %labels; my @tree_arr; foreach my $oid ( sort keys(%SNMP::MIB) ) { #Определяем ветку дерева, либо корень. my $prev_id = ( $SNMP::MIB{$oid}{parent} ) ? $SNMP::MIB{$oid}{parent}{objectID} : '#'; #Ну и дальше мы определяем типы OID и навешиваем атрибуты для jsTree my $icon = ''; my %type; if ( $SNMP::MIB{$oid}{children}[0]{indexes}[0] ) { $type{type} = 'table'; } elsif ($SNMP::MIB{$oid}{parent} && $SNMP::MIB{$oid}{parent}{indexes}[0]){ $type{type} = 'row'; } elsif ( $SNMP::MIB{$oid}{type} ) { $type{type} = 'scalar'; } elsif ( $SNMP::MIB{$oid}{indexes}[0] ) { $type{type} = 'indexes'; } else { $type{type} = 'folder'; } push @tree_arr, ( { id => $SNMP::MIB{$oid}{objectID}, text => $SNMP::MIB{$oid}{label}, parent => $prev_id, %type } ); } } my %types = ( table => { icon => 'fa fa-table' }, row => { icon => 'fa fa-columns' }, scalar => { icon => 'fa fa-paragraph' }, indexes => { icon => 'fa fa-list-ul' }, folder => { icon => 'fa fa-folder-o' }, ); return make_tree( { plugins => [ 'types', 'search', 'contextmenu' ], contextmenu => { items => '*customMenu*' }, types => \%types, core => { data => \@tree_arr } } ); }
На этом пожалуй пока остановлюсь, так как дальше будет уже много JS и HTML. Для затравки покажу, что должно получится в результате:

Пишу, пока есть настроение и не факт, что продолжение будет. Поэтому дам ссылку на мою старенькую репку на github. Код рабочий, правда без комментариев, думаю имеющим опыт работы с Perl, не составит труда выдернуть нужные куски.
ссылка на оригинал статьи https://habr.com/ru/post/560192/
Добавить комментарий