mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Allow SnmpQuery to optionally abort walks if one fails (#14255)
* Allow SnmpQuery to optionally abort walks if one fails * style * remove baseline
This commit is contained in:
@@ -87,6 +87,10 @@ class NetSnmpQuery implements SnmpQueryInterface
|
||||
* @var \App\Models\Device
|
||||
*/
|
||||
private $device;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $abort = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -159,6 +163,17 @@ class NetSnmpQuery implements SnmpQueryInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When walking multiple OIDs, stop if one fails. Used when the first OID indicates if the rest are supported.
|
||||
* OIDs will be walked in order, so you may want to put your OIDs in a specific order.
|
||||
*/
|
||||
public function abortOnFailure(): SnmpQueryInterface
|
||||
{
|
||||
$this->abort = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not error on out of order indexes.
|
||||
* Use with caution as we could get stuck in an infinite loop.
|
||||
@@ -330,17 +345,20 @@ class NetSnmpQuery implements SnmpQueryInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function execMultiple(string $command, array $oids): ?SnmpResponse
|
||||
private function execMultiple(string $command, array $oids): SnmpResponse
|
||||
{
|
||||
$combined = null;
|
||||
$response = new SnmpResponse('');
|
||||
|
||||
foreach ($oids as $oid) {
|
||||
$response = $this->exec($command, [$oid]);
|
||||
$response = $response->append($this->exec($command, [$oid]));
|
||||
|
||||
$combined = $combined ? $combined->append($response) : $response;
|
||||
// if abort on failure is set, return after first failure
|
||||
if ($this->abort && ! $response->isValid()) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
return $combined;
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function exec(string $command, array $oids): SnmpResponse
|
||||
|
@@ -58,6 +58,12 @@ interface SnmpQueryInterface
|
||||
*/
|
||||
public function mibDir(?string $dir): SnmpQueryInterface;
|
||||
|
||||
/**
|
||||
* When walking multiple OIDs, stop if one fails. Used when the first OID indicates if the rest are supported.
|
||||
* OIDs will be walked in order, so you may want to put your OIDs in a specific order.
|
||||
*/
|
||||
public function abortOnFailure(): SnmpQueryInterface;
|
||||
|
||||
/**
|
||||
* Do not error on out of order indexes.
|
||||
* Use with caution as we could get stuck in an infinite loop.
|
||||
|
@@ -10835,11 +10835,6 @@ parameters:
|
||||
count: 1
|
||||
path: tests/MibTest.php
|
||||
|
||||
-
|
||||
message: "#^Property LibreNMS\\\\Tests\\\\Mocks\\\\SnmpQueryMock\\:\\:\\$context is never read, only written\\.$#"
|
||||
count: 1
|
||||
path: tests/Mocks/SnmpQueryMock.php
|
||||
|
||||
-
|
||||
message: "#^Method LibreNMS\\\\Tests\\\\OSDiscoveryTest\\:\\:checkOS\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
|
@@ -67,6 +67,10 @@ class SnmpQueryMock implements SnmpQueryInterface
|
||||
* @var array|mixed
|
||||
*/
|
||||
private $options = [];
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $abort = false;
|
||||
|
||||
public static function make(): SnmpQueryInterface
|
||||
{
|
||||
@@ -114,6 +118,13 @@ class SnmpQueryMock implements SnmpQueryInterface
|
||||
->translate($oid, $mib);
|
||||
}
|
||||
|
||||
public function abortOnFailure(): SnmpQueryInterface
|
||||
{
|
||||
$this->abort = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allowUnordered(): SnmpQueryInterface
|
||||
{
|
||||
return $this;
|
||||
@@ -157,7 +168,7 @@ class SnmpQueryMock implements SnmpQueryInterface
|
||||
|
||||
public function get($oid): SnmpResponse
|
||||
{
|
||||
$community = $this->device->community;
|
||||
$community = $this->community();
|
||||
$num_oid = $this->translateNumber($oid);
|
||||
$data = $this->getSnmprec($community)[$num_oid] ?? [0, ''];
|
||||
|
||||
@@ -166,27 +177,43 @@ class SnmpQueryMock implements SnmpQueryInterface
|
||||
return new SnmpResponse($this->outputLine($oid, $num_oid, $data[0], $data[1]));
|
||||
}
|
||||
|
||||
public function walk($oid): SnmpResponse
|
||||
/**
|
||||
* @param array|string $oids
|
||||
* @return \LibreNMS\Data\Source\SnmpResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function walk($oids): SnmpResponse
|
||||
{
|
||||
$community = $this->device->community;
|
||||
$num_oid = $this->translateNumber($oid);
|
||||
$community = $this->community();
|
||||
$dev = $this->getSnmprec($community);
|
||||
$response = new SnmpResponse('');
|
||||
|
||||
$output = '';
|
||||
foreach ($dev as $key => $data) {
|
||||
if (Str::startsWith($key, $num_oid)) {
|
||||
$output .= $this->outputLine($oid, $num_oid, $data[0], $data[1]);
|
||||
foreach (Arr::wrap($oids) as $oid) {
|
||||
$num_oid = $this->translateNumber($oid);
|
||||
|
||||
$output = '';
|
||||
foreach ($dev as $key => $data) {
|
||||
if (Str::startsWith($key, $num_oid)) {
|
||||
$output .= $this->outputLine($oid, $num_oid, $data[0], $data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$response = $response->append(new SnmpResponse($output));
|
||||
|
||||
if ($this->abort && ! $response->isValid()) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
Log::debug("[SNMP] snmpwalk $community $num_oid");
|
||||
}
|
||||
|
||||
Log::debug("[SNMP] snmpwalk $community $num_oid");
|
||||
|
||||
return new SnmpResponse($output);
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function next($oid): SnmpResponse
|
||||
{
|
||||
$community = $this->device->community;
|
||||
$community = $this->community();
|
||||
$num_oid = $this->translateNumber($oid);
|
||||
$dev = $this->getSnmprec($community);
|
||||
|
||||
@@ -324,6 +351,17 @@ class SnmpQueryMock implements SnmpQueryInterface
|
||||
return ltrim($number, '.');
|
||||
}
|
||||
|
||||
private function community(): string
|
||||
{
|
||||
$community = $this->device->community;
|
||||
|
||||
if (! empty($this->context)) {
|
||||
$community .= '_' . $this->context;
|
||||
}
|
||||
|
||||
return $community;
|
||||
}
|
||||
|
||||
private function extractMib(string $oid): ?string
|
||||
{
|
||||
if (Str::contains($oid, '::')) {
|
||||
|
Reference in New Issue
Block a user