Rewrite ISIS Adjacency discovery/polling (#13155)

* Rewrite ISIS Adjacency discovery/polling
hopefully much faster now, do most work in discovery and just check up/down in poller.

* unused variable

* Implement option for OS override

* fix an incorrect typehint

* test data

* work around stupid migration name

* update schema

* better handling for the on-demand discovery

* more detailed phpdoc

* fix when adjacency is not found

* don't clear out data when adjacency goes away

* Adjust nullable fields

* fixes

* fix class name

* correct migration

* fix bug causing adjacency data to always be blank

* port popups for port links

* isisISAdjState does not need to be nullable

* remove extra space

* default off

* If port is missing return $text

* update schema

* Cleanup old components

* correc copy paste error
This commit is contained in:
Tony Murray
2021-08-23 21:19:55 -05:00
committed by GitHub
parent 456c5d2fae
commit 8e409ba051
13 changed files with 358 additions and 186 deletions

View File

@@ -24,18 +24,20 @@
namespace LibreNMS\DB;
use Illuminate\Support\Collection;
trait SyncsModels
{
/**
* Sync several models for a device's relationship
* Model must implement \LibreNMS\Interfaces\Models\Keyable interface
*
* @param \App\Models\Device $device
* @param string $relationship
* @param \Illuminate\Support\Collection $models
* @param \App\Models\Device $device
* @param string $relationship
* @param \Illuminate\Support\Collection $models \LibreNMS\Interfaces\Models\Keyable
* @return \Illuminate\Support\Collection
*/
protected function syncModels($device, $relationship, $models)
protected function syncModels($device, $relationship, $models): Collection
{
$models = $models->keyBy->getCompositeKey();
$existing = $device->$relationship->keyBy->getCompositeKey();
@@ -56,4 +58,26 @@ trait SyncsModels
return $existing->merge($new);
}
/**
* Combine a list of existing and potentially new models
* If the model exists fill any new data from the new models
*
* @param \Illuminate\Support\Collection $existing \LibreNMS\Interfaces\Models\Keyable
* @param \Illuminate\Support\Collection $discovered \LibreNMS\Interfaces\Models\Keyable
* @return \Illuminate\Support\Collection
*/
protected function fillNew(Collection $existing, Collection $discovered): Collection
{
$all = $existing->keyBy->getCompositeKey();
foreach ($discovered as $new) {
if ($found = $all->get($new->getCompositeKey())) {
$found->fill($new->getAttributes());
} else {
$all->put($new->getCompositeKey(), $new);
}
}
return $all;
}
}

View File

@@ -0,0 +1,37 @@
<?php
/*
* IsIsDiscovery.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/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2021 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Interfaces\Discovery;
interface IsIsDiscovery
{
/**
* Discover a Collection of IsIsAdjacency models.
* Will be keyed by ifIndex
*
* @return \Illuminate\Support\Collection \App\Models\IsIsAdjacency
*/
public function discoverIsIs();
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* IsIsPolling.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/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2021 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Interfaces\Polling;
interface IsIsPolling
{
/**
* @param \Illuminate\Support\Collection $adjacencies \App\Models\IsIsAdjacency
* @return \Illuminate\Support\Collection \App\Models\IsIsAdjacency
*/
public function pollIsIs($adjacencies);
}

View File

@@ -24,60 +24,43 @@
namespace LibreNMS\Modules;
use App\Models\Device;
use App\Models\IsisAdjacency;
use App\Observers\ModuleModelObserver;
use Illuminate\Support\Arr;
use LibreNMS\Component;
use Illuminate\Support\Collection;
use LibreNMS\DB\SyncsModels;
use LibreNMS\Interfaces\Discovery\IsIsDiscovery;
use LibreNMS\Interfaces\Module;
use LibreNMS\Interfaces\Polling\IsIsPolling;
use LibreNMS\OS;
use LibreNMS\OS\Junos;
use LibreNMS\Util\IP;
class Isis implements Module
{
use SyncsModels;
protected $isis_codes = [
'l1IntermediateSystem' => 'L1',
'l2IntermediateSystem' => 'L2',
'l1L2IntermediateSystem' => 'L1L2',
'unknown' => 'unknown',
];
/**
* Discover this module. Heavier processes can be run here
* Run infrequently (default 4 times a day)
*
* @param OS $os
* @param OS $os
*/
public function discover(OS $os)
{
$device_array = $os->getDeviceArray();
$device_id = $os->getDeviceId();
$options = [
'filter' => [
'device_id' => ['=', $device_id],
'type' => ['=', 'ISIS'],
],
];
$adjacencies = $os instanceof IsIsDiscovery
? $os->discoverIsIs()
: $this->discoverIsIsMib($os);
$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";
}
ModuleModelObserver::observe('\App\Models\IsisAdjacency');
$this->syncModels($os->getDevice(), 'isisAdjacencies', $adjacencies);
}
/**
@@ -85,132 +68,111 @@ class Isis implements Module
* 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
* @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',
];
$adjacencies = $os->getDevice()->isisAdjacencies;
// 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();
if (empty($adjacencies)) {
return; // no data to poll
}
$updated = $os instanceof IsIsPolling
? $os->pollIsIs($adjacencies)
: $this->pollIsIsMib($adjacencies, $os);
$updated->each->save();
}
/**
* Remove all DB data for this module.
* This will be run when the module is disabled.
*
* @param OS $os
* @param OS $os
*/
public function cleanup(OS $os)
{
$os->getDevice()->isisAdjacencies()->delete();
// clean up legacy components from old code
$os->getDevice()->components()->where('type', 'ISIS')->delete();
}
public function discoverIsIsMib(OS $os): Collection
{
// Check if the device has any ISIS enabled interfaces
$circuits = snmpwalk_cache_oid($os->getDeviceArray(), 'ISIS-MIB::isisCirc', []);
$adjacencies = new Collection;
if (! empty($circuits)) {
$adjacencies_data = snmpwalk_cache_twopart_oid($os->getDeviceArray(), 'ISIS-MIB::isisISAdj', [], null, null, '-OQUstx');
$ifIndex_port_id_map = $os->getDevice()->ports()->pluck('port_id', 'ifIndex');
// No ISIS enabled interfaces -> delete the component
foreach ($circuits as $circuit_id => $circuit_data) {
if (! isset($circuit_data['isisCircIfIndex'])) {
continue;
}
if ($os instanceof Junos && $circuit_id == 16) {
continue; // Do not poll loopback interface
}
$adjacency_data = Arr::last($adjacencies_data[$circuit_id] ?? [[]]);
$attributes = [
'device_id' => $os->getDeviceId(),
'ifIndex' => $circuit_data['isisCircIfIndex'],
'port_id' => $ifIndex_port_id_map[$circuit_data['isisCircIfIndex']] ?? null,
'isisCircAdminState' => $circuit_data['isisCircAdminState'] ?? 'down',
'isisISAdjState' => $adjacency_data['isisISAdjState'] ?? 'down',
];
if (! empty($adjacency_data)) {
$attributes = array_merge($attributes, [
'isisISAdjNeighSysType' => Arr::get($this->isis_codes, $adjacency_data['isisISAdjNeighSysType'] ?? 'unknown', 'unknown'),
'isisISAdjNeighSysID' => str_replace(' ', '.', trim($adjacency_data['isisISAdjNeighSysID'] ?? '')),
'isisISAdjNeighPriority' => $adjacency_data['isisISAdjNeighPriority'] ?? '',
'isisISAdjLastUpTime' => $this->parseAdjacencyTime($adjacency_data),
'isisISAdjAreaAddress' => str_replace(' ', '.', trim($adjacency_data['isisISAdjAreaAddress'] ?? '')),
'isisISAdjIPAddrType' => $adjacency_data['isisISAdjIPAddrType'] ?? '',
'isisISAdjIPAddrAddress' => (string) IP::fromHexstring($adjacency_data['isisISAdjIPAddrAddress'] ?? null, true),
]);
}
$adjacencies->push(new IsisAdjacency($attributes));
}
}
return $adjacencies;
}
public function pollIsIsMib(Collection $adjacencies, OS $os): Collection
{
$data = snmpwalk_cache_twopart_oid($os->getDeviceArray(), 'isisISAdjState', [], 'ISIS-MIB');
if (count($data) !== $adjacencies->where('isisISAdjState', 'up')->count()) {
echo 'New Adjacencies, running discovery';
// don't enable, might be a bad heuristic
return $this->fillNew($adjacencies, $this->discoverIsIsMib($os));
}
$data = snmpwalk_cache_twopart_oid($os->getDeviceArray(), 'isisISAdjLastUpTime', $data, 'ISIS-MIB', null, '-OQUst');
$adjacencies->each(function (IsisAdjacency $adjacency) use (&$data) {
$adjacency_data = Arr::last($data[$adjacency->ifIndex]);
$adjacency->isisISAdjState = $adjacency_data['isisISAdjState'] ?? $adjacency->isisISAdjState;
$adjacency->isisISAdjLastUpTime = $this->parseAdjacencyTime($adjacency_data);
$adjacency->save();
unset($data[$adjacency->ifIndex]);
});
return $adjacencies;
}
protected function parseAdjacencyTime($data): int
{
return (int) max($data['isisISAdjLastUpTime'] ?? 1, 1) / 100;
}
}

