Skip to content

Commit

Permalink
collect-snmp-data.php can now capture snmp context test data (librenm…
Browse files Browse the repository at this point in the history
…s#13596)

* collect-snmp-data.php can now capture snmp context test data
This is helpful for devices that use context for multiple data sets such as VLANs and VRFs.  Allows us to test things that use those now, but does make more snmprec files :/

* update typehints on affected methods and baseline
  • Loading branch information
murrant authored Dec 3, 2021
1 parent ef8dd82 commit b325242
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 77 deletions.
74 changes: 43 additions & 31 deletions LibreNMS/Util/ModuleTestHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function setJsonSavePath($path)
$this->json_file = $path;
}

public function captureFromDevice($device_id, $write = true, $prefer_new = false, $full = false)
public function captureFromDevice(int $device_id, bool $prefer_new = false, bool $full = false): void
{
if ($full) {
$snmp_oids[] = [
Expand All @@ -159,27 +159,28 @@ public function captureFromDevice($device_id, $write = true, $prefer_new = false

DeviceCache::setPrimary($device_id);

$snmprec_data = [];
foreach ($snmp_oids as $oid_data) {
$this->qPrint(' ' . $oid_data['oid']);

$snmp_options = ['-OUneb', '-Ih', '-m', '+' . $oid_data['mib']];
if ($oid_data['method'] == 'walk') {
$data = \SnmpQuery::options($snmp_options)->mibDir($oid_data['mibdir'])->walk($oid_data['oid']);
} elseif ($oid_data['method'] == 'get') {
$data = \SnmpQuery::options($snmp_options)->mibDir($oid_data['mibdir'])->get($oid_data['oid']);
} elseif ($oid_data['method'] == 'getnext') {
$data = \SnmpQuery::options($snmp_options)->mibDir($oid_data['mibdir'])->next($oid_data['oid']);
}
foreach ($snmp_oids as $context => $context_oids) {
dump($context, $context_oids);
$snmprec_data = [];
foreach ($context_oids as $oid_data) {
$this->qPrint(' ' . $oid_data['oid']);

$snmp_options = ['-OUneb', '-Ih', '-m', '+' . $oid_data['mib']];
if ($oid_data['method'] == 'walk') {
$data = \SnmpQuery::options($snmp_options)->context($context)->mibDir($oid_data['mibdir'])->walk($oid_data['oid']);
} elseif ($oid_data['method'] == 'get') {
$data = \SnmpQuery::options($snmp_options)->context($context)->mibDir($oid_data['mibdir'])->get($oid_data['oid']);
} elseif ($oid_data['method'] == 'getnext') {
$data = \SnmpQuery::options($snmp_options)->context($context)->mibDir($oid_data['mibdir'])->next($oid_data['oid']);
}

if (isset($data) && $data->isValid()) {
$snmprec_data[] = $this->convertSnmpToSnmprec($data);
if (isset($data) && $data->isValid()) {
$snmprec_data[] = $this->convertSnmpToSnmprec($data);
}
}
}

$this->qPrint(PHP_EOL);

return $this->saveSnmprec($snmprec_data, $write, $prefer_new);
$this->saveSnmprec($snmprec_data, $context, true, $prefer_new);
}
}

private function collectOids($device_id)
Expand All @@ -194,7 +195,7 @@ private function collectOids($device_id)
$save_debug = Debug::isEnabled();
$save_vdebug = Debug::isVerbose();
Debug::set();
Debug::setVerbose(false);
Debug::setVerbose();
\Log::setDefaultDriver('console');
discover_device($device, $this->parseArgs('discovery'));
$poller = app(Poller::class, ['device_spec' => $device_id, 'module_override' => $this->modules]);
Expand All @@ -211,24 +212,26 @@ private function collectOids($device_id)
$collection_output = preg_replace('/\033\[[\d;]+m/', '', $collection_output);

// extract snmp queries
$snmp_query_regex = '/SNMP\[.*snmp(?:bulk)?([a-z]+)\' .+:HOSTNAME:[0-9]+\' \'(.+)\'\]/';
$snmp_query_regex = '/SNMP\[.*snmp(?:bulk)?([a-z]+)\' .+(udp|tcp|tcp6|udp6):[^:]+:[0-9]+\' \'(.+)\']/';
preg_match_all($snmp_query_regex, $collection_output, $snmp_matches);

// extract mibs and group with oids
$snmp_oids = [
$snmp_oids = [null => [
'sysDescr.0_get' => ['oid' => 'sysDescr.0', 'mib' => 'SNMPv2-MIB', 'method' => 'get'],
'sysObjectID.0_get' => ['oid' => 'sysObjectID.0', 'mib' => 'SNMPv2-MIB', 'method' => 'get'],
];
]];
foreach ($snmp_matches[0] as $index => $line) {
preg_match("/'-m' '\+?([a-zA-Z0-9:\-]+)'/", $line, $mib_matches);
$mib = $mib_matches[1];
preg_match("/'-M' '\+?([a-zA-Z0-9:\-\/]+)'/", $line, $mibdir_matches);
$mibdir = $mibdir_matches[1];
$method = $snmp_matches[1][$index];
$oids = explode("' '", trim($snmp_matches[2][$index]));
$oids = explode("' '", trim($snmp_matches[3][$index]));
preg_match("/('-c' '.*@([^']+)'|'-n' '([^']+)')/", $line, $context_matches);
$context = $context_matches[2] ?? $context_matches[3] ?? null;

foreach ($oids as $oid) {
$snmp_oids["{$oid}_$method"] = [
$snmp_oids[$context]["{$oid}_$method"] = [
'oid' => $oid,
'mib' => $mib,
'mibdir' => $mibdir,
Expand Down Expand Up @@ -453,10 +456,16 @@ private function getSnmprecType($text)
return $snmpTypes[$text];
}

private function saveSnmprec($data, $write = true, $prefer_new = false)
private function saveSnmprec(array $data, ?string $context = null, bool $write = true, bool $prefer_new = false): string
{
if (is_file($this->snmprec_file)) {
$existing_data = $this->indexSnmprec(explode(PHP_EOL, file_get_contents($this->snmprec_file)));
$filename = $this->snmprec_file;

if ($context) {
$filename = str_replace('.snmprec', '', $filename) . "@$context.snmprec";
}

if (is_file($filename)) {
$existing_data = $this->indexSnmprec(explode(PHP_EOL, file_get_contents($filename)));
} else {
$existing_data = [];
}
Expand All @@ -481,9 +490,12 @@ private function saveSnmprec($data, $write = true, $prefer_new = false)
$output = implode(PHP_EOL, $results) . PHP_EOL;

if ($write) {
$this->qPrint("\nUpdated snmprec data $this->snmprec_file\n");
$this->qPrint("\nVerify this file does not contain any private data before submitting!\n");
file_put_contents($this->snmprec_file, $output);
if (empty($results)) {
$this->qPrint("No data for $filename\n");
} else {
$this->qPrint("Saved snmprec data $filename\n");
file_put_contents($filename, $output);
}
}

return $output;
Expand Down
45 changes: 0 additions & 45 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5930,31 +5930,6 @@ parameters:
count: 1
path: LibreNMS/Util/Laravel.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:captureFromDevice\\(\\) has no return type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:captureFromDevice\\(\\) has parameter \\$device_id with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:captureFromDevice\\(\\) has parameter \\$full with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:captureFromDevice\\(\\) has parameter \\$prefer_new with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:captureFromDevice\\(\\) has parameter \\$write with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:cleanSnmprecData\\(\\) has no return type specified\\.$#"
count: 1
Expand Down Expand Up @@ -6060,26 +6035,6 @@ parameters:
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:saveSnmprec\\(\\) has no return type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:saveSnmprec\\(\\) has parameter \\$data with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:saveSnmprec\\(\\) has parameter \\$prefer_new with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:saveSnmprec\\(\\) has parameter \\$write with no type specified\\.$#"
count: 1
path: LibreNMS/Util/ModuleTestHelper.php

-
message: "#^Method LibreNMS\\\\Util\\\\ModuleTestHelper\\:\\:setJsonSavePath\\(\\) has no return type specified\\.$#"
count: 1
Expand Down
3 changes: 2 additions & 1 deletion scripts/collect-snmp-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@

echo 'Capturing Data: ';
\LibreNMS\Util\OS::updateCache(true); // Force update of OS Cache
$capture->captureFromDevice($device['device_id'], true, $prefer_new_snmprec, $full);
$capture->captureFromDevice($device['device_id'], $prefer_new_snmprec, $full);
echo "\nVerify these file(s) do not contain any private data before sharing!\n";
} catch (InvalidModuleException $e) {
echo $e->getMessage() . PHP_EOL;
}

0 comments on commit b325242

Please sign in to comment.