lnms snmp:translate always show textual and numeric translations (#16187)

* lnms snmp:translate always show textual and numeric translations
accept os name as device spec for translate
values output tidy up for translate and one result

* ingore phpstan
This commit is contained in:
Tony Murray
2024-07-09 12:04:18 -05:00
committed by GitHub
parent e083775e1d
commit 1baf8f4a1f
3 changed files with 52 additions and 39 deletions

View File

@@ -31,7 +31,7 @@ abstract class SnmpFetch extends LnmsCommand
parent::__construct();
$this->addArgument('device spec', InputArgument::REQUIRED, trans('commands.snmp:fetch.arguments.device spec'));
$this->addArgument('oid(s)', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, trans('commands.snmp:fetch.arguments.oid(s)'));
$this->addOption('output', 'o', InputOption::VALUE_REQUIRED, trans('commands.snmp:fetch.options.output', ['formats' => '[value, values, table]']));
$this->addOption('output', 'o', InputOption::VALUE_REQUIRED, trans('commands.snmp:fetch.options.output', ['formats' => '[value, values, table, index-table]']));
$this->addOption('depth', 'd', InputOption::VALUE_REQUIRED, trans('commands.snmp:fetch.options.depth'), 1);
$this->addOption('numeric', 'i', InputOption::VALUE_NONE, trans('commands.snmp:fetch.options.numeric'));
}
@@ -48,9 +48,13 @@ abstract class SnmpFetch extends LnmsCommand
$this->type = substr($this->name, 5); // 'snmp:<type>'
$this->deviceSpec = $this->argument('device spec');
$this->oids = $this->argument('oid(s)') ?: [];
$this->numeric = $this->option('numeric');
$this->outputFormat = $this->option('output') ?: ($this->type == 'walk' ? 'table' : 'value');
$this->numeric = $this->hasOption('numeric') ? $this->option('numeric') : null; // // @phpstan-ignore-line larastan.console.undefinedOption
$this->depth = (int) $this->option('depth');
$this->outputFormat = $this->option('output') ?: match ($this->type) {
'walk' => 'table',
'translate' => 'values',
default => 'value',
};
$devices = $this->getDevices();
@@ -63,15 +67,12 @@ abstract class SnmpFetch extends LnmsCommand
$return = 0;
foreach ($devices as $device) {
if ($device->exists) {
DeviceCache::setPrimary($device->device_id);
}
$device_name = $device->displayName();
if ($device_name) {
$this->info($device_name . ':');
}
$res = $this->fetchData();
$res = $this->fetchData($device);
if (! $res->isValid()) {
$this->warn(trans('commands.snmp:fetch.failed'));
@@ -88,14 +89,19 @@ abstract class SnmpFetch extends LnmsCommand
continue 2;
case 'values':
$values = [];
foreach ($res->values() as $oid => $value) {
$values[] = ["<fg=bright-blue>$oid</>", $value];
$values = array_map(fn ($value, $oid) => ["<fg=bright-blue>$oid</>", $value], $res->values(), array_keys($res->values()));
if (count($values) === 1) {
[$oid, $value] = array_pop($values);
$this->line("$oid = $value");
continue 2;
}
$this->table(
[trans('commands.snmp:fetch.oid'), trans('commands.snmp:fetch.value')],
$values
);
$headers = $this->type == 'translate'
? [__('commands.snmp:fetch.textual'), __('commands.snmp:fetch.numeric')]
: [__('commands.snmp:fetch.oid'), __('commands.snmp:fetch.value')];
$this->table($headers, $values);
continue 2;
case 'table':
@@ -152,12 +158,13 @@ abstract class SnmpFetch extends LnmsCommand
->map(fn ($device_id) => DeviceCache::get($device_id));
}
protected function fetchData(): SnmpResponse
protected function fetchData(Device $device): SnmpResponse
{
$type = $this->type;
return SnmpQuery::make()
->numeric($this->numeric)
->device($device)
->$type($this->oids);
}

View File

@@ -4,9 +4,8 @@ namespace App\Console\Commands;
use App\Models\Device;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use LibreNMS\Config;
use LibreNMS\Data\Source\SnmpResponse;
use LibreNMS\Util\Oid;
use SnmpQuery;
class SnmpTranslate extends SnmpFetch
@@ -14,6 +13,16 @@ class SnmpTranslate extends SnmpFetch
protected $name = 'snmp:translate';
protected array $oids;
public function __construct()
{
parent::__construct();
// remove numeric option as this shows both
$options = $this->getDefinition()->getOptions();
unset($options['numeric']);
$this->getDefinition()->setOptions($options);
}
protected function getDevices(): Collection
{
if (empty($this->oids)) {
@@ -23,37 +32,32 @@ class SnmpTranslate extends SnmpFetch
}
$devices = parent::getDevices();
if ($devices->isEmpty()) {
$this->oids = [$this->deviceSpec, ...$this->oids];
return new Collection([new Device]); // no device needed, supply dummy
if ($devices->isNotEmpty()) {
return $devices;
}
return $devices;
// check if the "device" is an valid os, if it is, use that for the dummy device
\LibreNMS\Util\OS::loadDefinition($this->deviceSpec);
if (Config::has('os.' . $this->deviceSpec)) {
return new Collection([new Device(['os' => $this->deviceSpec])]);
}
$this->oids = [$this->deviceSpec, ...$this->oids];
// no device needed, supply dummy
return new Collection([new Device]);
}
protected function fetchData(): SnmpResponse
protected function fetchData($device): SnmpResponse
{
$res = new SnmpResponse('');
// translate does not support multiple oids (should it?)
foreach ($this->oids as $oid) {
if (Oid::isNumeric($oid)) {
$translated = SnmpQuery::numeric(false)->mibs(['ALL'])->translate($oid);
$response = new SnmpResponse($translated . PHP_EOL);
$res = $res->append($response);
$textual = SnmpQuery::numeric(false)->device($device)->mibs(['ALL'])->translate($oid);
$numeric = SnmpQuery::numeric(true)->device($device)->mibs(['ALL'])->translate($oid);
continue;
}
$translated = SnmpQuery::numeric($this->numeric)->translate($oid);
// if we got the same back (ignoring . prefix) swap numeric
if (empty($translated) || Str::start($oid, '.') == Str::start($translated, '.')) {
$translated = SnmpQuery::numeric(! $this->numeric)->translate($oid);
}
$res = $res->append(new SnmpResponse($translated . PHP_EOL));
$response = new SnmpResponse("$textual = $numeric\n");
$res = $res->append($response);
}
return $res;

View File

@@ -234,6 +234,7 @@ return [
'oid(s)' => 'One or more SNMP OID to fetch. Should be either MIB::oid or a numeric oid',
],
'failed' => 'SNMP command failed!',
'numeric' => 'Numeric',
'oid' => 'OID',
'options' => [
'output' => 'Specify the output format :formats',
@@ -241,6 +242,7 @@ return [
'depth' => 'Depth to group the snmp table at. Usually the same number as the items in the index of the table',
],
'not_found' => 'Device not found',
'textual' => 'Textual',
'value' => 'Value',
],
'translation:generate' => [