API: device_add support display field (#13846)

* API: device_add support display field
remove legacy code path
update docs
A few improvements to the new code too

* some fixes, port_association_mode was not available

* hand version -> snmpver translation
This commit is contained in:
Tony Murray
2022-03-15 06:54:02 -05:00
committed by GitHub
parent 369617ffa1
commit 8df92a5f2b
4 changed files with 67 additions and 59 deletions
+16 -5
View File
@@ -28,6 +28,7 @@ namespace App\Actions\Device;
use App\Models\Device;
use Illuminate\Support\Arr;
use LibreNMS\Config;
use LibreNMS\Enum\PortAssociationMode;
use LibreNMS\Exceptions\HostIpExistsException;
use LibreNMS\Exceptions\HostnameExistsException;
use LibreNMS\Exceptions\HostSysnameExistsException;
@@ -79,11 +80,7 @@ class ValidateDeviceAndCreate
}
$this->exceptIfHostnameExists();
// defaults
$this->device->os = $this->device->os ?: 'generic';
$this->device->status_reason = '';
$this->device->sysName = $this->device->sysName ?: $this->device->hostname;
$this->fillDefaults();
if (! $this->force) {
$this->exceptIfIpExists();
@@ -181,6 +178,20 @@ class ValidateDeviceAndCreate
}
}
private function fillDefaults(): void
{
$this->device->port = $this->device->port ?: Config::get('snmp.port', 161);
$this->device->transport = $this->device->transport ?: Config::get('snmp.transports.0', 'udp');
$this->device->poller_group = $this->device->poller_group ?: Config::get('default_poller_group', 0);
$this->device->os = $this->device->os ?: 'generic';
$this->device->status_reason = '';
$this->device->sysName = $this->device->sysName ?: $this->device->hostname;
$this->device->port_association_mode = $this->device->port_association_mode ?: Config::get('default_port_association_mode', 'ifIndex');
if (! is_int($this->device->port_association_mode)) {
$this->device->port_association_mode = PortAssociationMode::getId($this->device->port_association_mode) ?? 1;
}
}
/**
* @throws \LibreNMS\Exceptions\HostExistsException
*/
+3 -3
View File
@@ -57,15 +57,15 @@ class DeviceAdd extends LnmsCommand
$this->addOption('ping-fallback', 'b', InputOption::VALUE_NONE);
$this->addOption('port-association-mode', 'p', InputOption::VALUE_REQUIRED, null, Config::get('default_port_association_mode'));
$this->addOption('community', 'c', InputOption::VALUE_REQUIRED);
$this->addOption('transport', 't', InputOption::VALUE_REQUIRED, null, 'udp');
$this->addOption('port', 'r', InputOption::VALUE_REQUIRED, null, 161);
$this->addOption('transport', 't', InputOption::VALUE_REQUIRED, null, Config::get('snmp.transports.0', 'udp'));
$this->addOption('port', 'r', InputOption::VALUE_REQUIRED, null, Config::get('snmp.port', 161));
$this->addOption('security-name', 'u', InputOption::VALUE_REQUIRED, null, 'root');
$this->addOption('auth-password', 'A', InputOption::VALUE_REQUIRED);
$this->addOption('auth-protocol', 'a', InputOption::VALUE_REQUIRED, null, 'MD5');
$this->addOption('privacy-password', 'X', InputOption::VALUE_REQUIRED);
$this->addOption('privacy-protocol', 'x', InputOption::VALUE_REQUIRED, null, 'AES');
$this->addOption('ping-only', 'P', InputOption::VALUE_NONE);
$this->addOption('os', 'o', InputOption::VALUE_REQUIRED, null, 'ping');
$this->addOption('os', 'o', InputOption::VALUE_REQUIRED);
$this->addOption('hardware', 'w', InputOption::VALUE_REQUIRED);
$this->addOption('sysName', 's', InputOption::VALUE_REQUIRED);
}
+15 -6
View File
@@ -1129,20 +1129,28 @@ Output:
### `add_device`
Add a new device.
Add a new device. Most fields are optional. You may omit snmp
credentials to attempt each system credential in order. See snmp.version, snmp.community, and snmp.v3
To guarantee device is added, use force_add. This will skip checks
for duplicate device and snmp reachability, but not duplicate hostname.
Route: `/api/v0/devices`
Input (JSON):
- hostname: device hostname
- overwrite_ip: alternate polling IP. Will be use instead of hostname (optional)
- hostname (required): device hostname or IP
- display: A string to display as the name of this device, defaults to
hostname (or device_display_default setting). May be a simple
template using replacements: {{ $hostname }}, {{ $sysName }},
{{ $sysName_fallback }}, {{ $ip }}
- port: SNMP port (defaults to port defined in config).
- transport: SNMP protocol (defaults to transport defined in config).
- version: SNMP version to use, v1, v2c or v3. Defaults to v2c.
- snmpver: SNMP version to use, v1, v2c or v3. Defaults to v2c.
- port_association_mode: method to identify ports: ifIndex (default), ifName, ifDescr, ifAlias
- poller_group: This is the poller_group id used for distributed
poller setup. Defaults to 0.
- force_add: Force the device to be added regardless of it being able
- force_add: Set to true to force the device to be added regardless of it being able
to respond to snmp or icmp.
For SNMP v1 or v2c
@@ -1154,7 +1162,7 @@ For SNMP v3
- authlevel: SNMP authlevel (noAuthNoPriv, authNoPriv, authPriv).
- authname: SNMP Auth username
- authpass: SNMP Auth password
- authalgo: SNMP Auth algorithm (MD5, SHA)
- authalgo: SNMP Auth algorithm (MD5, SHA) (SHA-224, SHA-256, SHA-384, SHA-512 if supported by your server)
- cryptopass: SNMP Crypto Password
- cryptoalgo: SNMP Crypto algorithm (AES, DES)
@@ -1162,6 +1170,7 @@ For ICMP only
- snmp_disable: Boolean, set to true for ICMP only.
- os: OS short name for the device (defaults to ping).
- sysName: sysName for the device.
- hardware: Device hardware.
Example:
+33 -45
View File
@@ -12,6 +12,7 @@
* the source code distribution for details.
*/
use App\Actions\Device\ValidateDeviceAndCreate;
use App\Models\Availability;
use App\Models\Device;
use App\Models\DeviceGroup;
@@ -369,12 +370,8 @@ function list_devices(Illuminate\Http\Request $request)
function add_device(Illuminate\Http\Request $request)
{
// This will add a device using the data passed encoded with json
// FIXME: Execution flow through this function could be improved
$data = json_decode($request->getContent(), true);
$data = $request->json()->all();
$additional = [];
// keep scrutinizer from complaining about snmpver not being set for all execution paths
$snmpver = 'v2c';
if (empty($data)) {
return api_error(400, 'No information has been provided to add this new device');
}
@@ -382,54 +379,45 @@ function add_device(Illuminate\Http\Request $request)
return api_error(400, 'Missing the device hostname');
}
$hostname = $data['hostname'];
$port = $data['port'] ?: Config::get('snmp.port');
$transport = $data['transport'] ?: 'udp';
$poller_group = $data['poller_group'] ?: 0;
$force_add = $data['force_add'] ? true : false;
$snmp_disable = ($data['snmp_disable']);
if ($snmp_disable) {
$additional = [
'sysName' => $data['sysName'] ?: '',
'os' => $data['os'] ?: 'ping',
'hardware' => $data['hardware'] ?: '',
'snmp_disable' => 1,
];
} elseif ($data['version'] == 'v1' || $data['version'] == 'v2c') {
if ($data['community']) {
Config::set('snmp.community', [$data['community']]);
try {
$device = new Device(Arr::only($data, [
'hostname',
'display',
'overwrite_ip',
'port',
'transport',
'poller_group',
'snmpver',
'port_association_mode',
'community',
'authlevel',
'authname',
'authpass',
'authalgo',
'cryptopass',
'cryptoalgo',
]));
// uses different name in legacy call
if (! empty($data['version'])) {
$device->snmpver = $data['version'];
}
$snmpver = $data['version'];
} elseif ($data['version'] == 'v3') {
$v3 = [
'authlevel' => $data['authlevel'],
'authname' => $data['authname'],
'authpass' => $data['authpass'],
'authalgo' => $data['authalgo'],
'cryptopass' => $data['cryptopass'],
'cryptoalgo' => $data['cryptoalgo'],
];
if (! empty($data['snmp_disable'])) {
$device->os = $data['os'] ?? 'ping';
$device->sysName = $data['sysName'] ?? '';
$device->hardware = $data['hardware'] ?? '';
$device->snmp_disable = 1;
}
$v3_config = Config::get('snmp.v3');
array_unshift($v3_config, $v3);
Config::set('snmp.v3', $v3_config);
$snmpver = 'v3';
} else {
return api_error(400, 'You haven\'t specified an SNMP version to use');
}
$additional['overwrite_ip'] = $data['overwrite_ip'] ?: null;
try {
$device_id = addHost($hostname, $snmpver, $port, $transport, $poller_group, $force_add, 'ifIndex', $additional);
(new ValidateDeviceAndCreate($device, ! empty($data['force_add'])))->execute();
} catch (Exception $e) {
return api_error(500, $e->getMessage());
}
$device = device_by_id_cache($device_id);
$message = "Device $device->hostname ($device->device_id) has been added successfully";
return api_success([$device], 'devices', $response);
return api_success($device->attributesToArray(), 'devices', $message);
}
function del_device(Illuminate\Http\Request $request)