Discovery - Refactor num_oid computing (#12576)

* Test the num_oid generation

* Refactor num_oid discovery

* cnt

* Cache the value to avoid unnecessary snmptranslate

* desc of function

* typo

* Negative caching as well

* Negative caching

* style

* Str::before

* Str::before

* Str::before

* Fix key,  and model Devices

* types

* types

* doc update

* re-run tests

* Use Cache class

* Simplify caching and do it into oidToNumeric

* Simplify caching and do it into oidToNumeric

* style

* Extend to 3 hours

* and not ->cache_time

* force re-run tests

* only one OID for num_oid test

* rerun tests

* typo in MD

* restore

* Exemple

* Exemple

* light change

* test

* test

* test

* back to PR

* phpstan + suggestions from Tony

* fix firebrick num_oid

Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
PipoCanaja
2021-04-22 21:40:45 +02:00
committed by GitHub
parent d32e62479e
commit 07900ccc08
5 changed files with 75 additions and 36 deletions

View File

@@ -24,6 +24,7 @@
namespace LibreNMS\Device;
use Cache;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use LibreNMS\Exceptions\InvalidOidException;
@@ -32,6 +33,8 @@ use LibreNMS\OS;
class YamlDiscovery
{
private static $cache_time = 1800; // 30 min, Used for oid translation cache
/**
* @param OS $os
* @param DiscoveryItem|string $class
@@ -85,16 +88,7 @@ class YamlDiscovery
// determine numeric oid automatically if not specified
if (! isset($data['num_oid'])) {
try {
d_echo('Info: Trying to find a numerical OID for ' . $data['value'] . '.');
$search_mib = $device['dynamic_discovery']['mib'];
if (Str::contains($data['oid'], '::') && ! (Str::contains($data['value'], '::'))) {
// We should search this mib first
$exp_oid = explode('::', $data['oid']);
$search_mib = $exp_oid[0] . ':' . $search_mib;
}
$num_oid = static::oidToNumeric($data['value'], $device, $search_mib, $device['mib_dir']);
$data['num_oid'] = $num_oid . '.{{ $index }}';
d_echo('Info: We found numerical oid for ' . $data['value'] . ': ' . $data['num_oid']);
$data['num_oid'] = static::computeNumericalOID($device, $data);
} catch (\Exception $e) {
d_echo('Error: We cannot find a numerical OID for ' . $data['value'] . '. Skipping this one...');
continue;
@@ -129,6 +123,32 @@ class YamlDiscovery
return $items;
}
/**
* @param array $device Device we are working on
* @param array $data Array derived from YAML
* @return string
*/
public static function computeNumericalOID($device, $data)
{
d_echo('Info: Trying to find a numerical OID for ' . $data['value'] . '.');
$search_mib = $device['dynamic_discovery']['mib'];
$mib_prefix_data_oid = Str::before($data['oid'], '::');
if (! empty($mib_prefix_data_oid) && empty(Str::before($data['value'], '::'))) {
// We should search value in this mib first, as it is explicitely specified
$search_mib = $mib_prefix_data_oid . ':' . $search_mib;
}
try {
$num_oid = static::oidToNumeric($data['value'], $device, $search_mib, $device['mib_dir']);
} catch (\Exception $e) {
throw $e;
}
d_echo('Info: We found numerical oid for ' . $data['value'] . ': ' . $num_oid);
return $num_oid . '.{{ $index }}';
}
/**
* @param string $name Name of the field in yaml
* @param string $index index in the snmp table
@@ -192,7 +212,7 @@ class YamlDiscovery
$name = $discovery_data[$name];
}
if (isset($pre_cache[$discovery_data['oid']][$index][$name])) {
if (! is_array($discovery_data['oid']) && isset($pre_cache[$discovery_data['oid']][$index]) && isset($pre_cache[$discovery_data['oid']][$index][$name])) {
return $pre_cache[$discovery_data['oid']][$index][$name];
}
@@ -356,13 +376,21 @@ class YamlDiscovery
if (self::oidIsNumeric($oid)) {
return $oid;
}
foreach (explode(':', $mib) as $mib_name) {
if ($numeric_oid = snmp_translate($oid, $mib_name, $mibdir, null, $device)) {
break;
$key = 'YamlDiscovery:oidToNumeric:' . $mibdir . '/' . $mib . '/' . $oid;
if (Cache::has($key)) {
$numeric_oid = Cache::get($key);
} else {
foreach (explode(':', $mib) as $mib_name) {
$numeric_oid = snmp_translate($oid, $mib_name, $mibdir, null, $device);
if ($numeric_oid) {
break;
}
}
}
//Store the value
Cache::put($key, $numeric_oid, self::$cache_time);
if (empty($numeric_oid)) {
throw new InvalidOidException("Unable to translate oid $oid");
}