Как стать автором
Обновить

SNMP MIB браузер на Perl и JavaScript

Время на прочтение3 мин
Количество просмотров5.3K

Что делать на работе, если не знаешь, чем бы еще заняться? Конечно же писать на Хабр!

Благодаря нашим доблестным законодателям, дальнейшее развитие бизнеса самостоятельно нерентабельно и мы уходим под более крупного оператора. Вот у меня и сложилась такая ситуация, что смысла дорабатывать, переписывать и исправлять свои старые проекты - нет, у "крупняка" все сервисы свои. Сижу, курю. А потом думаю, а чего сидеть-то, напишу-ка я на Хабр. Статья прошла модерацию, «И тут Остапа понесло...».

Итак, о чем будет эта статья. Все кто занимаются сетями, рано или поздно сталкиваются с 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, не составит труда выдернуть нужные куски.

продолжение будет

Теги:
Хабы:
Всего голосов 9: ↑9 и ↓0+9
Комментарии2

Публикации