New module add juniper rpm support + reimplementation of cisco-sla module (#12799)

* Definition of a new SLA module to migrate from old cisco-sla and support other devices : Juniper RPM and Huawei

* Change wrong description name of module SLA

* Re implementing Juniper RPM support in a new module Slas (Cisco SLA to be added)

* Added Graphs for Juniper RPM types

* Tried to make discover and poller generic : to handle Cisco SLA and Juniper RPM and others

* Reimplementing Cisco SLA in the new Sla module and adding condition to manage both SLA and RPM

* Definition of a new SLA module to migrate from old cisco-sla and support other devices : Juniper RPM and Huawei

* Change wrong description name of module SLA

* Re implementing Juniper RPM support in a new module Slas (Cisco SLA to be added)

* Added Graphs for Juniper RPM types

* Tried to make discover and poller generic : to handle Cisco SLA and Juniper RPM and others

* Reimplementing Cisco SLA in the new Sla module and adding condition to manage both SLA and RPM

* Fix some error due to Elequent object replacing SQL request

* Fixing indentation

* Fixed continuous integrations errors

* Fixed continuous integrations errors part 2

* Fixed continuous integrations errors part 3 : missing last new lines

* Fixed PHP Static Analysis checks

* Fixed continuous integrations errors part 4

* Fixed PHP Static Analysis checks part 2

* Trying to convert existing cisco-sla to new slas one

* Trying to add slas to fix test failure (I am pretty sure this is not enough but I don't know how to do it)

* Switching old cisco-sla module declaration to new slas module in concerned OS files

* Fixing wrong sla module name instead of slas in concerned OS files

* Fixing wrong module name sla changed to slas (as is it in power-supplies reimplementation)

* Fixing some warnings shown in the Inspection CI but skipping some that are already present

* Adding tests files from virtual Juniper VMX and adding slas modules in /tests/module_tables

* Adding missing SNMP data files

* Module Slas modifications to use inheritance

* Fix CI errors

* Fix CI errors part 2

* Fix CI errors part 3

* Fixing no value on RTT graphs

* Fixing only last SLA to be polled : problem with loops

* Fix CI errors part 4

* Optimizing a little the Juniper RPM poller part

I wanted to query only the required values but it is complicated to query a specific OID
as Cisco-SLA does because the owner and tag are hardcoded in ASCII decimal with strange values.
So I use the function snmp_walk which gets the whole OID values in text.
And I index the Juniper MIB (because we want multiple values). But I changed the DISMAN MIB
requests to get only what we want.

* Fix CI errors

* Fix CI errors part 2

* Fix CI errors part 3

* Fixing PHP Static Analysis error 2/4

* Fix CI errors

* Implementing Interfaces to fix some errors that occurs with inheritance

* Adding missing Interfaces files

* Moving generic Sla discovery code into Junos Class

* Fix CI errors

* Fix CI errors part 2

* Fixing missing definition of SlaDiscovery in Cisco shared Class

* Fixing missing import for Illuminate\Database\Eloquent\Collection

* Fix CI errors part 3

* Fix PHP Static Analysis error

* change type strings to use translations instead of config

* IOSXR test data

* remove test data garbage

* simplify discovery

* Fix style

* Updating test files to adapt mock sla_nr ID starting from 0 and not 1 : CI tests should pass

* clean up polling
add rtt field in the db
cisco icmpjitter seems to have confused a lot of values

* rtt on discovery

* use crc32 for consistent sla_nr values

* revert snmprec

* Fix style

* correct schema

Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
geg347
2021-06-11 20:48:33 +02:00
committed by GitHub
parent 3cf039764e
commit 672fe61b5e
59 changed files with 19866 additions and 2663 deletions

View File

@@ -28,17 +28,21 @@ namespace LibreNMS\OS\Shared;
use App\Models\Device;
use App\Models\Mempool;
use App\Models\PortsNac;
use App\Models\Sla;
use Illuminate\Support\Arr;
use LibreNMS\Device\Processor;
use LibreNMS\Interfaces\Discovery\MempoolsDiscovery;
use LibreNMS\Interfaces\Discovery\OSDiscovery;
use LibreNMS\Interfaces\Discovery\ProcessorDiscovery;
use LibreNMS\Interfaces\Discovery\SlaDiscovery;
use LibreNMS\Interfaces\Polling\NacPolling;
use LibreNMS\Interfaces\Polling\SlaPolling;
use LibreNMS\OS;
use LibreNMS\OS\Traits\YamlOSDiscovery;
use LibreNMS\RRD\RrdDefinition;
use LibreNMS\Util\IP;
class Cisco extends OS implements OSDiscovery, ProcessorDiscovery, MempoolsDiscovery, NacPolling
class Cisco extends OS implements OSDiscovery, SlaDiscovery, ProcessorDiscovery, MempoolsDiscovery, NacPolling, SlaPolling
{
use YamlOSDiscovery {
YamlOSDiscovery::discoverOS as discoverYamlOS;
@@ -302,6 +306,56 @@ class Cisco extends OS implements OSDiscovery, ProcessorDiscovery, MempoolsDisco
return $processors;
}
public function discoverSlas()
{
$slas = collect();
$sla_data = snmpwalk_cache_oid($this->getDeviceArray(), 'rttMonCtrl', [], 'CISCO-RTTMON-MIB');
if (! empty($sla_data)) {
$sla_data = snmpwalk_cache_oid($this->getDeviceArray(), 'rttMonLatestRttOperCompletionTime', $sla_data, 'CISCO-RTTMON-MIB');
}
foreach ($sla_data as $index => $sla_config) {
$slas->push(new Sla([
'sla_nr' => $index,
'owner' => $sla_config['rttMonCtrlAdminOwner'] ?? '',
'tag' => $this->getSlaTag($sla_config),
'rtt_type' => $sla_config['rttMonCtrlAdminRttType'],
'rtt' => $sla_config['rttMonLatestRttOperCompletionTime'] ?? null,
'status' => ($sla_config['rttMonCtrlAdminStatus'] == 'active') ? 1 : 0,
'opstatus' => ($sla_config['rttMonLatestRttOperSense'] == 'ok') ? 0 : 2,
]));
}
return $slas;
}
private function getSlaTag($data)
{
if (! empty($data['rttMonCtrlAdminTag'])) {
return $data['rttMonCtrlAdminTag'];
}
switch ($data['rttMonCtrlAdminRttType']) {
case 'http':
return $data['rttMonEchoAdminURL'];
case 'dns':
return $data['rttMonEchoAdminTargetAddressString'];
case 'echo':
return IP::fromHexString($data['rttMonEchoAdminTargetAddress'], true);
case 'jitter':
$tag = IP::fromHexString($data['rttMonEchoAdminTargetAddress'], true) . ':' . $data['rttMonEchoAdminTargetPort'];
if (isset($data['rttMonEchoAdminCodecType']) && $data['rttMonEchoAdminCodecType'] != 'notApplicable') {
$tag .= ' (' . $data['rttMonEchoAdminCodecType'] . ' @ ' . $data['rttMonEchoAdminCodecInterval'] . 'ms)';
}
return $tag;
default:
return '';
}
}
public function pollNac()
{
$nac = collect();
@@ -346,6 +400,110 @@ class Cisco extends OS implements OSDiscovery, ProcessorDiscovery, MempoolsDisco
return $nac;
}
public function pollSlas($slas)
{
$device = $this->getDeviceArray();
$data = snmpwalk_group($device, 'rttMonLatestRttOperTable', 'CISCO-RTTMON-MIB');
$data = snmpwalk_group($device, 'ttMonLatestOper', 'CISCO-RTTMON-MIB', 1, $data);
$time_offset = time() - $this->getDevice()->uptime;
foreach ($slas as $sla) {
$sla_id = $sla->sla_id;
$sla_nr = $sla->sla_nr;
$rtt_type = $sla->rtt_type;
// Lets process each SLA
$unixtime = intval(($data[$sla_nr]['rttMonLatestRttOperTime'] / 100 + $time_offset));
$time = strftime('%Y-%m-%d %H:%M:%S', $unixtime);
// Save data
$sla->rtt = $data[$sla_nr]['rttMonLatestRttOperCompletionTime'];
// Use Nagios Status codes. 0: Good, 2: Critical
$sla->opstatus = $data[$sla_nr]['rttMonLatestRttOperSense'] == 1 ? 0 : 2;
echo 'SLA ' . $sla_nr . ': ' . $rtt_type . ' ' . $sla['owner'] . ' ' . $sla['tag'] . '... ' . $sla->rtt . 'ms at ' . $time . "\n";
$fields = [
'rtt' => $sla->rtt,
];
// The base RRD
$rrd_name = ['sla', $sla['sla_nr']];
$rrd_def = RrdDefinition::make()->addDataset('rtt', 'GAUGE', 0, 300000);
$tags = compact('sla_nr', 'rrd_name', 'rrd_def');
data_update($device, 'sla', $tags, $fields);
// Let's gather some per-type fields.
switch ($rtt_type) {
case 'jitter':
$jitter = [
'PacketLossSD' => $data[$sla_nr]['rttMonLatestJitterOperPacketLossSD'],
'PacketLossDS' => $data[$sla_nr]['rttMonLatestJitterOperPacketLossDS'],
'PacketOutOfSequence' => $data[$sla_nr]['rttMonLatestJitterOperPacketOutOfSequence'],
'PacketMIA' => $data[$sla_nr]['rttMonLatestJitterOperPacketMIA'],
'PacketLateArrival' => $data[$sla_nr]['rttMonLatestJitterOperPacketLateArrival'],
'MOS' => isset($data[$sla_nr]['rttMonLatestJitterOperMOS']) ? intval($data[$sla_nr]['rttMonLatestJitterOperMOS']) / 100 : null,
'ICPIF' => $data[$sla_nr]['rttMonLatestJitterOperICPIF'] ?? null,
'OWAvgSD' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgSD'] ?? null,
'OWAvgDS' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgDS'] ?? null,
'AvgSDJ' => $data[$sla_nr]['rttMonLatestJitterOperAvgSDJ'] ?? null,
'AvgDSJ' => $data[$sla_nr]['rttMonLatestJitterOperAvgDSJ'] ?? null,
];
$rrd_name = ['sla', $sla_nr, $rtt_type];
$rrd_def = RrdDefinition::make()
->addDataset('PacketLossSD', 'GAUGE', 0)
->addDataset('PacketLossDS', 'GAUGE', 0)
->addDataset('PacketOutOfSequence', 'GAUGE', 0)
->addDataset('PacketMIA', 'GAUGE', 0)
->addDataset('PacketLateArrival', 'GAUGE', 0)
->addDataset('MOS', 'GAUGE', 0)
->addDataset('ICPIF', 'GAUGE', 0)
->addDataset('OWAvgSD', 'GAUGE', 0)
->addDataset('OWAvgDS', 'GAUGE', 0)
->addDataset('AvgSDJ', 'GAUGE', 0)
->addDataset('AvgDSJ', 'GAUGE', 0);
$tags = compact('rrd_name', 'rrd_def', 'sla_nr', 'rtt_type');
data_update($device, 'sla', $tags, $jitter);
$fields = array_merge($fields, $jitter);
break;
case 'icmpjitter':
$icmpjitter = [
'PacketLoss' => $data[$sla_nr]['rttMonLatestJitterOperPacketLossSD'],
'PacketOosSD' => $data[$sla_nr]['rttMonLatestJitterOperPacketOutOfSequence'],
'PacketOosDS' => $data[$sla_nr]['rttMonLatestJitterOperPacketMIA'],
'PacketLateArrival' => $data[$sla_nr]['rttMonLatestJitterOperPacketLateArrival'],
'JitterAvgSD' => $data[$sla_nr]['rttMonLatestJitterOperAvgSDJ'],
'JitterAvgDS' => $data[$sla_nr]['rttMonLatestJitterOperAvgDSJ'],
'LatencyOWAvgSD' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgSD'],
'LatencyOWAvgDS' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgDS'],
'JitterIAJOut' => $data[$sla_nr]['rttMonLatestJitterOperIAJOut'],
'JitterIAJIn' => $data[$sla_nr]['rttMonLatestJitterOperIAJIn'],
];
$rrd_name = ['sla', $sla_nr, $rtt_type];
$rrd_def = RrdDefinition::make()
->addDataset('PacketLoss', 'GAUGE', 0)
->addDataset('PacketOosSD', 'GAUGE', 0)
->addDataset('PacketOosDS', 'GAUGE', 0)
->addDataset('PacketLateArrival', 'GAUGE', 0)
->addDataset('JitterAvgSD', 'GAUGE', 0)
->addDataset('JitterAvgDS', 'GAUGE', 0)
->addDataset('LatencyOWAvgSD', 'GAUGE', 0)
->addDataset('LatencyOWAvgDS', 'GAUGE', 0)
->addDataset('JitterIAJOut', 'GAUGE', 0)
->addDataset('JitterIAJIn', 'GAUGE', 0);
$tags = compact('rrd_name', 'rrd_def', 'sla_nr', 'rtt_type');
data_update($device, 'sla', $tags, $icmpjitter);
$fields = array_merge($fields, $icmpjitter);
break;
}
d_echo('The following datasources were collected for #' . $sla['sla_nr'] . ":\n");
d_echo($fields);
}
}
protected function getMainSerial()
{
$serial_output = snmp_get_multi($this->getDeviceArray(), ['entPhysicalSerialNum.1', 'entPhysicalSerialNum.1001'], '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB');