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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

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

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


Интересные статьи

Интересные статьи

В начале апреля на хабре была опубликована статья «JavaScript: Стек вызовов и магия его размера» — её автор пришёл к выводу, что каждый кадр стека занимает (72 + 8 * число_локальных_п...
Ранее в одном из наших КП добавление задач обрабатывалось бизнес-процессами, сейчас задач стало столько, что бизнес-процессы стали неуместны, и понадобился инструмент для массовой заливки задач на КП.
Ваш сайт работает на 1С-Битрикс? Каждому клиенту вы даёте собственную скидку или назначаете персональную цену на товар? Со временем в вашей 1С сложилась непростая логика ценообразования и формирования...
Получить трафик для интернет-магазина сегодня не проблема. Есть много каналов его привлечения: органическая выдача, контекстная реклама, контент-маркетинг, RTB-сети и т. д. Вопрос в том, как вы распор...
Привет, читатель. Иногда для решении задачи приходится использовать Рекурсию, в которой есть свои плюсы и минусы. Я столкнулся с проблемой переполнения стека. Максимальная глубина рекурсии ог...