mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
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:
@@ -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");
|
||||
}
|
||||
|
@@ -88,8 +88,9 @@ are as follows:
|
||||
- `oid` (required): This is the name of the table you want to do the snmp walk on.
|
||||
- `value` (optional): This is the key within the table that contains
|
||||
the value. If not provided willuse `oid`
|
||||
- `num_oid` (optional): If not provided, this parameter should be computed
|
||||
automatically by discovery process. This is the numerical OID that contains
|
||||
- `num_oid` (required for PullRequests): If not provided, this parameter should be computed
|
||||
automatically by discovery process. This parameter is still required to
|
||||
submit a pull request. This is the numerical OID that contains
|
||||
`value`. This should usually include `{{ $index }}`.
|
||||
In case the index is a string, `{{ $index_string }}` can be used instead.
|
||||
- `divisor` (optional): This is the divisor to use against the returned `value`.
|
||||
@@ -163,13 +164,13 @@ the variable name. Example `{{ $ifName:2 }}`
|
||||
value: 1
|
||||
```
|
||||
|
||||
> ``` op ``` can be any of the following operators :
|
||||
>
|
||||
`op` can be any of the following operators :
|
||||
|
||||
> =, !=, ==, !==, <=, >=, <, >,
|
||||
> starts, ends, contains, regex, in_array, not_starts,
|
||||
> not_ends, not_contains, not_regex, not_in_array, exists
|
||||
>
|
||||
> Example:
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
skip_values:
|
||||
@@ -187,6 +188,21 @@ the variable name. Example `{{ $ifName:2 }}`
|
||||
value: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
temperature:
|
||||
data:
|
||||
-
|
||||
oid: hwOpticalModuleInfoTable
|
||||
value: hwEntityOpticalTemperature
|
||||
descr: '{{ $entPhysicalName }}'
|
||||
index: '{{ $index }}'
|
||||
skip_values:
|
||||
-
|
||||
oid: hwEntityOpticalMode
|
||||
op: '='
|
||||
value: '1'
|
||||
```
|
||||
|
||||
If you aren't able to use yaml to perform the sensor discovery, you
|
||||
will most likely need to use Advanced health discovery.
|
||||
|
||||
|
@@ -14,6 +14,7 @@ modules:
|
||||
-
|
||||
oid: fbMonitoringMib
|
||||
value: fbMonReadingValue
|
||||
num_oid: '.1.3.6.1.4.1.24693.100.1.1.1.4.{{ $index }}'
|
||||
descr: 'fbMonReadingName'
|
||||
index: 'fbMonReadingValue.{{ $index }}'
|
||||
low_limit: 1000
|
||||
|
@@ -886,9 +886,9 @@ function discovery_process(&$valid, $device, $sensor_class, $pre_cache)
|
||||
$user_function = $data['user_func'];
|
||||
}
|
||||
// get the value for this sensor, check 'value' and 'oid', if state string, translate to a number
|
||||
$data_name = isset($data['value']) ? $data['value'] : $data['oid']; // fallback to oid if value is not set
|
||||
$data['value'] = isset($data['value']) ? $data['value'] : $data['oid']; // fallback to oid if value is not set
|
||||
|
||||
$snmp_value = $snmp_data[$data_name];
|
||||
$snmp_value = $snmp_data[$data['value']];
|
||||
if (! is_numeric($snmp_value)) {
|
||||
if ($sensor_class === 'temperature') {
|
||||
// For temp sensors, try and detect fahrenheit values
|
||||
@@ -917,20 +917,11 @@ function discovery_process(&$valid, $device, $sensor_class, $pre_cache)
|
||||
// Check if we have a "num_oid" value. If not, we'll try to compute it from textual OIDs with snmptranslate.
|
||||
if (empty($data['num_oid'])) {
|
||||
try {
|
||||
d_echo('Info: Trying to find a numerical OID for ' . $data_name . '.');
|
||||
$search_mib = $device['dynamic_discovery']['mib'];
|
||||
if (Str::contains($data['oid'], '::') && ! (Str::contains($data_name, '::'))) {
|
||||
// We should search this mib first
|
||||
$exp_oid = explode('::', $data['oid']);
|
||||
$search_mib = $exp_oid[0] . ':' . $search_mib;
|
||||
}
|
||||
$num_oid = YamlDiscovery::oidToNumeric($data_name, $device, $search_mib, $device['mib_dir']);
|
||||
$data['num_oid'] = $num_oid . '.{{ $index }}';
|
||||
d_echo('Info: We found numerical oid for ' . $data_name . ': ' . $data['num_oid']);
|
||||
$data['num_oid'] = YamlDiscovery::computeNumericalOID($device, $data);
|
||||
} catch (\Exception $e) {
|
||||
d_echo('Error: We cannot find a numerical OID for ' . $data_name . '. Skipping this one...');
|
||||
d_echo('Error: We cannot find a numerical OID for ' . $data['value'] . '. Skipping this one...');
|
||||
$skippedFromYaml = true;
|
||||
// Cause we still don't have a num_oid
|
||||
// Because we don't have a num_oid, we have no way to add this sensor.
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -170,7 +170,8 @@
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"oid"
|
||||
"oid",
|
||||
"num_oid"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -278,6 +279,7 @@
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"descr",
|
||||
"num_oid",
|
||||
"oid",
|
||||
"states"
|
||||
]
|
||||
@@ -444,6 +446,7 @@
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"descr",
|
||||
"num_oid",
|
||||
"oid"
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user