SnmpQuery, respect snmp.max_oid (#14894)

Previously, the code would query all the oids it received. Now it will split it up into multiple queries if too many are sent.

Prevents some devices snmp service from crashing.
This commit is contained in:
Tony Murray 2023-03-13 10:17:34 -05:00 committed by GitHub
parent 2a4c50ed19
commit d3f02e6bb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 15 deletions

View File

@ -250,11 +250,7 @@ class NetSnmpQuery implements SnmpQueryInterface
*/
public function get($oid): SnmpResponse
{
if (empty($oid)) {
return new SnmpResponse('');
}
return $this->exec('snmpget', $this->parseOid($oid));
return $this->execMultiple('snmpget', $this->limitOids($this->parseOid($oid)));
}
/**
@ -278,7 +274,7 @@ class NetSnmpQuery implements SnmpQueryInterface
*/
public function next($oid): SnmpResponse
{
return $this->exec('snmpgetnext', $this->parseOid($oid));
return $this->execMultiple('snmpgetnext', $this->limitOids($this->parseOid($oid)));
}
/**
@ -374,7 +370,7 @@ class NetSnmpQuery implements SnmpQueryInterface
$response = new SnmpResponse('');
foreach ($oids as $oid) {
$response = $response->append($this->exec($command, [$oid]));
$response = $response->append($this->exec($command, Arr::wrap($oid)));
// if abort on failure is set, return after first failure
if ($this->abort && ! $response->isValid()) {
@ -500,10 +496,20 @@ class NetSnmpQuery implements SnmpQueryInterface
Log::debug($error);
}
/**
* @param array|string $oid
*/
private function parseOid($oid): array
private function limitOids(array $oids): array
{
// get max oids per query device attrib > os setting > global setting
$configured_max = $this->device->getAttrib('snmp_max_oid') ?: Config::getOsSetting($this->device->os, 'snmp_max_oid', Config::get('snmp.max_oid', 10));
$max_oids = max($configured_max, 1); // 0 or less would break things.
if (count($oids) > $max_oids) {
return array_chunk($oids, $max_oids);
}
return $oids;
}
private function parseOid(array|string $oid): array
{
return is_string($oid) ? explode(' ', $oid) : $oid;
}

View File

@ -5,9 +5,9 @@ icon: hpe
group: hpe
mib_dir: hp
over:
- {graph: device_power, text: Power}
- {graph: device_power, text: Power}
- {graph: device_current, text: Current}
snmp_max_oid: '8'
snmp_max_oid: 8
discovery:
-
sysObjectID:

View File

@ -3,7 +3,7 @@ text: 'Tait TN Admin OS'
type: network
icon: tait
mib_dir: tait
snmp_max_oid: '1'
snmp_max_oid: 1
over:
- { graph: device_temperature, text: 'Temperature' }
discovery:

View File

@ -5280,6 +5280,13 @@
"type": "integer",
"units": "seconds"
},
"snmp.max_oid": {
"group": "poller",
"section": "snmp",
"order": 5,
"type": "integer",
"default": 10
},
"snmp.max_repeaters": {
"group": "poller",
"section": "snmp",

View File

@ -391,7 +391,8 @@
"type": "boolean"
},
"snmp_max_oid": {
"type": "string"
"type": "integer",
"minimum": 1
},
"ifXmcbc": {
"type": "boolean"

View File

@ -1413,6 +1413,10 @@ return [
'description' => 'Communities (priority)',
'help' => 'Enter community strings for v1 and v2c and order them as you want them to be tried',
],
'max_oid' => [
'description' => 'Max OIDs',
'help' => 'Maximum OIDs per query. Can be overriden at OS and device levels.',
],
'max_repeaters' => [
'description' => 'Max Repeaters',
'help' => 'Set repeaters to use for SNMP bulk requests',