View File

@@ -56,13 +56,14 @@ class ModuleTestHelper
private $exclude_from_all = ['arp-table', 'fdb-table'];
private static $module_deps = [
'arp-table' => ['ports', 'arp-table'],
'cisco-mac-accounting' => ['ports', 'cisco-mac-accounting'],
'fdb-table' => ['ports', 'vlans', 'fdb-table'],
'vlans' => ['ports', 'vlans'],
'vrf' => ['ports', 'vrf'],
'isis' => ['ports', 'isis'],
'mpls' => ['ports', 'vrf', 'mpls'],
'nac' => ['ports', 'nac'],
'ospf' => ['ports', 'ospf'],
'cisco-mac-accounting' => ['ports', 'cisco-mac-accounting'],
'vlans' => ['ports', 'vlans'],
'vrf' => ['ports', 'vrf'],
];
/**

View File

@@ -129,6 +129,10 @@ class Url
*/
public static function portLink($port, $text = null, $type = null, $overlib = true, $single_graph = false)
{
if ($port === null) {
return $text;
}
$label = Rewrite::normalizeIfName($port->getLabel());
if (! $text) {
$text = $label;

View File

@@ -25,8 +25,9 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use LibreNMS\Interfaces\Models\Keyable;
class IsisAdjacency extends PortRelatedModel
class IsisAdjacency extends PortRelatedModel implements Keyable
{
use HasFactory;
@@ -37,6 +38,7 @@ class IsisAdjacency extends PortRelatedModel
'device_id',
'port_id',
'ifIndex',
'isisCircAdminState',
'isisISAdjState',
'isisISAdjNeighSysType',
'isisISAdjNeighSysID',
@@ -53,4 +55,9 @@ class IsisAdjacency extends PortRelatedModel
{
return $this->belongsTo(\App\Models\Port::class, 'device_id');
}
public function getCompositeKey()
{
return $this->ifIndex;
}
}

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class IsisAdjacenciesAddAdminStatus extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('isis_adjacencies', function (Blueprint $table) {
$table->string('isisCircAdminState', 16)->default('off');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropColumns('isis_adjacencies', 'isisCircAdminState');
}
}

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class IsisAdjacenciesNullable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('isis_adjacencies', function (Blueprint $table) {
$table->integer('port_id')->nullable()->change();
$table->string('isisISAdjNeighSysType', 128)->nullable()->change();
$table->string('isisISAdjNeighSysID', 128)->nullable()->change();
$table->string('isisISAdjNeighPriority', 128)->nullable()->change();
$table->unsignedBigInteger('isisISAdjLastUpTime')->nullable()->change();
$table->string('isisISAdjAreaAddress', 128)->nullable()->change();
$table->string('isisISAdjIPAddrType', 128)->nullable()->change();
$table->string('isisISAdjIPAddrAddress', 128)->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('isis_adjacencies', function (Blueprint $table) {
$table->integer('port_id')->change();
$table->string('isisISAdjNeighSysType', 128)->change();
$table->string('isisISAdjNeighSysID', 128)->change();
$table->string('isisISAdjNeighPriority', 128)->change();
$table->unsignedBigInteger('isisISAdjLastUpTime')->change();
$table->string('isisISAdjAreaAddress', 128)->change();
$table->string('isisISAdjIPAddrType', 128)->change();
$table->string('isisISAdjIPAddrAddress', 128)->change();
});
}
}

View File

@@ -10,14 +10,15 @@ echo '
<thead>
<tr>
<th>&nbsp;</th>
<th>Local device</th>
<th>Local interface</th>
<th>Local Device</th>
<th>Local Interface</th>
<th>Adjacent</th>
<th>System ID</th>
<th>Area</th>
<th>System type</th>
<th>System Type</th>
<th>Admin</th>
<th>State</th>
<th>Last uptime</th>
<th>Last Uptime</th>
</tr>
</thead>';
@@ -34,16 +35,12 @@ foreach (IsisAdjacency::where('device_id', $device['device_id'])->with('port')->
<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>' . \LibreNMS\Util\Url::portLink($adj->port) . '</td>
<td>' . $adj->isisISAdjIPAddrAddress . '</td>
<td>' . $adj->isisISAdjNeighSysID . '</td>
<td>' . $adj->isisISAdjAreaAddress . '</td>
<td>' . $adj->isisISAdjNeighSysType . '</td>
<td>' . $adj->isisCircAdminState . '</td>
<td><strong><span style="color: ' . $color . ';">' . $adj->isisISAdjState . '</span></strong></td>
<td>' . \LibreNMS\Util\Time::formatInterval($adj->isisISAdjLastUpTime) . '</td>
</tr>

View File

@@ -63,14 +63,15 @@ if (! Auth::user()->hasGlobalRead()) {
<thead>
<tr>
<th>&nbsp;</th>
<th>Local device</th>
<th>Local interface</th>
<th>Local Device</th>
<th>Local Interface</th>
<th>Adjacent</th>
<th>System ID</th>
<th>Area</th>
<th>System type</th>
<th>System Type</th>
<th>Admin</th>
<th>State</th>
<th>Last uptime</th>
<th>Last Uptime</th>
</tr>
</thead>';
@@ -89,16 +90,12 @@ if (! Auth::user()->hasGlobalRead()) {
<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>' . \LibreNMS\Util\Url::portLink($adj->port) . '</td>
<td>' . $adj->isisISAdjIPAddrAddress . '</td>
<td>' . $adj->isisISAdjNeighSysID . '</td>
<td>' . $adj->isisISAdjAreaAddress . '</td>
<td>' . $adj->isisISAdjNeighSysType . '</td>
<td>' . $adj->isisCircAdminState . '</td>
<td><strong><span style="color: ' . $color . ';">' . $adj->isisISAdjState . '</span></strong></td>
<td>' . \LibreNMS\Util\Time::formatInterval($adj->isisISAdjLastUpTime) . '</td>
</tr>

View File

@@ -796,16 +796,17 @@ 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: port_id, Type: int, 'Null': true, 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: '' }
- { Field: isisISAdjNeighSysType, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: isisISAdjNeighSysID, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: isisISAdjNeighPriority, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: isisISAdjLastUpTime, Type: 'bigint unsigned', 'Null': true, Extra: '' }
- { Field: isisISAdjAreaAddress, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: isisISAdjIPAddrType, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: isisISAdjIPAddrAddress, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: isisCircAdminState, Type: varchar(16), 'Null': false, Extra: '', Default: 'off' }
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 }

View File

@@ -13016,5 +13016,36 @@
],
"ports_vlans": []
}
},
"isis": {
"discovery": {
"isis_adjacencies": [
{
"ifIndex": 559,
"isisISAdjState": "up",
"isisISAdjNeighSysType": "L2",
"isisISAdjNeighSysID": "01.00.99.19.12.55",
"isisISAdjNeighPriority": "0",
"isisISAdjLastUpTime": 1224167,
"isisISAdjAreaAddress": "49.00.01",
"isisISAdjIPAddrType": "ipv4",
"isisISAdjIPAddrAddress": "10.99.252.255",
"isisCircAdminState": "on"
},
{
"ifIndex": 572,
"isisISAdjState": "up",
"isisISAdjNeighSysType": "L2",
"isisISAdjNeighSysID": "10.99.20.40.00.51",
"isisISAdjNeighPriority": "0",
"isisISAdjLastUpTime": 1206503,
"isisISAdjAreaAddress": "49.00.01",
"isisISAdjIPAddrType": "ipv4",
"isisISAdjIPAddrAddress": "10.99.252.253",
"isisCircAdminState": "on"
}
]
},
"poller": "matches discovery"
}
}
}