mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
OSPF SNMP Trap Handlers (#11647)
* Intitial push working tests * Adding unit tests * created interface state unit tests * started ospf nbr unit tests * finished nbr change unit tests * precommit checks pass * removed uneccsarry relationship
This commit is contained in:
88
LibreNMS/Snmptrap/Handlers/OspfIfStateChange.php
Normal file
88
LibreNMS/Snmptrap/Handlers/OspfIfStateChange.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* OspfIfStateChange.php
|
||||
*
|
||||
* -Description-
|
||||
* Handles the ospfIfStateChange SNMP trap signaling an interface
|
||||
* in the OSPF topology has changed its state. The handler logs the
|
||||
* change and updates the interface's state in ospf_ports table.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 KanREN Inc
|
||||
* @author Heath Barnhart <hbarnhart@kanren.net>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Snmptrap\Handlers;
|
||||
|
||||
use App\Models\Device;
|
||||
use LibreNMS\Interfaces\SnmptrapHandler;
|
||||
use LibreNMS\Snmptrap\Trap;
|
||||
use Log;
|
||||
|
||||
class OspfIfStateChange implements SnmptrapHandler
|
||||
{
|
||||
/**
|
||||
* Handle snmptrap.
|
||||
* Data is pre-parsed and delivered as a Trap.
|
||||
*
|
||||
* @param Device $device
|
||||
* @param Trap $trap
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Device $device, Trap $trap)
|
||||
{
|
||||
$ospfIfIpAddress = $trap->getOidData($trap->findOid('OSPF-MIB::ospfIfIpAddress'));
|
||||
$ospfPort = $device->ospfPorts()->where('ospfIfIpAddress', $ospfIfIpAddress)->first();
|
||||
|
||||
$port = $device->ports()->where('port_id', $ospfPort->port_id)->first();
|
||||
|
||||
if (!$port) {
|
||||
Log::warning("Snmptrap ospfIfStateChange: Could not find port at port_id $ospfPort->port_id for device: " . $device->hostname);
|
||||
return;
|
||||
}
|
||||
|
||||
$ospfPort->ospfIfState = $trap->getOidData($trap->findOid('OSPF-MIB::ospfIfState'));
|
||||
|
||||
switch ($ospfPort->ospfIfState) {
|
||||
case 'down':
|
||||
$severity = 5;
|
||||
break;
|
||||
case 'designatedRouter':
|
||||
$severity = 1;
|
||||
break;
|
||||
case 'backupDesignatedRouter':
|
||||
$severity = 1;
|
||||
break;
|
||||
case 'otherDesignatedRouter':
|
||||
$severity = 1;
|
||||
break;
|
||||
case 'pointToPoint':
|
||||
$severity = 1;
|
||||
break;
|
||||
case 'waiting':
|
||||
$severity = 4;
|
||||
break;
|
||||
case 'loopback':
|
||||
$severity = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
Log::event("OSPF interface $port->ifName is $ospfPort->ospfIfState", $device->device_id, 'trap', $severity);
|
||||
|
||||
$ospfPort->save();
|
||||
}
|
||||
}
|
65
LibreNMS/Snmptrap/Handlers/OspfNbrStateChange.php
Normal file
65
LibreNMS/Snmptrap/Handlers/OspfNbrStateChange.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* OspfNbrStateChange.php
|
||||
*
|
||||
* -Description-
|
||||
* Handles ospfNbrStateChange SNMP traps. Trap is sent when an OSPF
|
||||
* neighbor changes state. Handler logs the change and updates the
|
||||
* neighbor's information in the ospf_nbrs table.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 KanREN Inc
|
||||
* @author Heath Barnhart <hbarnhart@kanren.net>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Snmptrap\Handlers;
|
||||
|
||||
use App\Models\Device;
|
||||
use LibreNMS\Interfaces\SnmptrapHandler;
|
||||
use LibreNMS\Snmptrap\Trap;
|
||||
use Log;
|
||||
|
||||
class OspfNbrStateChange implements SnmptrapHandler
|
||||
{
|
||||
/**
|
||||
* Handle snmptrap.
|
||||
* Data is pre-parsed and delivered as a Trap.
|
||||
*
|
||||
* @param Device $device
|
||||
* @param Trap $trap
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Device $device, Trap $trap)
|
||||
{
|
||||
$ospfNbrIpAddr = $trap->getOidData($trap->findOid('OSPF-MIB::ospfNbrRtrId'));
|
||||
$ospfNbr = $device->ospfNbrs()->where('ospfNbrRtrId', $ospfNbrIpAddr)->first();
|
||||
|
||||
$ospfNbr->ospfNbrState = $trap->getOidData($trap->findOid('OSPF-MIB::ospfNbrState'));
|
||||
|
||||
$severity = 4;
|
||||
|
||||
if ($ospfNbr->ospfNbrState == 'full') {
|
||||
$severity = 1;
|
||||
} elseif ($ospfNbr->ospfNbrState == 'down') {
|
||||
$severity = 5;
|
||||
}
|
||||
|
||||
Log::event("OSPF neighbor $ospfNbrIpAddr changed state to $ospfNbr->ospfNbrState", $device->device_id, 'trap', $severity);
|
||||
|
||||
$ospfNbr->save();
|
||||
}
|
||||
}
|
@@ -45,7 +45,7 @@ class Device extends BaseModel
|
||||
*/
|
||||
public static function pollerTarget($device)
|
||||
{
|
||||
if (! is_array($device)) {
|
||||
if (!is_array($device)) {
|
||||
$ret = static::where('hostname', $device)->first(['hostname', 'overwrite_ip']);
|
||||
if (empty($ret)) {
|
||||
return $device;
|
||||
@@ -222,7 +222,7 @@ class Device extends BaseModel
|
||||
];
|
||||
|
||||
foreach ($options as $file) {
|
||||
if (is_file(public_path()."/$file")) {
|
||||
if (is_file(public_path() . "/$file")) {
|
||||
return asset($file);
|
||||
}
|
||||
}
|
||||
@@ -281,9 +281,9 @@ class Device extends BaseModel
|
||||
public function validateStandalone()
|
||||
{
|
||||
if ($this->max_depth === 0 && $this->children()->count() > 0) {
|
||||
$this->max_depth = 1; // has children
|
||||
$this->max_depth = 1; // has children
|
||||
} elseif ($this->max_depth === 1 && $this->parents()->count() === 0) {
|
||||
$this->max_depth = 0; // no children or parents
|
||||
$this->max_depth = 0; // no children or parents
|
||||
}
|
||||
|
||||
$this->save();
|
||||
@@ -306,7 +306,7 @@ class Device extends BaseModel
|
||||
}
|
||||
|
||||
$attrib->attrib_value = $value;
|
||||
return (bool)$this->attribs()->save($attrib);
|
||||
return (bool) $this->attribs()->save($attrib);
|
||||
}
|
||||
|
||||
public function forgetAttrib($name)
|
||||
@@ -316,7 +316,7 @@ class Device extends BaseModel
|
||||
});
|
||||
|
||||
if ($attrib_index !== false) {
|
||||
$deleted=(bool)$this->attribs->get($attrib_index)->delete();
|
||||
$deleted = (bool) $this->attribs->get($attrib_index)->delete();
|
||||
// only forget the attrib_index after delete, otherwise delete() will fail fatally with:
|
||||
// Symfony\\Component\\Debug\Exception\\FatalThrowableError(code: 0): Call to a member function delete() on null
|
||||
$this->attribs->forget($attrib_index);
|
||||
@@ -365,7 +365,7 @@ class Device extends BaseModel
|
||||
|
||||
public function setStatusAttribute($status)
|
||||
{
|
||||
$this->attributes['status'] = (int)$status;
|
||||
$this->attributes['status'] = (int) $status;
|
||||
}
|
||||
|
||||
// ---- Query scopes ----
|
||||
@@ -376,7 +376,7 @@ class Device extends BaseModel
|
||||
['status', '=', 1],
|
||||
['ignore', '=', 0],
|
||||
['disable_notify', '=', 0],
|
||||
['disabled', '=', 0]
|
||||
['disabled', '=', 0],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ class Device extends BaseModel
|
||||
{
|
||||
return $query->where([
|
||||
['ignore', '=', 0],
|
||||
['disabled', '=', 0]
|
||||
['disabled', '=', 0],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ class Device extends BaseModel
|
||||
['status', '=', 0],
|
||||
['disable_notify', '=', 0],
|
||||
['ignore', '=', 0],
|
||||
['disabled', '=', 0]
|
||||
['disabled', '=', 0],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -402,28 +402,28 @@ class Device extends BaseModel
|
||||
{
|
||||
return $query->where([
|
||||
['ignore', '=', 1],
|
||||
['disabled', '=', 0]
|
||||
['disabled', '=', 0],
|
||||
]);
|
||||
}
|
||||
|
||||
public function scopeNotIgnored($query)
|
||||
{
|
||||
return $query->where([
|
||||
['ignore', '=', 0]
|
||||
['ignore', '=', 0],
|
||||
]);
|
||||
}
|
||||
|
||||
public function scopeIsDisabled($query)
|
||||
{
|
||||
return $query->where([
|
||||
['disabled', '=', 1]
|
||||
['disabled', '=', 1],
|
||||
]);
|
||||
}
|
||||
|
||||
public function scopeIsDisableNotify($query)
|
||||
{
|
||||
return $query->where([
|
||||
['disable_notify', '=', 1]
|
||||
['disable_notify', '=', 1],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ class Device extends BaseModel
|
||||
{
|
||||
return $query->where([
|
||||
['disable_notify', '=', 0],
|
||||
['disabled', '=', 0]
|
||||
['disabled', '=', 0],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -439,7 +439,7 @@ class Device extends BaseModel
|
||||
{
|
||||
return $query->where([
|
||||
['uptime', '>', 0],
|
||||
['uptime', $modifier, $uptime]
|
||||
['uptime', $modifier, $uptime],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -571,6 +571,15 @@ class Device extends BaseModel
|
||||
{
|
||||
return $this->hasMany(\App\Models\OspfInstance::class, 'device_id');
|
||||
}
|
||||
public function ospfNbrs()
|
||||
{
|
||||
return $this->hasMany(\App\Models\OspfNbr::class, 'device_id');
|
||||
}
|
||||
|
||||
public function ospfPorts()
|
||||
{
|
||||
return $this->hasMany(\App\Models\OspfPort::class, 'device_id');
|
||||
}
|
||||
|
||||
public function netscalerVservers()
|
||||
{
|
||||
|
@@ -99,5 +99,7 @@ return [
|
||||
'VMWARE-VMINFO-MIB::vmwVmPoweredOn' => \LibreNMS\Snmptrap\Handlers\VmwVmPoweredOn::class,
|
||||
'VMWARE-VMINFO-MIB::vmwVmPoweredOff' => \LibreNMS\Snmptrap\Handlers\VmwVmPoweredOff::class,
|
||||
'VMWARE-VMINFO-MIB::vmwVmSuspended' => \LibreNMS\Snmptrap\Handlers\VmwVmSuspended::class,
|
||||
'OSPF-TRAP-MIB::ospfIfStateChange' => \LibreNMS\Snmptrap\Handlers\OspfIfStateChange::class,
|
||||
'OSPF-TRAP-MIB::ospfNbrStateChange' => \LibreNMS\Snmptrap\Handlers\OspfNbrStateChange::class,
|
||||
]
|
||||
];
|
||||
|
@@ -132,6 +132,32 @@ $factory->define(\App\Models\Vminfo::class, function (Faker\Generator $faker) {
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\App\Models\OspfNbr::class, function (Faker\Generator $faker) {
|
||||
return [
|
||||
'id' => $faker->randomDigit,
|
||||
'ospfNbrIpAddr' => $faker->ipv4,
|
||||
'ospfNbrAddressLessIndex' => $faker->randomDigit,
|
||||
'ospfNbrRtrId' => $faker->ipv4,
|
||||
'ospfNbrOptions' => 0,
|
||||
'ospfNbrPriority' => 1,
|
||||
'ospfNbrEvents' => $faker->randomDigit,
|
||||
'ospfNbrLsRetransQLen' => 0,
|
||||
'ospfNbmaNbrStatus' => 'active',
|
||||
'ospfNbmaNbrPermanence' => 'dynamic',
|
||||
'ospfNbrHelloSuppressed' => 'false',
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\App\Models\OspfPort::class, function (Faker\Generator $faker) {
|
||||
return [
|
||||
'id' => $faker->randomDigit,
|
||||
'ospf_port_id' => $faker->randomDigit,
|
||||
'ospfIfIpAddress' => $faker->ipv4,
|
||||
'ospfAddressLessIf' => $faker->randomDigit,
|
||||
'ospfIfAreaId' => '0.0.0.0',
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\App\Models\Component::class, function (Faker\Generator $faker) {
|
||||
return [
|
||||
'device_id' => $faker->randomDigit,
|
||||
|
271
tests/Feature/SnmpTraps/OspfIfStateChangeTest.php
Normal file
271
tests/Feature/SnmpTraps/OspfIfStateChangeTest.php
Normal file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
/**
|
||||
* OspfIfStateChangeTest.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* Unit test for the OspfIfStateChange SNMP trap handler. Will verify
|
||||
* trap is properly logged and ospf_ports.ospfIfState is updated in the
|
||||
* database.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 KanREN, Inc
|
||||
* @author Heath Barnhart <hbarnhart@kanren.net>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Tests\Feature\SnmpTraps;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Models\OspfPort;
|
||||
use App\Models\Port;
|
||||
use LibreNMS\Snmptrap\Dispatcher;
|
||||
use LibreNMS\Snmptrap\Trap;
|
||||
use Log;
|
||||
|
||||
class OspfIfStateChangeTest extends SnmpTrapTestCase
|
||||
{
|
||||
//Test OSPF interface state down
|
||||
public function testOspfIfDown()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'designatedRouter']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 down
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is down";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 5);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange down');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'down');
|
||||
}
|
||||
|
||||
//Test OSPF interface state DesignatedRouter
|
||||
public function testOspfIfDr()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'down']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 designatedRouter
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is designatedRouter";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 1);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange designatedRouter');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'designatedRouter');
|
||||
}
|
||||
|
||||
//Test OSPF interface state backupDesignatedRouter
|
||||
public function testOspfIfBdr()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'down']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 backupDesignatedRouter
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is backupDesignatedRouter";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 1);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange backupDesignatedRouter');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'backupDesignatedRouter');
|
||||
}
|
||||
|
||||
//Test OSPF interface state otherDesignatedRouter
|
||||
public function testOspfIfOdr()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'down']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 otherDesignatedRouter
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is otherDesignatedRouter";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 1);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange otherDesignatedRouter');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'otherDesignatedRouter');
|
||||
}
|
||||
|
||||
//Test OSPF interface state pointToPoint
|
||||
public function testOspfIfPtp()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'down']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 pointToPoint
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is pointToPoint";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 1);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange pointToPoint');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'pointToPoint');
|
||||
}
|
||||
|
||||
//Test OSPF interface state waiting
|
||||
public function testOspfIfWait()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'designatedRouter']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 waiting
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is waiting";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 4);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange waiting');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'waiting');
|
||||
}
|
||||
|
||||
//Test OSPF interface state loopback
|
||||
public function testOspfIfLoop()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
$port = factory(Port::class)->make(['ifAdminStatus' => 'up', 'ifOperStatus' => 'up']);
|
||||
|
||||
$device->ports()->save($port);
|
||||
|
||||
$ospfIf = factory(OspfPort::class)->make(['port_id' => $port->port_id, 'ospfIfState' => 'designatedRouter']);
|
||||
$device->ospfPorts()->save($ospfIf);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:6:11:31.55
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfIfStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfIfIpAddress.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfIfIpAddress
|
||||
OSPF-MIB::ospfAddressLessIf.$ospfIf->ospfIfIpAddress.0 $ospfIf->ospfAddressLessIf
|
||||
OSPF-MIB::ospfIfState.$ospfIf->ospfIfIpAddress.0 loopback
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF interface $port->ifName is loopback";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 4);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfIfStateChange loopback');
|
||||
|
||||
$ospfIf = $ospfIf->fresh();
|
||||
$this->assertEquals($ospfIf->ospfIfState, 'loopback');
|
||||
}
|
||||
}
|
135
tests/Feature/SnmpTraps/OspfNbrStateChangeTest.php
Normal file
135
tests/Feature/SnmpTraps/OspfNbrStateChangeTest.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* OspfNbrStateChangeTest.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* Unit test for the OspfNbStateChange SNMP trap handler. Will verify
|
||||
* trap is properly logged and ospf_nbrs.ospfNbrState is updated in the
|
||||
* database.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 KanREN, Inc
|
||||
* @author Heath Barnhart <hbarnhart@kanren.net>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Tests\Feature\SnmpTraps;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Models\OspfNbr;
|
||||
use LibreNMS\Snmptrap\Dispatcher;
|
||||
use LibreNMS\Snmptrap\Trap;
|
||||
use Log;
|
||||
|
||||
class OspfNbrStateChangeTest extends SnmpTrapTestCase
|
||||
{
|
||||
//Test OSPF neighbor state down trap
|
||||
public function testOspfNbrDown()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
|
||||
$ospfNbr = factory(OspfNbr::class)->make(['device_id' => $device->device_id, 'ospfNbrState' => 'full']);
|
||||
$ospfNbr->ospf_nbr_id = "$ospfNbr->ospfNbrIpAddr.$ospfNbr->ospfNbrAddressLessIndex";
|
||||
$device->ospfNbrs()->save($ospfNbr);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:1:07:16.06
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfNbrStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfNbrIpAddr.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrIpAddr
|
||||
OSPF-MIB::ospfNbrAddressLessIndex.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrAddressLessIndex
|
||||
OSPF-MIB::ospfNbrRtrId.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrRtrId
|
||||
OSPF-MIB::ospfNbrState.$ospfNbr->ospf_nbr_id down
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240 ";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF neighbor $ospfNbr->ospfNbrRtrId changed state to down";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 5);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfNbrStateChange down');
|
||||
|
||||
$ospfNbr = $ospfNbr->fresh();
|
||||
$this->assertEquals($ospfNbr->ospfNbrState, 'down');
|
||||
}
|
||||
|
||||
//Test OSPF neighbor state full trap
|
||||
public function testOspfNbrFull()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
|
||||
$ospfNbr = factory(OspfNbr::class)->make(['device_id' => $device->device_id, 'ospfNbrState' => 'down']);
|
||||
$ospfNbr->ospf_nbr_id = "$ospfNbr->ospfNbrIpAddr.$ospfNbr->ospfNbrAddressLessIndex";
|
||||
$device->ospfNbrs()->save($ospfNbr);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:1:07:16.06
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfNbrStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfNbrIpAddr.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrIpAddr
|
||||
OSPF-MIB::ospfNbrAddressLessIndex.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrAddressLessIndex
|
||||
OSPF-MIB::ospfNbrRtrId.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrRtrId
|
||||
OSPF-MIB::ospfNbrState.$ospfNbr->ospf_nbr_id full
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240 ";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF neighbor $ospfNbr->ospfNbrRtrId changed state to full";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 1);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfNbrStateChange full');
|
||||
|
||||
$ospfNbr = $ospfNbr->fresh();
|
||||
$this->assertEquals($ospfNbr->ospfNbrState, 'full');
|
||||
}
|
||||
|
||||
//Test OSPF neighbor state trap any other state
|
||||
public function testOspfNbrOther()
|
||||
{
|
||||
$device = factory(Device::class)->create();
|
||||
|
||||
$ospfNbr = factory(OspfNbr::class)->make(['device_id' => $device->device_id, 'ospfNbrState' => 'full']);
|
||||
$ospfNbr->ospf_nbr_id = "$ospfNbr->ospfNbrIpAddr.$ospfNbr->ospfNbrAddressLessIndex";
|
||||
$device->ospfNbrs()->save($ospfNbr);
|
||||
|
||||
$trapText = "$device->hostname
|
||||
UDP: [$device->ip]:57602->[192.168.5.5]:162
|
||||
DISMAN-EVENT-MIB::sysUpTimeInstance 0:1:07:16.06
|
||||
SNMPv2-MIB::snmpTrapOID.0 OSPF-TRAP-MIB::ospfNbrStateChange
|
||||
OSPF-MIB::ospfRouterId.0 $device->ip
|
||||
OSPF-MIB::ospfNbrIpAddr.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrIpAddr
|
||||
OSPF-MIB::ospfNbrAddressLessIndex.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrAddressLessIndex
|
||||
OSPF-MIB::ospfNbrRtrId.$ospfNbr->ospf_nbr_id $ospfNbr->ospfNbrRtrId
|
||||
OSPF-MIB::ospfNbrState.$ospfNbr->ospf_nbr_id exstart
|
||||
SNMPv2-MIB::snmpTrapEnterprise.0 JUNIPER-CHASSIS-DEFINES-MIB::jnxProductNameSRX240 ";
|
||||
|
||||
$trap = new Trap($trapText);
|
||||
|
||||
$message = "OSPF neighbor $ospfNbr->ospfNbrRtrId changed state to exstart";
|
||||
|
||||
\Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 4);
|
||||
|
||||
$this->assertTrue(Dispatcher::handle($trap), 'Could not handle ospfNbrStateChange exstart');
|
||||
|
||||
$ospfNbr = $ospfNbr->fresh();
|
||||
$this->assertEquals($ospfNbr->ospfNbrState, 'exstart');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user