Misc fixes 2 (#15190)

* Fix error when missing poller data

* Apparently impossible to detect regex without error, so require regex always.  Update docs.

* Apparently this adva code is garbage :D

* Missing count sensor type

* Processor handle missing input

* Handle missing ifName a little better

* Yep, ports module is a dumpster fire.  Attempt to clean up some.

* apparently os yaml trying to replace on non-existent fields

* Might as well define all sensor type units

* revert previous fix, real issue was vlans module does not have polling.
This commit is contained in:
Tony Murray
2023-08-13 11:43:52 -05:00
committed by GitHub
parent d865e3b372
commit 6e4d124619
10 changed files with 88 additions and 79 deletions

View File

@@ -119,19 +119,19 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover
public static function fromYaml(OS $os, $index, array $data)
{
$precision = $data['precision'] ?: 1;
$precision = empty($data['precision']) ? 1 : $data['precision'];
return static::discover(
$data['type'] ?: $os->getName(),
empty($data['type']) ? $os->getName() : $data['type'],
$os->getDeviceId(),
$data['num_oid'],
isset($data['index']) ? $data['index'] : $index,
$data['descr'] ? trim($data['descr']) : 'Processor',
empty($data['descr']) ? 'Processor' : trim($data['descr']),
$precision,
static::processData($data['value'], $precision),
$data['warn_percent'],
$data['entPhysicalIndex'],
$data['hrDeviceIndex']
$data['warn_percent'] ?? null,
$data['entPhysicalIndex'] ?? null,
$data['hrDeviceIndex'] ?? null
);
}

View File

@@ -164,11 +164,8 @@ trait YamlOSDiscovery
$replacement = $replacements[1];
}
// check for regex
if (preg_match($search, $device->$field)) {
if (isset($device->$field)) {
$device->$field = preg_replace($search, $replacement, $device->$field);
} else {
$device->$field = str_replace($search, $replacement, $device->$field);
}
}
}

View File

