mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
ISIS-adjacency polling support (#12461)
* init
* Add adjacency polling support
* Format messages
* Fix prints
* Apply fixes from StyleCI
* Fix schema
* Schema fix
* Alert rule example
* Remove display format
* Change option order
* Add test data
* Add test data
* Test data
* Review fixes
* Remove duplicate MIB-file
* Add cleanup
* Fix
* Print fix
* Remove extra cleanup
* Revert "Remove duplicate MIB-file"
This reverts commit 4b3cf8127c
.
* Remove unneeded MIB-files
* Add check for empty array
* Apply fixes from StyleCI
* Review fixes
* StyleCI
* StyleCI
* Apply fixes from StyleCI
* typo
* Update function calls on pages
* Linting fixes
* Apply fixes from StyleCI
* Discovery module
* Add discovery module
* Apply fixes from StyleCI
* Update example alert rule
Co-authored-by: ottorei <ottorei@users.noreply.github.com>
Co-authored-by: PipoCanaja <38363551+PipoCanaja@users.noreply.github.com>
This commit is contained in:
216
LibreNMS/Modules/Isis.php
Normal file
216
LibreNMS/Modules/Isis.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* Isis.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @link http://librenms.org
|
||||
* @copyright 2021 Otto Reinikainen
|
||||
* @author Otto Reinikainen <otto@ottorei.fi>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Modules;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Models\IsisAdjacency;
|
||||
use Illuminate\Support\Arr;
|
||||
use LibreNMS\Component;
|
||||
use LibreNMS\Interfaces\Module;
|
||||
use LibreNMS\OS;
|
||||
use LibreNMS\OS\Junos;
|
||||
use LibreNMS\Util\IP;
|
||||
|
||||
class Isis implements Module
|
||||
{
|
||||
/**
|
||||
* Discover this module. Heavier processes can be run here
|
||||
* Run infrequently (default 4 times a day)
|
||||
*
|
||||
* @param OS $os
|
||||
*/
|
||||
public function discover(OS $os)
|
||||
{
|
||||
$device_array = $os->getDeviceArray();
|
||||
$device_id = $os->getDeviceId();
|
||||
$options = [
|
||||
'filter' => [
|
||||
'device_id' => ['=', $device_id],
|
||||
'type' => ['=', 'ISIS'],
|
||||
],
|
||||
];
|
||||
|
||||
$component = new Component();
|
||||
$components = $component->getComponents($device_id, $options);
|
||||
|
||||
// Check if the device has any ISIS enabled interfaces
|
||||
$circuits_poll = snmpwalk_group($device_array, 'ISIS-MIB::isisCirc', 'ISIS-MIB');
|
||||
|
||||
// No ISIS enabled interfaces -> delete the component
|
||||
if (empty($circuits_poll)) {
|
||||
if (isset($components[$device_id])) {
|
||||
foreach ($components[$device_id] as $component_id => $_unused) {
|
||||
$component->deleteComponent($component_id);
|
||||
}
|
||||
echo "\nISIS components deleted";
|
||||
}
|
||||
|
||||
// ISIS enabled interfaces found -> create the component
|
||||
} else {
|
||||
if (isset($components[$device_id])) {
|
||||
$isis_component = $components[$device_id];
|
||||
} else {
|
||||
$isis_component = $component->createComponent($device_id, 'ISIS');
|
||||
}
|
||||
|
||||
$component->setComponentPrefs($device_id, $isis_component);
|
||||
echo "\nISIS component updated";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll data for this module and update the DB / RRD.
|
||||
* Try to keep this efficient and only run if discovery has indicated there is a reason to run.
|
||||
* Run frequently (default every 5 minutes)
|
||||
*
|
||||
* @param OS $os
|
||||
*/
|
||||
public function poll(OS $os)
|
||||
{
|
||||
// Translate system state codes into meaningful strings
|
||||
$isis_codes = ['1' => 'L1',
|
||||
'2' => 'L2',
|
||||
'3' => 'L1L2',
|
||||
'4' => 'unknown',
|
||||
];
|
||||
|
||||
// Get device objects
|
||||
$device_array = $os->getDeviceArray();
|
||||
$device = $os->getDevice();
|
||||
$device_id = $os->getDeviceId();
|
||||
|
||||
// Check if device has any ISIS enabled circuits previously discovered
|
||||
$options = [
|
||||
'filter' => [
|
||||
'device_id' => ['=', $device_id],
|
||||
'type' => ['=', 'ISIS'],
|
||||
],
|
||||
];
|
||||
|
||||
$component = new Component();
|
||||
$components = $component->getComponents($device_id, $options);
|
||||
|
||||
if (! empty($components)) {
|
||||
|
||||
// Poll all ISIS enabled interfaces from the device
|
||||
$circuits_poll = snmpwalk_group($device_array, 'ISIS-MIB::isisCirc', 'ISIS-MIB');
|
||||
|
||||
// Poll all available adjacencies
|
||||
$adjacencies_poll = snmpwalk_group($device_array, 'ISIS-MIB::isisISAdj', 'ISIS-MIB');
|
||||
$adjacencies = collect();
|
||||
$isis_data = [];
|
||||
|
||||
if ($os instanceof Junos) {
|
||||
// Do not poll loopback interface
|
||||
unset($circuits_poll['16']);
|
||||
}
|
||||
|
||||
// Loop through all configured adjacencies on the device
|
||||
foreach ($circuits_poll as $circuit => $circuit_data) {
|
||||
if (is_numeric($circuit)) {
|
||||
echo "\nAdjacency found on ifIndex: " . $circuit;
|
||||
$port_id = (int) $device->ports()->where('ifIndex', $circuit)->value('port_id');
|
||||
|
||||
if ($circuit_data['isisCircPassiveCircuit'] != '1') {
|
||||
// Adjacency is UP
|
||||
if (! empty($adjacencies_poll[$circuit]) && Arr::last($adjacencies_poll[$circuit]['isisISAdjState']) == '3') {
|
||||
$isis_data['isisISAdjState'] = Arr::last($adjacencies_poll[$circuit]['isisISAdjState']);
|
||||
$isis_data['isisISAdjNeighSysID'] = Arr::last($adjacencies_poll[$circuit]['isisISAdjNeighSysID']);
|
||||
$isis_data['isisISAdjNeighSysType'] = Arr::last($adjacencies_poll[$circuit]['isisISAdjNeighSysType']);
|
||||
$isis_data['isisISAdjNeighPriority'] = Arr::last($adjacencies_poll[$circuit]['isisISAdjNeighPriority']);
|
||||
$isis_data['isisISAdjLastUpTime'] = Arr::last($adjacencies_poll[$circuit]['isisISAdjLastUpTime']);
|
||||
$isis_data['isisISAdjAreaAddress'] = Arr::last(Arr::last($adjacencies_poll[$circuit]['isisISAdjAreaAddress']));
|
||||
$isis_data['isisISAdjIPAddrType'] = Arr::last(Arr::last($adjacencies_poll[$circuit]['isisISAdjIPAddrType']));
|
||||
$isis_data['isisISAdjIPAddrAddress'] = Arr::last(Arr::last($adjacencies_poll[$circuit]['isisISAdjIPAddrAddress']));
|
||||
|
||||
// Format data
|
||||
$isis_data['isisISAdjNeighSysID'] = str_replace(' ', '.', $isis_data['isisISAdjNeighSysID']);
|
||||
$isis_data['isisISAdjLastUpTime'] = (int) $isis_data['isisISAdjLastUpTime'] / 100;
|
||||
$isis_data['isisISAdjAreaAddress'] = str_replace(' ', '.', $isis_data['isisISAdjAreaAddress']);
|
||||
|
||||
// Save data into the DB
|
||||
$adjacency = IsisAdjacency::updateOrCreate([
|
||||
'device_id' => $device_id,
|
||||
'ifIndex' => $circuit,
|
||||
], [
|
||||
'device_id' => $device_id,
|
||||
'ifIndex' => $circuit,
|
||||
'port_id' => $port_id,
|
||||
'isisISAdjState' => 'up',
|
||||
'isisISAdjNeighSysType' => $isis_codes[$isis_data['isisISAdjNeighSysType']],
|
||||
'isisISAdjNeighSysID' => $isis_data['isisISAdjNeighSysID'],
|
||||
'isisISAdjNeighPriority' => $isis_data['isisISAdjNeighPriority'],
|
||||
'isisISAdjLastUpTime' => $isis_data['isisISAdjLastUpTime'],
|
||||
'isisISAdjAreaAddress' => $isis_data['isisISAdjAreaAddress'],
|
||||
'isisISAdjIPAddrType' => $isis_data['isisISAdjIPAddrType'],
|
||||
'isisISAdjIPAddrAddress' => IP::fromHexstring($isis_data['isisISAdjIPAddrAddress']),
|
||||
]);
|
||||
} else {
|
||||
/*
|
||||
* Adjacency is configured on the device but not available
|
||||
* Update existing record to down state
|
||||
* Set the status of the adjacency to down
|
||||
* Also if the adjacency was never up, create a record
|
||||
*/
|
||||
if ($circuit_data['isisCircAdminState'] != '1') {
|
||||
$state = 'disabled';
|
||||
} else {
|
||||
$state = 'down';
|
||||
}
|
||||
$adjacency = IsisAdjacency::updateOrCreate([
|
||||
'device_id' => $device_id,
|
||||
'ifIndex' => $circuit,
|
||||
], [
|
||||
'device_id' => $device_id,
|
||||
'ifIndex' => $circuit,
|
||||
'port_id' => $port_id,
|
||||
'isisISAdjState' => $state,
|
||||
]);
|
||||
}
|
||||
$adjacencies->push($adjacency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\nFound " . $adjacencies->count() . ' configured adjacencies';
|
||||
|
||||
// Cleanup
|
||||
IsisAdjacency::query()
|
||||
->where(['device_id' => $device['device_id']])
|
||||
->whereNotIn('ifIndex', $adjacencies->pluck('ifIndex'))->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all DB data for this module.
|
||||
* This will be run when the module is disabled.
|
||||
*
|
||||
* @param OS $os
|
||||
*/
|
||||
public function cleanup(OS $os)
|
||||
{
|
||||
$os->getDevice()->isisAdjacencies()->delete();
|
||||
}
|
||||
}
|
@@ -29,6 +29,7 @@ use App\Models\BgpPeer;
|
||||
use App\Models\CefSwitching;
|
||||
use App\Models\Component;
|
||||
use App\Models\Device;
|
||||
use App\Models\IsisAdjacency;
|
||||
use App\Models\Mpls;
|
||||
use App\Models\OspfInstance;
|
||||
use App\Models\Port;
|
||||
@@ -64,6 +65,7 @@ class ObjectCache
|
||||
'vrf' => Vrf::hasAccess($user)->count(),
|
||||
'mpls' => Mpls::hasAccess($user)->count(),
|
||||
'ospf' => OspfInstance::hasAccess($user)->count(),
|
||||
'isis' => IsisAdjacency::hasAccess($user)->count(),
|
||||
'cisco-otv' => Component::hasAccess($user)->where('type', 'Cisco-OTV')->count(),
|
||||
'bgp' => BgpPeer::hasAccess($user)->count(),
|
||||
'cef' => CefSwitching::hasAccess($user)->count(),
|
||||
|
@@ -36,8 +36,10 @@ class RoutingController implements DeviceTab
|
||||
public function __construct()
|
||||
{
|
||||
$device = DeviceCache::getPrimary();
|
||||
//dd($device);
|
||||
$this->tabs = [
|
||||
'ospf' => $device->ospfInstances()->count(),
|
||||
'isis' => $device->isisAdjacencies()->count(),
|
||||
'bgp' => $device->bgppeers()->count(),
|
||||
'vrf' => $device->vrfs()->count(),
|
||||
'cef' => $device->cefSwitching()->count(),
|
||||
|
@@ -162,6 +162,16 @@ class MenuComposer
|
||||
];
|
||||
}
|
||||
|
||||
if ($routing_count['isis']) {
|
||||
$routing_menu[] = [
|
||||
[
|
||||
'url' => 'isis',
|
||||
'icon' => 'arrows-alt',
|
||||
'text' => 'ISIS Adjacencies',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
if ($routing_count['cisco-otv']) {
|
||||
$routing_menu[] = [
|
||||
[
|
||||
|
@@ -654,6 +654,11 @@ class Device extends BaseModel
|
||||
return $this->hasMany(\App\Models\OspfPort::class, 'device_id');
|
||||
}
|
||||
|
||||
public function isisAdjacencies(): HasMany
|
||||
{
|
||||
return $this->hasMany(\App\Models\IsisAdjacency::class, 'device_id', 'device_id');
|
||||
}
|
||||
|
||||
public function netscalerVservers(): HasMany
|
||||
{
|
||||
return $this->hasMany(NetscalerVserver::class, 'device_id');
|
||||
|
56
app/Models/IsisAdjacency.php
Normal file
56
app/Models/IsisAdjacency.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* IsisAdjacency.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @link http://librenms.org
|
||||
* @copyright 2021 Otto Reinikainen
|
||||
* @author Otto Reinikainen <otto@ottorei.fi>
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class IsisAdjacency extends PortRelatedModel
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
//public $primaryKey = 'id';
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'device_id',
|
||||
'port_id',
|
||||
'ifIndex',
|
||||
'isisISAdjState',
|
||||
'isisISAdjNeighSysType',
|
||||
'isisISAdjNeighSysID',
|
||||
'isisISAdjNeighPriority',
|
||||
'isisISAdjLastUpTime',
|
||||
'isisISAdjAreaAddress',
|
||||
'isisISAdjIPAddrType',
|
||||
'isisISAdjIPAddrAddress',
|
||||
];
|
||||
|
||||
// ---- Define Relationships ----
|
||||
|
||||
public function device()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Port::class, 'device_id');
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateIsisAdjacenciesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('isis_adjacencies', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('device_id')->index();
|
||||
$table->integer('port_id')->index();
|
||||
$table->integer('ifIndex')->index();
|
||||
$table->string('isisISAdjState', 13);
|
||||
$table->string('isisISAdjNeighSysType', 128);
|
||||
$table->string('isisISAdjNeighSysID', 128);
|
||||
$table->string('isisISAdjNeighPriority', 128);
|
||||
$table->unsignedBigInteger('isisISAdjLastUpTime');
|
||||
$table->string('isisISAdjAreaAddress', 128);
|
||||
$table->string('isisISAdjIPAddrType', 128);
|
||||
$table->string('isisISAdjIPAddrAddress', 128);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('isis_adjacencies');
|
||||
}
|
||||
}
|
30
includes/discovery/isis.inc.php
Normal file
30
includes/discovery/isis.inc.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* isis.inc.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @link http://librenms.org
|
||||
* @copyright 2021 Otto Reinikainen
|
||||
* @author Otto Reinikainen <otto@ottorei.fi>
|
||||
*/
|
||||
|
||||
use LibreNMS\OS;
|
||||
|
||||
if (! $os instanceof OS) {
|
||||
$os = OS::make($device);
|
||||
}
|
||||
(new \LibreNMS\Modules\Isis())->discover($os);
|
@@ -312,6 +312,9 @@ function delete_device($id)
|
||||
dbQuery('DELETE `ipv4_addresses` FROM `ipv4_addresses` INNER JOIN `ports` ON `ports`.`port_id`=`ipv4_addresses`.`port_id` WHERE `device_id`=?', [$id]);
|
||||
dbQuery('DELETE `ipv6_addresses` FROM `ipv6_addresses` INNER JOIN `ports` ON `ports`.`port_id`=`ipv6_addresses`.`port_id` WHERE `device_id`=?', [$id]);
|
||||
|
||||
//Remove IsisAdjacencies
|
||||
\App\Models\IsisAdjacency::where('device_id', $id)->delete();
|
||||
|
||||
//Remove Outages
|
||||
\App\Models\Availability::where('device_id', $id)->delete();
|
||||
\App\Models\DeviceOutage::where('device_id', $id)->delete();
|
||||
|
@@ -19,6 +19,7 @@ $type_text['netscaler_vsvr'] = 'VServers';
|
||||
$type_text['bgp'] = 'BGP';
|
||||
$type_text['cef'] = 'CEF';
|
||||
$type_text['ospf'] = 'OSPF';
|
||||
$type_text['isis'] = 'ISIS';
|
||||
$type_text['vrf'] = 'VRFs';
|
||||
$type_text['routes'] = 'Routing Table';
|
||||
$type_text['cisco-otv'] = 'OTV';
|
||||
|
55
includes/html/pages/device/routing/isis.inc.php
Normal file
55
includes/html/pages/device/routing/isis.inc.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
use App\Models\IsisAdjacency;
|
||||
|
||||
echo '
|
||||
<div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<table class="table table-condensed table-hover" style="border-collapse:collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Local device</th>
|
||||
<th>Local interface</th>
|
||||
<th>Adjacent</th>
|
||||
<th>System ID</th>
|
||||
<th>Area</th>
|
||||
<th>System type</th>
|
||||
<th>State</th>
|
||||
<th>Last uptime</th>
|
||||
</tr>
|
||||
</thead>';
|
||||
|
||||
foreach (IsisAdjacency::where('device_id', $device['device_id'])->with('port')->get() as $adj) {
|
||||
if ($adj->isisISAdjState == 'up') {
|
||||
$color = 'green';
|
||||
} else {
|
||||
$color = 'red';
|
||||
}
|
||||
$interface_name = $adj->port->ifName;
|
||||
|
||||
echo '
|
||||
<tbody>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>' . generate_device_link($device, 0, ['tab' => 'routing', 'proto' => 'isis']) . '</td>
|
||||
<td><a href="' . \LibreNMS\Util\Url::generate([
|
||||
'page'=>'device',
|
||||
'device'=>$adj->device_id,
|
||||
'tab'=>'port',
|
||||
'port'=>$adj->port_id,
|
||||
]) . '">' . $interface_name . '</a></td>
|
||||
<td>' . $adj->isisISAdjIPAddrAddress . '</td>
|
||||
<td>' . $adj->isisISAdjNeighSysID . '</td>
|
||||
<td>' . $adj->isisISAdjAreaAddress . '</td>
|
||||
<td>' . $adj->isisISAdjNeighSysType . '</td>
|
||||
<td><strong><span style="color: ' . $color . ';">' . $adj->isisISAdjState . '</span></strong></td>
|
||||
<td>' . \LibreNMS\Util\Time::formatInterval($adj->isisISAdjLastUpTime) . '</td>
|
||||
</tr>
|
||||
</tbody>';
|
||||
}
|
||||
echo '</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
@@ -17,6 +17,7 @@ $type_text['bgp'] = 'BGP';
|
||||
$type_text['cef'] = 'CEF';
|
||||
$type_text['mpls'] = 'MPLS';
|
||||
$type_text['ospf'] = 'OSPF';
|
||||
$type_text['isis'] = 'ISIS';
|
||||
$type_text['vrf'] = 'VRFs';
|
||||
$type_text['cisco-otv'] = 'OTV';
|
||||
|
||||
@@ -58,6 +59,7 @@ switch ($vars['protocol']) {
|
||||
case 'cef':
|
||||
case 'mpls':
|
||||
case 'ospf':
|
||||
case 'isis':
|
||||
case 'cisco-otv':
|
||||
include 'includes/html/pages/routing/' . $vars['protocol'] . '.inc.php';
|
||||
break;
|
||||
|
111
includes/html/pages/routing/isis.inc.php
Normal file
111
includes/html/pages/routing/isis.inc.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
use App\Models\IsisAdjacency;
|
||||
|
||||
if (! Auth::user()->hasGlobalRead()) {
|
||||
include 'includes/html/error-no-perm.inc.php';
|
||||
} else {
|
||||
$link_array = [
|
||||
'page' => 'routing',
|
||||
'protocol' => 'isis',
|
||||
];
|
||||
|
||||
print_optionbar_start('', '');
|
||||
|
||||
echo '<span style="font-weight: bold;">Adjacencies</span> » ';
|
||||
|
||||
if (! $vars['state']) {
|
||||
$vars['state'] = 'all';
|
||||
}
|
||||
|
||||
if ($vars['state'] == 'all') {
|
||||
$filter = ['up', 'down'];
|
||||
echo "<span class='pagemenu-selected'>";
|
||||
}
|
||||
|
||||
echo generate_link('All', $vars, ['state' => 'all']);
|
||||
if ($vars['state'] == 'all') {
|
||||
echo '</span>';
|
||||
}
|
||||
|
||||
echo ' | ';
|
||||
|
||||
if ($vars['state'] == 'up') {
|
||||
$filter = ['up'];
|
||||
echo "<span class='pagemenu-selected'>";
|
||||
}
|
||||
|
||||
echo generate_link('Up', $vars, ['state' => 'up']);
|
||||
if ($vars['state'] == 'up') {
|
||||
$filter = ['up'];
|
||||
echo '</span>';
|
||||
}
|
||||
|
||||
echo ' | ';
|
||||
|
||||
if ($vars['state'] == 'down') {
|
||||
echo "<span class='pagemenu-selected'>";
|
||||
}
|
||||
|
||||
echo generate_link('Down', $vars, ['state' => 'down']);
|
||||
if ($vars['state'] == 'down') {
|
||||
$filter = ['down'];
|
||||
echo '</span>';
|
||||
}
|
||||
|
||||
print_optionbar_end();
|
||||
|
||||
echo '
|
||||
<div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<table class="table table-condensed table-hover" style="border-collapse:collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Local device</th>
|
||||
<th>Local interface</th>
|
||||
<th>Adjacent</th>
|
||||
<th>System ID</th>
|
||||
<th>Area</th>
|
||||
<th>System type</th>
|
||||
<th>State</th>
|
||||
<th>Last uptime</th>
|
||||
</tr>
|
||||
</thead>';
|
||||
|
||||
foreach (IsisAdjacency::whereIn('isisISAdjState', $filter)->with('port')->get() as $adj) {
|
||||
$device = device_by_id_cache($adj->device_id);
|
||||
if ($adj->isisISAdjState == 'up') {
|
||||
$color = 'green';
|
||||
} else {
|
||||
$color = 'red';
|
||||
}
|
||||
|
||||
$interface_name = $adj->port->ifName;
|
||||
|
||||
echo '
|
||||
<tbody>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>' . generate_device_link($device, 0, ['tab' => 'routing', 'proto' => 'isis']) . '</td>
|
||||
<td><a href="' . \LibreNMS\Util\Url::generate([
|
||||
'page'=>'device',
|
||||
'device'=>$adj->device_id,
|
||||
'tab'=>'port',
|
||||
'port'=>$adj->port_id,
|
||||
]) . '">' . $interface_name . '</a></td>
|
||||
<td>' . $adj->isisISAdjIPAddrAddress . '</td>
|
||||
<td>' . $adj->isisISAdjNeighSysID . '</td>
|
||||
<td>' . $adj->isisISAdjAreaAddress . '</td>
|
||||
<td>' . $adj->isisISAdjNeighSysType . '</td>
|
||||
<td><strong><span style="color: ' . $color . ';">' . $adj->isisISAdjState . '</span></strong></td>
|
||||
<td>' . \LibreNMS\Util\Time::formatInterval($adj->isisISAdjLastUpTime) . '</td>
|
||||
</tr>
|
||||
</tbody>';
|
||||
}
|
||||
echo '</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
30
includes/polling/isis.inc.php
Normal file
30
includes/polling/isis.inc.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* isis.inc.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* @link http://librenms.org
|
||||
* @copyright 2021 Otto Reinikainen
|
||||
* @author Otto Reinikainen <otto@ottorei.fi>
|
||||
*/
|
||||
|
||||
use LibreNMS\OS;
|
||||
|
||||
if (! $os instanceof OS) {
|
||||
$os = OS::make($device);
|
||||
}
|
||||
(new \LibreNMS\Modules\Isis())->poll($os);
|
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,10 @@
|
||||
"name": "BGP Session down",
|
||||
"extra": "{\"count\": 1}"
|
||||
},
|
||||
{
|
||||
"builder": {"condition":"AND","rules":[{"id":"isis_adjacencies.isisISAdjState","field":"isis_adjacencies.isisISAdjState","type":"string","input":"text","operator":"equal","value":"down"},{"condition":"AND","rules":[{"id":"component.type","field":"component.type","type":"string","input":"text","operator":"equal","value":"ISIS"},{"condition":"AND","rules":[{"id":"component.ignore","field":"component.ignore","type":"string","input":"text","operator":"equal","value":"0"},{"id":"component.disabled","field":"component.disabled","type":"string","input":"text","operator":"equal","value":"0"}]}]},{"id":"macros.device_up","field":"macros.device_up","type":"integer","input":"radio","operator":"equal","value":"1"}],"valid":true},
|
||||
"name": "ISIS Adjacency down"
|
||||
},
|
||||
{
|
||||
"rule": "bgpPeers.bgpPeerFsmEstablishedTime < \"300\" && bgpPeers.bgpPeerState = \"established\" && macros.device_up = \"1\"",
|
||||
"name": "BGP Session established",
|
||||
|
@@ -993,6 +993,13 @@
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"discovery_modules.isis": {
|
||||
"order": 450,
|
||||
"group": "discovery",
|
||||
"section": "discovery_modules",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"discovery_modules.processors": {
|
||||
"order": 260,
|
||||
"group": "discovery",
|
||||
@@ -4382,6 +4389,13 @@
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"poller_modules.isis": {
|
||||
"order": 450,
|
||||
"group": "poller",
|
||||
"section": "poller_modules",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"poller_modules.cisco-ipsec-flow-monitor": {
|
||||
"order": 90,
|
||||
"group": "poller",
|
||||
|
@@ -790,6 +790,25 @@ ipv6_networks:
|
||||
- { Field: context_name, Type: varchar(128), 'Null': true, Extra: '' }
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [ipv6_network_id], Unique: true, Type: BTREE }
|
||||
isis_adjacencies:
|
||||
Columns:
|
||||
- { Field: id, Type: int unsigned, 'Null': false, Extra: 'auto_increment' }
|
||||
- { Field: device_id, Type: int, 'Null': false, Extra: '' }
|
||||
- { Field: port_id, Type: int, 'Null': false, Extra: '' }
|
||||
- { Field: ifIndex, Type: int, 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjState, Type: varchar(13), 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjNeighSysType, Type: varchar(128), 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjNeighSysID, Type: varchar(128), 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjNeighPriority, Type: varchar(128), 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjLastUpTime, Type: bigint unsigned, 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjAreaAddress, Type: varchar(128), 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjIPAddrType, Type: varchar(128), 'Null': false, Extra: '' }
|
||||
- { Field: isisISAdjIPAddrAddress, Type: varchar(128), 'Null': false, Extra: '' }
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [id], Unique: true, Type: BTREE }
|
||||
isis_adjacencies_device_id_index: { Name: isis_adjacencies_device_id_index, Columns: [device_id], Unique: false, Type: BTREE }
|
||||
isis_adjacencies_port_id_index: { Name: isis_adjacencies_port_id_index, Columns: [port_id], Unique: false, Type: BTREE }
|
||||
isis_adjacencies_ifindex_index: { Name: isis_adjacencies_ifindex_index, Columns: [ifIndex], Unique: false, Type: BTREE }
|
||||
juniAtmVp:
|
||||
Columns:
|
||||
- { Field: id, Type: 'bigint unsigned', 'Null': false, Extra: auto_increment }
|
||||
|
@@ -499,6 +499,9 @@ return [
|
||||
'ipv6-addresses' => [
|
||||
'description' => 'IPv6 Addresses',
|
||||
],
|
||||
'isis' => [
|
||||
'description' => 'ISIS',
|
||||
],
|
||||
'junose-atm-vp' => [
|
||||
'description' => 'Junose ATM VP',
|
||||
],
|
||||
@@ -1053,6 +1056,9 @@ return [
|
||||
'ospf' => [
|
||||
'description' => 'OSPF',
|
||||
],
|
||||
'isis' => [
|
||||
'description' => 'ISIS',
|
||||
],
|
||||
'cisco-ipsec-flow-monitor' => [
|
||||
'description' => 'Cisco IPSec flow Monitor',
|
||||
],
|
||||
|
13212
tests/data/junos_mx5t_isis.json
Normal file
13212
tests/data/junos_mx5t_isis.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -69,6 +69,9 @@ ospf:
|
||||
excluded_fields: [id, device_id]
|
||||
ospf_nbrs:
|
||||
excluded_fields: [id, device_id]
|
||||
isis:
|
||||
isis_adjacencies:
|
||||
excluded_fields: [id, device_id, port_id]
|
||||
ports:
|
||||
ports:
|
||||
excluded_fields: [device_id, port_id, poll_time, poll_period, ifVrf]
|
||||
|
5651
tests/snmpsim/junos_mx5t_isis.snmprec
Normal file
5651
tests/snmpsim/junos_mx5t_isis.snmprec
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user