Интеграция с OpenNMS

Материал из DvoWiki
Перейти к: навигация, поиск

Приамбула

Данный материал содержит сведения по внедрению в OpenNMS дополнительного сервиса, целью которого является расширение существующей функциональности OpenNMS. Принцип работы сервиса заключается в прослушивании сети на предмет поступления сообщений от внешних агентов по протоколу TCP/IP в форме текстоых сообщений. При получении команд, которые соответстуют некоторым событиям, от внешних агентов, сервис должен добавлять event-ы в OpenNMS. Целью создания этого сервиса служит необходимость в отслеживании событий которые ,во превых, специфичны для пользователя, а ,во вторых, могут быть посланы устройствами, которые не поддержыивают станартный механизм SNMP.

Создание собственных событий (event)

Для сождания описания собственного события необходимо создать его описание в отдельном файле. Предположим, что opennms устанвлен в директорию /opt/opennms/.

$cd /opt/openms/

Создадим файл с событием Выключение света

$vim ./etc/events/POWER.events.xml

Запишем туда следующую информацию

<events>
<event>
  <uei>uei.opennms.org/vendors/AXIS/Trigger/Poweroff</uei>
  <event-label>Axis trigger event: Power Off</event-label>
  <descr>Axis tigger set to Powerr Off 
                        Node ID: %nodeid%
                        Host: %nodelabel%
                        Interface: %interface% 
  </descr>
  <logmsg dest='logndisplay'>Axis tigger set to Power Off.</logmsg>
  <severity>Indeterminate</severity>
 </event>
</events>
<event>
  <uei>uei.opennms.org/vendors/AXIS/Trigger/PowerOn</uei>
  <event-label>Axis trigger event: Power On</event-label>
  <descr>Axis tigger set to Powerr On
                         Node ID: %nodeid%
                         Host: %nodelabel%
                         Interface: %interface%
   </descr>
  <logmsg dest='logndisplay'>Axis tigger set to Power On.</logmsg>
  <severity>Indeterminate</severity>
</event>


Далее необходимо прописать информацию об этом файле в ./etc/eventconf.xml

<event-file>events/POWER.events.xml</event-file>

Для того тчобы зарегистрировать новое событие в системе можно перезапустить opennms.

$./bin/opennms restart

Сервер приёма сообщений

Этот сервис представляет из себя простой однопоточный сервер написаный на perl.

#!/usr/bin/perl 
use IO::Socket;
use Net::hostent;		# for OO version of gethostbyaddr
use DBI;
$PORT = 9000;			# pick something not in use
$server = IO::Socket::INET->new( Proto     => 'tcp',
                                 LocalPort => $PORT,
                                 Listen    => SOMAXCONN,
                                 Reuse     => 1);
die "can't setup server" unless $server;
print "[Server $0 accepting clients]\n";
while ($client = $server->accept()) {
  $client->autoflush(1);
  print $client "Welcome to $0; type help for command list.\n";
  $hostinfo = gethostbyaddr($client->peeraddr);
  $other_end = getpeername($client) or die "Coud't identify other end: $!\n";
  ($port, $iaddr) = unpack_sockaddr_in($other_end);
  $peer_addr = inet_ntoa($iaddr);
  $node_id = get_node_id($peer_addr);
  #my $peer_addr = $host->peeraddr;
  printf "Connect from  $peer_addr \n";
  printf "[Connect from %s]\n", $hostinfo->name || $client->peerhost;
  printf "Node id $node_id\n";
  while ( <$client>) {
    next unless /\S/;	     # blank line
    if    (/quit|exit/i)    { last;                                     }
    elsif (/power_off/i)    { printf "Receive poweroff message\n"; putNmsEvent_PowerOff($peer_addr, $node_id); }
    elsif (/power_on/i )    { print  "Receive power on message\n"; putNmsEvent_PowerOn($peer_addr, $node_id);               }
    #elsif (/cookie/i )      { print  $client `/usr/games/fortune 2>&1`; }
    #elsif (/motd/i )        { print  $client `cat /etc/motd 2>&1`;      }
    else {
      print $client "Annown protocol command\n";
    }
  } continue {
     print $client "Command? ";
  }
  close $client;
}  
close($server);
sub get_node_id(){
   my ($node_ip) = @_;
   # имя базы данных
   $dbname = "opennms";
   # имя пользователя
   $username = "admin";    
   $dbh = DBI->connect("dbi:Pg:dbname=$dbname","$username","",	{PrintError => 0});
   if ($DBI::err != 0) {
       print "Problems during connecting to Postgres\n";
       print $DBI::errstr . "\n";
       exit($DBI::err);
   }
   $query = "select nodeid from ipinterface where ipaddr='$node_ip'";    
   $sth = $dbh->prepare($query);
   $rv = $sth->execute();
   if (!defined $rv) {
       print "При выполнении запроса '$query' возникла ошибка: " . $dbh->errstr . "\n"; 
       exit(0);
   }
   local $node_id;
   while (@array = $sth->fetchrow_array()) {
       if (defined $array[0]){
           $node_id = $array[0];
       }	
   }    
   $sth->finish();    
   $dbh->disconnect();
   return $node_id;
}
#Послать сообщение о выключении света
sub putNmsEvent_PowerOff(){
   local ($node_ip, $node_id) = @_;
   $cmd = "/opt/opennms/bin/send-event.pl --interface $node_ip uei.opennms.org/vendor/AXISN/PowerOffTrap  -n=$node_id ";
   print "$cmd\n";
    $result = `$cmd`;
   print "$result\n";
}
#Послать сообщение о включении света
sub putNmsEvent_PowerOn(){
   local ($node_ip, $node_id) = @_;
   $cmd = "/opt/opennms/bin/send-event.pl --interface $node_ip uei.opennms.org/vendor/AXISN/PowerOnTrap  -n=$node_id ";
   print "$cmd\n";
   $result = `$cmd`;
   print "$result\n";
}

Для этого сервера можно написать простой run скрипт. Предполагается что будет запускаться файл event_listener.pl, находящийся в директории /opt/opennms/bin/.

#!/bin/bash

PID_FILE="/var/run/opennms_eventd.pid"

function if_daemon_worck(){
   if [ -f "$PID_FILE" ]; then
       echo "Daemon is alredy running plese stop it, or if it is not"
       echo "run delte pid file $PID_FILE"
       exit 1
   fi
   return 0
}

case "$1" in
 start)
   if_daemon_worck
   echo -n "Starting KVM: "
   perl /opt/opennms/bin/event_listener.pl > /dev/null 2>&1 &
   echo $! > $PID_FILE
   echo "Daemon opennms event listener started. PID:$!"
   echo ""
   ;;
 stop)
   echo -n "Shutting down Event listener: "
   echo ""
   STORED_PID=`cat $PID_FILE`
   kill -9 $STORED_PID
   echo "stop process $STORED_PID"
   echo ""
   rm -f $PID_FILE
   echo -n "Daemon OpenNMS event listener id down."
   echo ""
   ;;
 restart)
   $0 stop
   $0 start
   ;;
 *)
   echo "Usage: start_stop.sh {start|stop|restart|status}"
   exit 1
    
esac
exit 0