@@ -162,7 +162,7 @@ more complex collection is required.
- `<field>` specify an oid or list of oids to attempt to pull the data from, the first non-empty response will be used
- `<field>_regex` parse the value out of the returned oid data, must use a named group
- `<field>_template` combine multiple oid results together to create a final string value. The result is trimmed.
- `<field>_replace` An array of replacements ['find', 'replace'] or strings to remove
- `<field>_replace` An array of replacements ['search regex', 'replace'] or regex to remove
- `hardware_mib` MIB used to translate sysObjectID to get hardware. hardware_regex can process the result.
```yaml

View File

@@ -5,10 +5,10 @@ modules:
- '/^AIX .* (?<version>\d+ \d+) (?<serial>\S+)$/' # net-snmp daemon
serial: IBM-AIX-MIB::aixSeSerialNumber.0
serial_replace:
- 'IBM,'
- '/IBM,/'
hardware: IBM-AIX-MIB::aixSeMachineType.0
hardware_replace:
- 'IBM,'
- '/IBM,/'
version_replace:
- '/(?<=^|\.)0+(?=[^.])/' # standard snmp daemon
- ['/(\d+) (\d+)/', '$2.$1'] # net-snmp daemon

View File

@@ -26,9 +26,9 @@ modules:
- HP-SN-AGENT-MIB::snAgImgVer.0
serial: SEMI-MIB::hpHttpMgSerialNumber.0
hardware_replace:
- [' ', ' ']
- ' Switch'
- ' Stack'
- ['/ /', ' ']
- '/ Switch/'
- '/ Stack/'
processors:
data:
-

View File

@@ -88,7 +88,7 @@ $divisor = 1;
foreach (array_keys($pre_cache['adva_fsp150']) as $index) {
foreach ($sensors_adva as $entry) {
$sensor_name = $entry['sensor_name'];
if ($pre_cache['adva_fsp150'][$index][$sensor_name]) {
if (! empty($pre_cache['adva_fsp150'][$index][$sensor_name])) {
$oid = $entry['sensor_oid'] . '.' . $index;
$descr = $pre_cache['adva_fsp150'][$index]['slotCardUnitName'] . ' [#' . $pre_cache['adva_fsp150'][$index]['slotIndex'] . ']';
$current = $pre_cache['adva_fsp150'][$index][$entry['sensor_name']] / $divisor;
@@ -119,7 +119,7 @@ unset($sensors_adva, $entry);
// Adva FSP150 SFP DOM Temperature
foreach ($pre_cache['adva_fsp150_ports'] as $index => $entry) {
if ($entry['cmEthernetNetPortMediaType'] == 'fiber' && $entry['cmEthernetNetPortOperationalState'] == 'normal') {
if (isset($entry['cmEthernetNetPortMediaType']) && $entry['cmEthernetNetPortMediaType'] == 'fiber' && $entry['cmEthernetNetPortOperationalState'] == 'normal') {
$oid = '.1.3.6.1.4.1.2544.1.12.5.1.5.1.40.' . $index . '.3';
$current = $pre_cache['adva_fsp150_perfs'][$index . '.3']['cmEthernetNetPortStatsTemp'];
@@ -149,9 +149,9 @@ foreach ($pre_cache['adva_fsp150_ports'] as $index => $entry) {
}
}
if ($entry['cmEthernetAccPortMediaType'] && $entry['cmEthernetAccPortMediaType'] == 'fiber' && $entry['cmEthernetAccPortOperationalState'] == 'normal') {
if (isset($entry['cmEthernetAccPortMediaType']) && $entry['cmEthernetAccPortMediaType'] == 'fiber' && $entry['cmEthernetAccPortOperationalState'] == 'normal') {
$oid = '.1.3.6.1.4.1.2544.1.12.5.1.1.1.39.' . $index . '.3';
$current = $pre_cache['adva_fsp150_perfs'][$index . '.3']['cmEthernetAccPortStatsTemp'];
$current = $pre_cache['adva_fsp150_perfs'][$index . '.3']['cmEthernetAccPortStatsTemp'] ?? null;
if ($current != 0) {
$entPhysicalIndex = $entry['cmEthernetAccPortIfIndex'];
$entPhysicalIndex_measured = 'ports';
@@ -178,9 +178,9 @@ foreach ($pre_cache['adva_fsp150_ports'] as $index => $entry) {
}
}
if ($entry['cmEthernetTrafficPortMediaType'] == 'fiber' && $entry['cmEthernetTrafficPortOperationalState'] == 'normal') {
if (isset($entry['cmEthernetTrafficPortMediaType']) && $entry['cmEthernetTrafficPortMediaType'] == 'fiber' && $entry['cmEthernetTrafficPortOperationalState'] == 'normal') {
$oid = '.1.3.6.1.4.1.2544.1.12.5.1.21.1.41.' . $index . '.3';
$current = $pre_cache['adva_fsp150_perfs'][$index . '.3']['cmEthernetTrafficPortStatsTemp'];
$current = $pre_cache['adva_fsp150_perfs'][$index . '.3']['cmEthernetTrafficPortStatsTemp'] ?? null;
if ($current != 0) {
$entPhysicalIndex = $entry['cmEthernetTrafficPortIfIndex'];
$entPhysicalIndex_measured = 'ports';

View File

@@ -606,7 +606,7 @@ function is_port_valid($port, $device)
}
$ifDescr = $port['ifDescr'];
$ifName = $port['ifName'];
$ifName = $port['ifName'] ?? '';
$ifAlias = $port['ifAlias'] ?? '';
$ifType = $port['ifType'];
$ifOperStatus = $port['ifOperStatus'] ?? '';
@@ -676,15 +676,10 @@ function is_port_valid($port, $device)
*/
function port_fill_missing_and_trim(&$port, $device)
{
if (isset($port['ifDescr'])) {
$port['ifDescr'] = trim($port['ifDescr']);
}
if (isset($port['ifAlias'])) {
$port['ifAlias'] = trim($port['ifAlias']);
}
if (isset($port['ifName'])) {
$port['ifName'] = trim($port['ifName']);
}
$port['ifDescr'] = isset($port['ifDescr']) ? trim($port['ifDescr']) : null;
$port['ifAlias'] = isset($port['ifAlias']) ? trim($port['ifAlias']) : null;
$port['ifName'] = isset($port['ifName']) ? trim($port['ifName']) : null;
// When devices do not provide data, populate with other data if available
if (! isset($port['ifDescr']) || $port['ifDescr'] == '') {
$port['ifDescr'] = $port['ifName'];

View File

@@ -137,23 +137,36 @@ function poll_sensor($device, $class)
function record_sensor_data($device, $all_sensors)
{
$supported_sensors = [
'current' => 'A',
'frequency' => 'Hz',
'runtime' => 'Min',
'humidity' => '%',
'fanspeed' => 'rpm',
'power' => 'W',
'voltage' => 'V',
'temperature' => 'C',
'dbm' => 'dBm',
'charge' => '%',
'load' => '%',
'state' => '#',
'signal' => 'dBm',
'airflow' => 'cfm',
'snr' => 'SNR',
'pressure' => 'kPa',
'cooling' => 'W',
'airflow' => 'cfm',
'ber' => '',
'bitrate' => 'bps',
'charge' => '%',
'chromatic_dispersion' => 'ps/nm',
'cooling' => 'W',
'count' => '',
'current' => 'A',
'delay' => 's',
'dbm' => 'dBm',
'eer' => 'eer',
'fanspeed' => 'rpm',
'frequency' => 'Hz',
'humidity' => '%',
'load' => '%',
'loss' => '%',
'percent' => '%',
'power' => 'W',
'power_consumed' => 'kWh',
'power_factor' => '',
'pressure' => 'kPa',
'quality_factor' => 'dB',
'runtime' => 'Min',
'signal' => 'dBm',
'snr' => 'SNR',
'state' => '#',
'temperature' => 'C',
'tv_signal' => 'dBmV',
'voltage' => 'V',
'waterflow' => 'l/m',
];
foreach ($all_sensors as $sensor) {

View File

@@ -286,7 +286,7 @@ if ($device['os'] === 'f5' && (version_compare($device['version'], '11.2.0', '>=
echo 'Full ports polling ';
// For devices that are on the bad_ifXentry list, try fetching ifAlias to have nice interface descriptions.
if (! in_array(strtolower($device['hardware']), array_map('strtolower', (array) Config::getOsSetting($device['os'], 'bad_ifXEntry', [])))) {
if (! in_array(strtolower($device['hardware'] ?? ''), array_map('strtolower', (array) Config::getOsSetting($device['os'], 'bad_ifXEntry', [])))) {
$port_stats = snmpwalk_cache_oid($device, 'ifXEntry', $port_stats, 'IF-MIB');
} else {
$port_stats = snmpwalk_cache_oid($device, 'ifAlias', $port_stats, 'IF-MIB', null, '-OQUst');
@@ -458,7 +458,7 @@ $ports_found = [];
foreach ($port_stats as $ifIndex => $port) {
// Store ifIndex in port entry and prefetch ifName as we'll need it multiple times
$port['ifIndex'] = $ifIndex;
$ifName = $port['ifName'];
$ifName = $port['ifName'] ?? null;
// Get port_id according to port_association_mode used for this device
$port_id = get_port_id($ports_mapped, $port, $port_association_mode);
@@ -519,7 +519,7 @@ foreach ($port_stats as $ifIndex => $port) {
/* Build a list of all ports, identified by their port_id, found within this poller run. */
$ports_found[] = $port_id;
} elseif (empty($ports[$port_id]['skipped'])) {
} elseif ($port_id && empty($ports[$port_id]['skipped'])) {
// Port vanished (mark as deleted) (except when skipped by selective port polling)
if ($ports[$port_id]['deleted'] != '1') {
dbUpdate(['deleted' => '1'], 'ports', '`port_id` = ?', [$port_id]);
@@ -664,6 +664,7 @@ foreach ($ports as $port) {
// Update IF-MIB data
$tune_port = false;
foreach ($data_oids as $oid) {
$current_oid = $this_port[$oid] ?? null;
if ($oid == 'ifAlias') {
if (! empty($device['attribs']['ifName:' . $port['ifName']])) {
$this_port['ifAlias'] = $port['ifAlias'];
@@ -677,16 +678,16 @@ foreach ($ports as $port) {
}
}
if ($port[$oid] != $this_port[$oid] && ! isset($this_port[$oid])) {
if ($port[$oid] != $current_oid && ! isset($current_oid)) {
$port['update'][$oid] = ['NULL'];
log_event($oid . ': ' . $port[$oid] . ' -> NULL', $device, 'interface', 4, $port['port_id']);
d_echo($oid . ': ' . $port[$oid] . ' -> NULL ', $oid . ' ');
} elseif ($port[$oid] != ($this_port[$oid] ?? null)) {
} elseif ($port[$oid] != $current_oid) {
// if the value is different, update it
// rrdtune if needed
$port_tune = $device['attribs']['ifName_tune:' . $port['ifName']];
$device_tune = $device['attribs']['override_rrdtool_tune'];
$port_tune = $device['attribs']['ifName_tune:' . $port['ifName']] ?? null;
$device_tune = $device['attribs']['override_rrdtool_tune'] ?? null;
if ($port_tune == 'true' ||
($device_tune == 'true' && $port_tune != 'false') ||
(Config::get('rrdtool_tune') == 'true' && $port_tune != 'false' && $device_tune != 'false')) {
@@ -696,7 +697,7 @@ foreach ($ports as $port) {
}
// set the update data
$port['update'][$oid] = $this_port[$oid];
$port['update'][$oid] = $current_oid;
// store the previous values for alerting
if (in_array($oid, ['ifOperStatus', 'ifAdminStatus', 'ifSpeed'])) {
@@ -705,10 +706,10 @@ foreach ($ports as $port) {
if ($oid == 'ifSpeed') {
$old = Number::formatSi($port[$oid], 2, 3, 'bps');
$new = Number::formatSi($this_port[$oid], 2, 3, 'bps');
$new = Number::formatSi($current_oid, 2, 3, 'bps');
} else {
$old = $port[$oid];
$new = $this_port[$oid];
$new = $current_oid;
}
log_event($oid . ': ' . $old . ' -> ' . $new, $device, 'interface', 3, $port['port_id']);
@@ -720,7 +721,7 @@ foreach ($ports as $port) {
} else {
if (in_array($oid, ['ifOperStatus', 'ifAdminStatus', 'ifSpeed'])) {
if ($port[$oid . '_prev'] == null) {
$port['update'][$oid . '_prev'] = $this_port[$oid];
$port['update'][$oid . '_prev'] = $current_oid;
}
}
}
@@ -767,19 +768,21 @@ foreach ($ports as $port) {
// End parse ifAlias
// Update IF-MIB metrics
$_stat_oids = array_merge($stat_oids_db, $stat_oids_db_extended);
$current_port_stats = ['ifInOctets_rate' => 0, 'ifOutOctets_rate' => 0];
foreach ($_stat_oids as $oid) {
$port_update = 'update';
$current_oid = $this_port[$oid] ?? null;
$extended_metric = ! in_array($oid, $stat_oids_db, true);
if ($extended_metric) {
$port_update = 'update_extended';
}
$port[$port_update][$oid] = set_numeric($this_port[$oid] ?? 0);
$port[$port_update][$oid] = set_numeric($current_oid ?? 0);
$port[$port_update][$oid . '_prev'] = set_numeric($port[$oid] ?? null);
$oid_prev = $oid . '_prev';
if (isset($port[$oid])) {
$oid_diff = (intval($this_port[$oid] ?? 0) - intval($port[$oid]));
$oid_diff = (intval($current_oid ?? 0) - intval($port[$oid]));
$oid_rate = ($oid_diff / $polled_period);
if ($oid_rate < 0) {
$oid_rate = '0';
@@ -787,8 +790,8 @@ foreach ($ports as $port) {
echo "negative $oid";
}
$port['stats'][$oid . '_rate'] = $oid_rate;
$port['stats'][$oid . '_diff'] = $oid_diff;
$current_port_stats[$oid . '_rate'] = $oid_rate;
$current_port_stats[$oid . '_diff'] = $oid_diff;
$port[$port_update][$oid . '_rate'] = $oid_rate;
$port[$port_update][$oid . '_delta'] = $oid_diff;
@@ -798,23 +801,23 @@ foreach ($ports as $port) {
if (Config::get('debug_port.' . $port['port_id'])) {
$port_debug = $port['port_id'] . '|' . $polled . '|' . $polled_period . '|' . $this_port['ifHCInOctets'] . '|' . $this_port['ifHCOutOctets'];
$port_debug .= '|' . $port['stats']['ifInOctets_rate'] . '|' . $port['stats']['ifOutOctets_rate'] . "\n";
$port_debug .= '|' . $current_port_stats['ifInOctets_rate'] . '|' . $current_port_stats['ifOutOctets_rate'] . "\n";
file_put_contents('/tmp/port_debug.txt', $port_debug, FILE_APPEND);
echo 'Wrote port debugging data';
}
$port['stats']['ifInBits_rate'] = round($port['stats']['ifInOctets_rate'] * 8);
$port['stats']['ifOutBits_rate'] = round($port['stats']['ifOutOctets_rate'] * 8);
$current_port_stats['ifInBits_rate'] = round($current_port_stats['ifInOctets_rate'] * 8);
$current_port_stats['ifOutBits_rate'] = round($current_port_stats['ifOutOctets_rate'] * 8);
// If we have a valid ifSpeed we should populate the stats for checking
if (is_numeric($this_port['ifSpeed']) && $this_port['ifSpeed'] > 0) {
$port['stats']['ifInBits_perc'] = Number::calculatePercent($port['stats']['ifInBits_rate'], $this_port['ifSpeed'], 0);
$port['stats']['ifOutBits_perc'] = Number::calculatePercent($port['stats']['ifOutBits_rate'], $this_port['ifSpeed'], 0);
$current_port_stats['ifInBits_perc'] = Number::calculatePercent($current_port_stats['ifInBits_rate'], $this_port['ifSpeed'], 0);
$current_port_stats['ifOutBits_perc'] = Number::calculatePercent($current_port_stats['ifOutBits_rate'], $this_port['ifSpeed'], 0);
}
echo 'bps(' . Number::formatSi($port['stats']['ifInBits_rate'], 2, 3, 'bps') . '/' . Number::formatSi($port['stats']['ifOutBits_rate'], 2, 3, 'bps') . ')';
echo 'bytes(' . Number::formatBi($port['stats']['ifInOctets_diff']) . '/' . Number::formatBi($port['stats']['ifOutOctets_diff']) . ')';
echo 'pkts(' . Number::formatSi($port['stats']['ifInUcastPkts_rate'], 2, 3, 'pps') . '/' . Number::formatSi($port['stats']['ifOutUcastPkts_rate'], 2, 3, 'pps') . ')';
echo 'bps(' . Number::formatSi($current_port_stats['ifInBits_rate'], 2, 3, 'bps') . '/' . Number::formatSi($current_port_stats['ifOutBits_rate'], 2, 3, 'bps') . ')';
echo 'bytes(' . Number::formatBi($current_port_stats['ifInOctets_diff'] ?? 0) . '/' . Number::formatBi($current_port_stats['ifOutOctets_diff'] ?? 0) . ')';
echo 'pkts(' . Number::formatSi($current_port_stats['ifInUcastPkts_rate'] ?? 0, 2, 3, 'pps') . '/' . Number::formatSi($current_port_stats['ifOutUcastPkts_rate'] ?? 0, 2, 3, 'pps') . ')';
// Update data stores
$rrd_name = Rrd::portName($port_id, '');
@@ -863,8 +866,8 @@ foreach ($ports as $port) {
$fields['ifOutOctets_rate'] = $port['ifOutOctets_rate'];
// Add delta rate between current poll and last poll.
$fields['ifInBits_rate'] = $port['stats']['ifInBits_rate'];
$fields['ifOutBits_rate'] = $port['stats']['ifOutBits_rate'];
$fields['ifInBits_rate'] = $current_port_stats['ifInBits_rate'];
$fields['ifOutBits_rate'] = $current_port_stats['ifOutBits_rate'];
if ($tune_port === true) {
Rrd::tune('port', $rrdfile, $this_port['ifSpeed']);
@@ -885,11 +888,12 @@ foreach ($ports as $port) {
if (! empty($this_port['pagpOperationMode']) || ! empty($port['pagpOperationMode'])) {
foreach ($pagp_oids as $oid) {
// Loop the OIDs
if ($this_port[$oid] != $port[$oid]) {
$current_oid = $this_port[$oid] ?? null;
if ($current_oid != $port[$oid]) {
// If data has changed, build a query
$port['update'][$oid] = $this_port[$oid];
$port['update'][$oid] = $current_oid;
echo 'PAgP ';
log_event("$oid -> " . $this_port[$oid], $device, 'interface', 3, $port['port_id']);
log_event("$oid -> " . $current_oid, $device, 'interface', 3, $port['port_id']);
}
}
}

View File

@@ -123,8 +123,8 @@ class OSModulesTest extends DBTestCase
$actual = $results[$module]['discovery'] ?? [];
$this->checkTestData($expected, $actual, 'Discovered', $os, $module, $filename, $helper, $phpunit_debug);
if ($module === 'route') {
// no route poller module
// modules without polling
if (in_array($module, ['route', 'vlans'])) {
continue;
}