Remove legacy addhost code (#15376)

* Remove legacy addhost code
Update webui addhost
Update device snmp settings page
Update discovery protocols device discovery (no longer force full new device discovery in process)

* remove baseline exceptions

* Apply fixes from StyleCI

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
Tony Murray
2023-10-07 22:02:45 -05:00
committed by GitHub
parent 685d11d4f1
commit c87c6e8b8e
7 changed files with 126 additions and 526 deletions

View File

@@ -12,6 +12,7 @@
* See COPYING for more details.
*/
use App\Models\Eventlog;
use App\Models\Ipv6Address;
use App\Models\Ipv6Network;
use App\Models\Port;
@@ -26,7 +27,16 @@ use LibreNMS\Util\IP;
use LibreNMS\Util\IPv6;
use LibreNMS\Util\UserFuncHelper;
function discover_new_device($hostname, $device = [], $method = '', $interface = '')
/**
* @param string $hostname
* @param array $device
* @param string $method name of process discoverying this device
* @param array|null $interface Interface this device was discovered on
* @return false|int
*
* @throws InvalidIpException
*/
function discover_new_device($hostname, $device, $method, $interface = null)
{
d_echo("discovering $hostname\n");
@@ -77,25 +87,26 @@ function discover_new_device($hostname, $device = [], $method = '', $interface =
}
try {
$remote_device_id = addHost($hostname, '', '161', 'udp', $device['poller_group']); // discover with actual poller group
$remote_device = device_by_id_cache($remote_device_id, 1);
echo '+[' . $remote_device['hostname'] . '(' . $remote_device['device_id'] . ')]';
discover_device($remote_device);
device_by_id_cache($remote_device_id, 1);
$remote_device = new \App\Models\Device([
'hostname' => $hostname,
'poller_group' => $device['poller_group'],
]);
$result = \App\Actions\Device\ValidateDeviceAndCreate($remote_device)->execute();
if ($result) {
echo '+[' . $remote_device->hostname . '(' . $remote_device->device_id . ')]';
if ($remote_device_id && is_array($device) && ! empty($method)) {
$extra_log = is_array($interface) ? ' (port ' . cleanPort($interface)['label'] . ') ' : '';
Eventlog::log('Device ' . $remote_device->hostname . " ($ip) $extra_log autodiscovered through $method on " . $device['hostname'], $device['device_id'], 'discovery', Severity::Ok);
log_event('Device ' . $remote_device['hostname'] . " ($ip) $extra_log autodiscovered through $method on " . $device['hostname'], $remote_device_id, 'discovery', 1);
} else {
log_event("$method discovery of " . $remote_device['hostname'] . " ($ip) failed - Check ping and SNMP access", $device['device_id'], 'discovery', 5);
return $remote_device->device_id;
}
return $remote_device_id;
Eventlog::log("$method discovery of " . $remote_device->hostname . " ($ip) failed - Check ping and SNMP access", $device['device_id'], 'discovery', Severity::Error);
} catch (HostExistsException $e) {
// already have this device
} catch (Exception $e) {
log_event("$method discovery of " . $hostname . " ($ip) failed - " . $e->getMessage(), $device['device_id'], 'discovery', 5);
Eventlog::log("$method discovery of " . $hostname . " ($ip) failed - " . $e->getMessage(), $device['device_id'], 'discovery', Severity::Error);
}
return false;
@@ -153,7 +164,7 @@ function discover_device(&$device, $force_module = false)
} catch (Throwable $e) {
// isolate module exceptions so they don't disrupt the polling process
Log::error("%rError discovering $module module for {$device['hostname']}.%n $e", ['color' => true]);
\App\Models\Eventlog::log("Error discovering $module module. Check log file for more details.", $device['device_id'], 'discovery', Severity::Error);
Eventlog::log("Error discovering $module module. Check log file for more details.", $device['device_id'], 'discovery', Severity::Error);
report($e);
// Re-throw exception if we're in CI

View File

@@ -11,18 +11,7 @@
use App\Models\Device;
use Illuminate\Support\Str;
use LibreNMS\Config;
use LibreNMS\Enum\PortAssociationMode;
use LibreNMS\Enum\Severity;
use LibreNMS\Exceptions\HostExistsException;
use LibreNMS\Exceptions\HostIpExistsException;
use LibreNMS\Exceptions\HostnameExistsException;
use LibreNMS\Exceptions\HostSysnameExistsException;
use LibreNMS\Exceptions\HostUnreachableException;
use LibreNMS\Exceptions\HostUnreachablePingException;
use LibreNMS\Exceptions\HostUnreachableSnmpException;
use LibreNMS\Exceptions\InvalidPortAssocModeException;
use LibreNMS\Exceptions\SnmpVersionUnsupportedException;
use LibreNMS\Modules\Core;
/**
* Parse cli discovery or poller modules and set config for this run
@@ -164,248 +153,6 @@ function delete_device($id)
return "Failed to remove device $device->hostname";
}
/**
* Add a device to LibreNMS
*
* @param string $host dns name or ip address
* @param string $snmp_version If this is empty, try v2c,v3,v1. Otherwise, use this specific version.
* @param int $port the port to connect to for snmp
* @param string $transport udp or tcp
* @param string $poller_group the poller group this device will belong to
* @param bool $force_add add even if the device isn't reachable
* @param string $port_assoc_mode snmp field to use to determine unique ports
* @param array $additional an array with additional parameters to take into consideration when adding devices
* @return int returns the device_id of the added device
*
* @throws HostExistsException This hostname already exists
* @throws HostIpExistsException We already have a host with this IP
* @throws HostUnreachableException We could not reach this device is some way
* @throws HostUnreachablePingException We could not ping the device
* @throws InvalidPortAssocModeException The given port association mode was invalid
* @throws SnmpVersionUnsupportedException The given snmp version was invalid
*/
function addHost($host, $snmp_version = '', $port = 161, $transport = 'udp', $poller_group = '0', $force_add = false, $port_assoc_mode = 'ifIndex', $additional = [])
{
// Test Database Exists
if (host_exists($host)) {
throw new HostnameExistsException($host);
}
// Valid port assoc mode
if (! in_array($port_assoc_mode, PortAssociationMode::getModes())) {
throw new InvalidPortAssocModeException("Invalid port association_mode '$port_assoc_mode'. Valid modes are: " . join(', ', PortAssociationMode::getModes()));
}
// check if we have the host by IP
$overwrite_ip = null;
if (! empty($additional['overwrite_ip'])) {
$overwrite_ip = $additional['overwrite_ip'];
$ip = $overwrite_ip;
} elseif (Config::get('addhost_alwayscheckip') === true) {
$ip = gethostbyname($host);
} else {
$ip = $host;
}
if ($force_add !== true && $existing = Device::findByIp($ip)) {
throw new HostIpExistsException($host, $existing->hostname, $ip);
}
// Test reachability
if (! $force_add) {
if (! (new \LibreNMS\Polling\ConnectivityHelper(new Device(['hostname' => $ip])))->isPingable()->success()) {
throw new HostUnreachablePingException($host);
}
}
// if $snmpver isn't set, try each version of snmp
if (empty($snmp_version)) {
$snmpvers = Config::get('snmp.version');
} else {
$snmpvers = [$snmp_version];
}
if (isset($additional['snmp_disable']) && $additional['snmp_disable'] == 1) {
return createHost($host, '', $snmp_version, $port, $transport, [], $poller_group, 1, true, $overwrite_ip, $additional);
}
$host_unreachable_exception = new HostUnreachableSnmpException($host);
// try different snmp variables to add the device
foreach ($snmpvers as $snmpver) {
if ($snmpver === 'v3') {
// Try each set of parameters from config
foreach (Config::get('snmp.v3') as $v3) {
$device = deviceArray($host, null, $snmpver, $port, $transport, $v3, $port_assoc_mode, $overwrite_ip);
if ($force_add === true || isSNMPable($device)) {
return createHost($host, null, $snmpver, $port, $transport, $v3, $poller_group, $port_assoc_mode, $force_add, $overwrite_ip);
} else {
$host_unreachable_exception->addReason($snmpver, $v3['authname'] . '/' . $v3['authlevel']);
}
}
} elseif ($snmpver === 'v2c' || $snmpver === 'v1') {
// try each community from config
foreach (Config::get('snmp.community') as $community) {
$device = deviceArray($host, $community, $snmpver, $port, $transport, null, $port_assoc_mode, $overwrite_ip);
if ($force_add === true || isSNMPable($device)) {
return createHost($host, $community, $snmpver, $port, $transport, [], $poller_group, $port_assoc_mode, $force_add, $overwrite_ip);
} else {
$host_unreachable_exception->addReason($snmpver, $community);
}
}
} else {
throw new SnmpVersionUnsupportedException($snmpver);
}
}
if (isset($additional['ping_fallback']) && $additional['ping_fallback'] == 1) {
$additional['snmp_disable'] = 1;
$additional['os'] = 'ping';
return createHost($host, '', $snmp_version, $port, $transport, [], $poller_group, 1, true, $overwrite_ip, $additional);
}
throw $host_unreachable_exception;
}
function deviceArray($host, $community, $snmpver, $port = 161, $transport = 'udp', $v3 = [], $port_assoc_mode = 'ifIndex', $overwrite_ip = null)
{
$device = [];
$device['hostname'] = $host;
$device['overwrite_ip'] = $overwrite_ip;
$device['port'] = $port;
$device['transport'] = $transport;
/* Get port_assoc_mode id if neccessary
* We can work with names of IDs here */
if (! is_int($port_assoc_mode)) {
$port_assoc_mode = PortAssociationMode::getId($port_assoc_mode);
}
$device['port_association_mode'] = $port_assoc_mode;
$device['snmpver'] = $snmpver;
if ($snmpver === 'v2c' or $snmpver === 'v1') {
$device['community'] = $community;
} elseif ($snmpver === 'v3') {
$device['authlevel'] = $v3['authlevel'];
$device['authname'] = $v3['authname'];
$device['authpass'] = $v3['authpass'];
$device['authalgo'] = $v3['authalgo'];
$device['cryptopass'] = $v3['cryptopass'];
$device['cryptoalgo'] = $v3['cryptoalgo'];
}
return $device;
}//end deviceArray()
function isSNMPable($device)
{
$pos = snmp_check($device);
if ($pos === true) {
return true;
} else {
$pos = snmp_get($device, 'sysObjectID.0', '-Oqv', 'SNMPv2-MIB');
if ($pos === '' || $pos === false) {
return false;
} else {
return true;
}
}
}
function getpollergroup($poller_group = '0')
{
//Is poller group an integer
if (is_int($poller_group) || ctype_digit($poller_group)) {
return $poller_group;
} else {
//Check if it contains a comma
if (strpos($poller_group, ',') !== false) {
//If it has a comma use the first element as the poller group
$poller_group_array = explode(',', $poller_group);
return getpollergroup($poller_group_array[0]);
} else {
if (Config::get('distributed_poller_group')) {
//If not use the poller's group from the config
return getpollergroup(Config::get('distributed_poller_group'));
} else {
//If all else fails use default
return '0';
}
}
}
}
/**
* Add a host to the database
*
* @param string $host The IP or hostname to add
* @param string $community The snmp community
* @param string $snmpver snmp version: v1 | v2c | v3
* @param int $port SNMP port number
* @param string $transport SNMP transport: udp | udp6 | udp | tcp6
* @param array $v3 SNMPv3 settings required array keys: authlevel, authname, authpass, authalgo, cryptopass, cryptoalgo
* @param int $poller_group distributed poller group to assign this host to
* @param string $port_assoc_mode field to use to identify ports: ifIndex, ifName, ifDescr, ifAlias
* @param bool $force_add Do not detect the host os
* @param array $additional an array with additional parameters to take into consideration when adding devices
* @return int the id of the added host
*
* @throws HostExistsException Throws this exception if the host already exists
* @throws Exception Throws this exception if insertion into the database fails
*/
function createHost(
$host,
$community,
$snmpver,
$port = 161,
$transport = 'udp',
$v3 = [],
$poller_group = 0,
$port_assoc_mode = 'ifIndex',
$force_add = false,
$overwrite_ip = null,
$additional = []
) {
$host = trim(strtolower($host));
$poller_group = getpollergroup($poller_group);
/* Get port_assoc_mode id if necessary
* We can work with names of IDs here */
if (! is_int($port_assoc_mode)) {
$port_assoc_mode = PortAssociationMode::getId($port_assoc_mode);
}
$device = new Device(array_merge([
'hostname' => $host,
'overwrite_ip' => $overwrite_ip,
'sysName' => $additional['sysName'] ?? $host,
'os' => $additional['os'] ?? 'generic',
'hardware' => $additional['hardware'] ?? null,
'community' => $community,
'port' => $port,
'transport' => $transport,
'status' => '1',
'snmpver' => $snmpver,
'poller_group' => $poller_group,
'status_reason' => '',
'port_association_mode' => $port_assoc_mode,
'snmp_disable' => $additional['snmp_disable'] ?? 0,
], $v3));
if ($force_add !== true) {
$device->os = Core::detectOS($device);
$device->sysName = SnmpQuery::device($device)->get('SNMPv2-MIB::sysName.0')->value();
if (host_exists($host, $device->sysName)) {
throw new HostSysnameExistsException($host, $device->sysName);
}
}
if ($device->save()) {
return $device->device_id;
}
throw new \Exception('Failed to add host to the database, please run ./validate.php');
}
function isDomainResolves($domain)
{
if (gethostbyname($domain) != $domain) {

View File

@@ -1,5 +1,6 @@
<?php
use App\Actions\Device\ValidateDeviceAndCreate;
use LibreNMS\Config;
use LibreNMS\Enum\PortAssociationMode;
use LibreNMS\Exceptions\HostUnreachableException;
@@ -27,64 +28,57 @@ if (! empty($_POST['hostname'])) {
print_error("Invalid hostname or IP: $hostname");
}
$new_device = new \App\Models\Device(['hostname' => $hostname]);
if (Auth::user()->hasGlobalRead()) {
// Settings common to SNMPv2 & v3
if ($_POST['port']) {
$port = strip_tags($_POST['port']);
} else {
$port = Config::get('snmp.port');
$new_device->port = strip_tags($_POST['port']);
}
if ($_POST['transport']) {
$transport = strip_tags($_POST['transport']);
} else {
$transport = 'udp';
$new_device->transport = strip_tags($_POST['transport']);
}
$additional = [];
if (! $snmp_enabled) {
$snmpver = 'v2c';
$additional = [
'snmp_disable' => 1,
'os' => $_POST['os'] ? strip_tags($_POST['os_id']) : 'ping',
'hardware' => strip_tags($_POST['hardware']),
'sysName' => strip_tags($_POST['sysName']),
];
$new_device->snmp_disable = 1;
$new_device->os = $_POST['os'] ? strip_tags($_POST['os_id']) : 'ping';
$new_device->hardware = strip_tags($_POST['hardware']);
$new_device->sysName = strip_tags($_POST['sysName']);
} elseif ($_POST['snmpver'] === 'v2c' || $_POST['snmpver'] === 'v1') {
$new_device->snmpver = strip_tags($_POST['snmpver']);
$communities = Config::get('snmp.community');
if ($_POST['community']) {
Config::set('snmp.community', [$_POST['community']]);
$new_device->community = $_POST['community'];
$communities = [$_POST['community']];
}
$snmpver = strip_tags($_POST['snmpver']);
print_message("Adding host $hostname communit" . (count(Config::get('snmp.community')) == 1 ? 'y' : 'ies') . ' ' . implode(', ', array_map("\LibreNMS\Util\Clean::html", Config::get('snmp.community'))) . " port $port using $transport");
print_message("Adding host $hostname communit" . (count($communities) == 1 ? 'y' : 'ies') . ' ' . implode(', ', array_map('htmlspecialchars', $communities)) . " port $new_device->port using $new_device->transport");
} elseif ($_POST['snmpver'] === 'v3') {
$v3 = [
'authlevel' => strip_tags($_POST['authlevel']),
'authname' => $_POST['authname'],
'authpass' => $_POST['authpass'],
'authalgo' => strip_tags($_POST['authalgo']),
'cryptopass' => $_POST['cryptopass'],
'cryptoalgo' => $_POST['cryptoalgo'],
];
$new_device->snmpver = 'v3';
$new_device->authlevel = strip_tags($_POST['authlevel']);
$new_device->authname = $_POST['authname'];
$new_device->authpass = $_POST['authpass'];
$new_device->authalgo = strip_tags($_POST['authalgo']);
$new_device->cryptopass = $_POST['cryptopass'];
$new_device->cryptoalgo = $_POST['cryptoalgo'];
$v3_config = Config::get('snmp.v3');
array_unshift($v3_config, $v3);
Config::set('snmp.v3', $v3_config);
$snmpver = 'v3';
print_message("Adding SNMPv3 host: $hostname port: $port");
} else {
print_error('Unsupported SNMP Version. There was a dropdown menu, how did you reach this error ?');
}//end if
$poller_group = strip_tags($_POST['poller_group'] ?? '');
$force_add = (isset($_POST['force_add']) && $_POST['force_add'] == 'on');
$port_assoc_mode = strip_tags($_POST['port_assoc_mode']);
try {
$device_id = addHost($hostname, $snmpver, $port, $transport, $poller_group, $force_add, $port_assoc_mode, $additional);
$link = \LibreNMS\Util\Url::deviceUrl($device_id);
print_message("Device added <a href='$link'>$hostname ($device_id)</a>");
$new_device->poller_group = strip_tags($_POST['poller_group'] ?? '');
$new_device->port_association_mode = PortAssociationMode::getId($_POST['port_assoc_mode']);
$force_add = (isset($_POST['force_add']) && $_POST['force_add'] == 'on');
$result = (new ValidateDeviceAndCreate($new_device, $force_add))->execute();
if ($result) {
$link = \LibreNMS\Util\Url::deviceUrl($new_device->device_id);
print_message("Device added <a href='$link'>$hostname ($new_device->device_id)</a>");
}
} catch (HostUnreachableException $e) {
print_error($e->getMessage());
foreach ($e->getReasons() as $reason) {

View File

@@ -3,87 +3,64 @@
use LibreNMS\Config;
use LibreNMS\Enum\PortAssociationMode;
$device = DeviceCache::getPrimary();
if ($_POST['editing']) {
if (Auth::user()->hasGlobalAdmin()) {
$force_save = ($_POST['force_save'] == 'on');
$poller_group = isset($_POST['poller_group']) ? $_POST['poller_group'] : 0;
$device->poller_group = isset($_POST['poller_group']) ? $_POST['poller_group'] : 0;
$snmp_enabled = ($_POST['snmp'] == 'on');
if ($snmp_enabled) {
$device->snmp_disable = 0;
$device->snmpver = $_POST['snmpver'];
$device->port = $_POST['port'] ? $_POST['port'] : Config::get('snmp.port');
$device->transport = $_POST['transport'] ? $_POST['transport'] : $transport = 'udp';
$device->port_association_mode = $_POST['port_assoc_mode'];
$max_repeaters = $_POST['max_repeaters'];
$max_oid = $_POST['max_oid'];
$port = $_POST['port'] ? $_POST['port'] : Config::get('snmp.port');
$port_assoc_mode = $_POST['port_assoc_mode'];
$retries = $_POST['retries'];
$snmpver = $_POST['snmpver'];
$transport = $_POST['transport'] ? $_POST['transport'] : $transport = 'udp';
$timeout = $_POST['timeout'];
$device->retries = $_POST['retries'] ?: null;
$device->timeout = $_POST['timeout'] ?: null;
$update = [
'poller_group' => $poller_group,
'port' => $port,
'port_association_mode' => $port_assoc_mode,
'snmp_disable' => 0,
'snmpver' => $snmpver,
'transport' => $transport,
];
if ($retries) {
$update['retries'] = $retries;
} else {
$update['retries'] = ['NULL'];
}
if ($snmpver != 'v3' && $_POST['community'] != '********') {
$community = $_POST['community'];
$update['community'] = $community;
}
if ($timeout) {
$update['timeout'] = $timeout;
} else {
$update['timeout'] = ['NULL'];
}
$v3 = [];
if ($snmpver == 'v3') {
$community = ''; // if v3 works, we don't need a community
$v3['authalgo'] = $_POST['authalgo'];
$v3['authlevel'] = $_POST['authlevel'];
$v3['authname'] = $_POST['authname'];
$v3['authpass'] = $_POST['authpass'];
$v3['cryptoalgo'] = $_POST['cryptoalgo'];
$v3['cryptopass'] = $_POST['cryptopass'];
$update = array_merge($update, $v3);
$device->community = ''; // if v3 works, we don't need a community
$device->authalgo = $_POST['authalgo'];
$device->authlevel = $_POST['authlevel'];
$device->authname = $_POST['authname'];
$device->authpass = $_POST['authpass'];
$device->cryptoalgo = $_POST['cryptoalgo'];
$device->cryptopass = $_POST['cryptopass'];
} elseif ($_POST['community'] != '********') {
$device->community = $_POST['community'];
}
} else {
// snmp is disabled
$update['features'] = null;
$update['hardware'] = $_POST['hardware'];
$update['icon'] = null;
$update['os'] = $_POST['os'] ? $_POST['os_id'] : 'ping';
$update['poller_group'] = $poller_group;
$update['snmp_disable'] = 1;
$update['sysName'] = $_POST['sysName'] ? $_POST['sysName'] : null;
$update['version'] = null;
$device->features = null;
$device->hardware = $_POST['hardware'];
$device->icon = null;
$device->os = $_POST['os'] ? $_POST['os_id'] : 'ping';
$device->poller_group = $poller_group;
$device->snmp_disable = 1;
$device->sysName = $_POST['sysName'] ? $_POST['sysName'] : null;
$device->version = null;
}
$device_is_snmpable = false;
$rows_updated = 0;
$device_updated = false;
if ($force_save !== true && $snmp_enabled) {
$device_snmp_details = deviceArray($device['hostname'], $community, $snmpver, $port, $transport, $v3, $port_assoc_mode);
$device_issnmpable = isSNMPable($device_snmp_details);
$helper = new \LibreNMS\Polling\ConnectivityHelper($device);
$device_is_snmpable = $helper->isSNMPable();
}
if ($force_save === true || ! $snmp_enabled || $device_issnmpable) {
if ($force_save === true || ! $snmp_enabled || $device_is_snmpable) {
// update devices table
$rows_updated = dbUpdate($update, 'devices', '`device_id` = ?', [$device['device_id']]);
$device_updated = $device->save();
} else {
$device->refresh(); // forget all pending changes
}
if ($snmp_enabled && ($force_save === true || $device_issnmpable)) {
if ($snmp_enabled && ($force_save === true || $device_is_snmpable)) {
// update devices_attribs table
// note:
@@ -116,23 +93,24 @@ if ($_POST['editing']) {
$set_devices_attrib = false; // testing $set_devices_attrib === false is not a true indicator of a failure
if ($form_value != $get_devices_attrib && $form_value_is_numeric && is_numeric($form_value) && $form_value != 0) {
$set_devices_attrib = set_dev_attrib($device, $devices_attrib, $form_value);
$device->setAttrib($devices_attrib, $form_value);
}
if ($form_value != $get_devices_attrib && ! $form_value_is_numeric) {
$set_devices_attrib = set_dev_attrib($device, $devices_attrib, $form_value);
$device->setAttrib($devices_attrib, $form_value);
}
if ($form_value != $get_devices_attrib && $form_value_is_numeric && ! is_numeric($form_value)) {
$set_devices_attrib = del_dev_attrib($device, $devices_attrib);
$device->forgetAttrib($devices_attrib);
}
if ($form_value != $get_devices_attrib && ! $form_value_is_numeric && $form_value == '') {
$set_devices_attrib = del_dev_attrib($device, $devices_attrib);
$device->forgetAttrib($devices_attrib);
}
if ($form_value != $get_devices_attrib && $set_devices_attrib) {
$set_devices_attrib = get_dev_attrib($device, $devices_attrib); // re-check the db value
unset($device->attribs); // unload relation
$set_devices_attrib = $device->getAttrib($devices_attrib); // re-check the db value
}
if ($form_value != $get_devices_attrib && $form_value == $set_devices_attrib && (is_null($set_devices_attrib) || $set_devices_attrib == '')) {
@@ -152,16 +130,16 @@ if ($_POST['editing']) {
unset($devices_attrib);
}
if ($rows_updated > 0) {
if ($device_updated) {
$update_message[] = 'Device record updated';
}
if ($snmp_enabled && ($force_save !== true && ! $device_issnmpable)) {
$update_failed_message[] = 'Could not connect to ' . htmlspecialchars($device['hostname']) . ' with those SNMP settings. To save anyway, turn on Force Save.';
if ($snmp_enabled && ($force_save !== true && ! $device_is_snmpable)) {
$update_failed_message[] = 'Could not connect to ' . htmlspecialchars($device->hostname) . ' with those SNMP settings. To save anyway, turn on Force Save.';
$update_message[] = 'SNMP settings reverted';
}
if ($rows_updated == 0 && ! isset($update_message) && ! isset($update_failed_message)) {
if (! $device_updated && ! isset($update_message) && ! isset($update_failed_message)) {
$update_message[] = 'SNMP settings did not change';
}
}//end if (Auth::user()->hasGlobalAdmin())
@@ -175,9 +153,8 @@ unset($force_save, $poller_group, $snmp_enabled);
unset($community, $max_repeaters, $max_oid, $port, $port_assoc_mode, $retries, $snmpver, $transport, $timeout);
// get up-to-date database values for use on the form
$device = dbFetchRow('SELECT * FROM `devices` WHERE `device_id` = ?', [$device['device_id']]);
$max_oid = get_dev_attrib($device, 'snmp_max_oid');
$max_repeaters = get_dev_attrib($device, 'snmp_max_repeaters');
$max_oid = $device->getAttrib('snmp_max_oid');
$max_repeaters = $device->getAttrib('snmp_max_repeaters');
// use PHP Flasher to print normal (success) messages, similar to Device Settings
if (isset($update_message)) {
@@ -219,49 +196,49 @@ echo "
<div class='form-group'>
<label for='hardware' class='col-sm-2 control-label'>SNMP</label>
<div class='col-sm-4'>
<input type='checkbox' id='snmp' name='snmp' data-size='small' onChange='disableSnmp(this);'" . ($device['snmp_disable'] ? '' : ' checked') . ">
<input type='checkbox' id='snmp' name='snmp' data-size='small' onChange='disableSnmp(this);'" . ($device->snmp_disable ? '' : ' checked') . ">
</div>
</div>
<div id='snmp_override' style='display: " . ($device['snmp_disable'] ? 'block' : 'none') . ";'>
<div id='snmp_override' style='display: " . ($device->snmp_disable ? 'block' : 'none') . ";'>
<div class='form-group'>
<label for='sysName' class='col-sm-2 control-label'>sysName (optional)</label>
<div class='col-sm-4'>
<input id='sysName' class='form-control' name='sysName' value='" . htmlspecialchars($device['sysName']) . "'/>
<input id='sysName' class='form-control' name='sysName' value='" . htmlspecialchars($device->sysName) . "'/>
</div>
</div>
<div class='form-group'>
<label for='hardware' class='col-sm-2 control-label'>Hardware (optional)</label>
<div class='col-sm-4'>
<input id='hardware' class='form-control' name='hardware' value='" . htmlspecialchars($device['hardware']) . "'/>
<input id='hardware' class='form-control' name='hardware' value='" . htmlspecialchars($device->hardware) . "'/>
</div>
</div>
<div class='form-group'>
<label for='os' class='col-sm-2 control-label'>OS (optional)</label>
<div class='col-sm-4'>
<input id='os' class='form-control' name='os' value='" . htmlspecialchars(Config::get("os.{$device['os']}.text")) . "'/>
<input type='hidden' id='os_id' class='form-control' name='os_id' value='" . $device['os'] . "'/>
<input id='os' class='form-control' name='os' value='" . htmlspecialchars(Config::get("os.{$device->os}.text")) . "'/>
<input type='hidden' id='os_id' class='form-control' name='os_id' value='" . $device->os . "'/>
</div>
</div>
</div>
<div id='snmp_conf' style='display: " . ($device['snmp_disable'] ? 'none' : 'block') . ";'>
<div id='snmp_conf' style='display: " . ($device->snmp_disable ? 'none' : 'block') . ";'>
<input type=hidden name='editing' value='yes'>
<div class='form-group'>
<label for='snmpver' class='col-sm-2 control-label'>SNMP Details</label>
<div class='col-sm-1'>
<select id='snmpver' name='snmpver' class='form-control input-sm' onChange='changeForm();'>
<option value='v1'>v1</option>
<option value='v2c' " . ($device['snmpver'] == 'v2c' ? 'selected' : '') . ">v2c</option>
<option value='v3' " . ($device['snmpver'] == 'v3' ? 'selected' : '') . ">v3</option>
<option value='v2c' " . ($device->snmpver == 'v2c' ? 'selected' : '') . ">v2c</option>
<option value='v3' " . ($device->snmpver == 'v3' ? 'selected' : '') . ">v3</option>
</select>
</div>
<div class='col-sm-2'>
<input type='number' name='port' placeholder='port' class='form-control input-sm' value='" . htmlspecialchars($device['port'] == Config::get('snmp.port') ? '' : $device['port']) . "'>
<input type='number' name='port' placeholder='port' class='form-control input-sm' value='" . htmlspecialchars($device->port == Config::get('snmp.port') ? '' : $device->port) . "'>
</div>
<div class='col-sm-1'>
<select name='transport' id='transport' class='form-control input-sm'>";
foreach (Config::get('snmp.transports') as $transport) {
echo "<option value='" . $transport . "'";
if ($transport == $device['transport']) {
if ($transport == $device->transport) {
echo " selected='selected'";
}
@@ -275,10 +252,10 @@ echo " </select>
<div class='col-sm-2'>
</div>
<div class='col-sm-1'>
<input type='number' id='timeout' name='timeout' class='form-control input-sm' value='" . htmlspecialchars($device['timeout'] ? $device['timeout'] : '') . "' placeholder='seconds' />
<input type='number' id='timeout' name='timeout' class='form-control input-sm' value='" . htmlspecialchars($device->timeout ?: '') . "' placeholder='seconds' />
</div>
<div class='col-sm-1'>
<input type='number' id='retries' name='retries' class='form-control input-sm' value='" . htmlspecialchars($device['timeout'] ? $device['retries'] : '') . "' placeholder='retries' />
<input type='number' id='retries' name='retries' class='form-control input-sm' value='" . htmlspecialchars($device->retries ?: '') . "' placeholder='retries' />
</div>
</div>
<div class='form-group'>
@@ -290,7 +267,7 @@ echo " </select>
foreach (PortAssociationMode::getModes() as $pam_id => $pam) {
echo " <option value='$pam_id'";
if ($pam_id == $device['port_association_mode']) {
if ($pam_id == $device->port_association_mode) {
echo " selected='selected'";
}
@@ -319,7 +296,7 @@ echo " </select>
<div class='form-group'>
<label for='community' class='col-sm-2 control-label'>SNMP Community</label>
<div class='col-sm-4'>
<input id='community' class='form-control' name='community' value='********' onfocus='this.value=(this.value==\"********\" ? decodeURIComponent(\"" . rawurlencode($device['community']) . "\") : this.value);'/>
<input id='community' class='form-control' name='community' value='********' onfocus='this.value=(this.value==\"********\" ? decodeURIComponent(\"" . rawurlencode($device->community) . "\") : this.value);'/>
</div>
</div>
</div>
@@ -332,21 +309,21 @@ echo " </select>
<div class='col-sm-4'>
<select id='authlevel' name='authlevel' class='form-control'>
<option value='noAuthNoPriv'>noAuthNoPriv</option>
<option value='authNoPriv' " . ($device['authlevel'] == 'authNoPriv' ? 'selected' : '') . ">authNoPriv</option>
<option value='authPriv' " . ($device['authlevel'] == 'authPriv' ? 'selected' : '') . ">authPriv</option>
<option value='authNoPriv' " . ($device->authlevel == 'authNoPriv' ? 'selected' : '') . ">authNoPriv</option>
<option value='authPriv' " . ($device->authlevel == 'authPriv' ? 'selected' : '') . ">authPriv</option>
</select>
</div>
</div>
<div class='form-group'>
<label for='authname' class='col-sm-2 control-label'>Auth User Name</label>
<div class='col-sm-4'>
<input type='text' id='authname' name='authname' class='form-control' value='" . htmlspecialchars($device['authname']) . "' autocomplete='off'>
<input type='text' id='authname' name='authname' class='form-control' value='" . htmlspecialchars($device->authname) . "' autocomplete='off'>
</div>
</div>
<div class='form-group'>
<label for='authpass' class='col-sm-2 control-label'>Auth Password</label>
<div class='col-sm-4'>
<input type='password' id='authpass' name='authpass' class='form-control' value='" . htmlspecialchars($device['authpass']) . "' autocomplete='off'>
<input type='password' id='authpass' name='authpass' class='form-control' value='" . htmlspecialchars($device->authpass) . "' autocomplete='off'>
</div>
</div>
<div class='form-group'>
@@ -354,7 +331,7 @@ echo " </select>
<div class='col-sm-4'>
<select id='authalgo' name='authalgo' class='form-control'>";
foreach (\LibreNMS\SNMPCapabilities::authAlgorithms() as $algo => $enabled) {
echo "<option value='$algo' " . ($device['authalgo'] === $algo ? 'selected' : '') . ($enabled ? '' : ' disabled') . ">$algo</option>\n";
echo "<option value='$algo' " . ($device->authalgo === $algo ? 'selected' : '') . ($enabled ? '' : ' disabled') . ">$algo</option>\n";
}
echo '</select>';
@@ -367,7 +344,7 @@ echo "
<div class='form-group'>
<label for='cryptopass' class='col-sm-2 control-label'>Crypto Password</label>
<div class='col-sm-4'>
<input type='password' id='cryptopass' name='cryptopass' class='form-control' value='" . htmlspecialchars($device['cryptopass']) . "' autocomplete='off'>
<input type='password' id='cryptopass' name='cryptopass' class='form-control' value='" . htmlspecialchars($device->cryptopass) . "' autocomplete='off'>
</div>
</div>
<div class='form-group'>
@@ -376,7 +353,7 @@ echo "
<select id='cryptoalgo' name='cryptoalgo' class='form-control'>";
foreach (\LibreNMS\SNMPCapabilities::cryptoAlgoritms() as $algo => $enabled) {
echo "<option value='$algo' " . ($device['cryptoalgo'] === $algo ? 'selected' : '') . ($enabled ? '' : ' disabled') . ">$algo</option>\n";
echo "<option value='$algo' " . ($device->cryptoalgo === $algo ? 'selected' : '') . ($enabled ? '' : ' disabled') . ">$algo</option>\n";
}
echo '</select>
';
@@ -403,7 +380,7 @@ if (Config::get('distributed_poller') === true) {
foreach (dbFetchRows('SELECT `id`,`group_name` FROM `poller_groups`') as $group) {
echo '<option value="' . $group['id'] . '"';
if ($device['poller_group'] == $group['id']) {
if ($device->poller_group == $group['id']) {
echo ' selected';
}
@@ -500,7 +477,7 @@ $("#os").on("typeahead:selected typeahead:autocompleted", function(e,datum) {
$("[name='snmp']").bootstrapSwitch('offColor','danger');
<?php
if ($device['snmpver'] == 'v3') {
if ($device->snmpver == 'v3') {
echo "$('#snmpv1_2').hide();";
echo "$('#snmpv3').show();";
} else {

View File

@@ -20,7 +20,6 @@ use App\Polling\Measure\Measurement;
use Illuminate\Support\Str;
use LibreNMS\Config;
use LibreNMS\Util\Oid;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
function prep_snmp_setting($device, $setting)
{
@@ -369,34 +368,6 @@ function snmp_getnext_multi($device, $oids, $options = '-OQUs', $mib = null, $mi
return $array;
}//end snmp_getnext_multi()
/**
* @param $device
* @return bool
*/
function snmp_check($device)
{
$measure = Measurement::start('snmpget');
try {
$oid = '.1.3.6.1.2.1.1.2.0';
$cmd = gen_snmpget_cmd($device, $oid, '-Oqvn');
$proc = new \Symfony\Component\Process\Process($cmd);
$proc->run();
$code = $proc->getExitCode();
Log::debug("SNMP Check response code: $code");
} catch (ProcessTimedOutException $e) {
Log::debug("Device didn't respond to snmpget before {$e->getExceededTimeout()}s timeout");
}
$measure->manager()->recordSnmp($measure->end());
if ($code === 0) {
return true;
}
return false;
}//end snmp_check()
function snmp_walk($device, $oid, $options = null, $mib = null, $mibdir = null)
{
$measure = Measurement::start('snmpwalk');

View File

@@ -325,16 +325,6 @@ parameters:
count: 2
path: database/seeders/RolesSeeder.php
-
message: "#^Parameter \\#4 \\$transport of function addHost expects string, int given\\.$#"
count: 1
path: tests/AddHostTest.php
-
message: "#^Parameter \\#5 \\$poller_group of function addHost expects string, int given\\.$#"
count: 4
path: tests/AddHostTest.php
-
message: "#^Parameter \\#1 \\$attr of method LibreNMS\\\\Authentication\\\\SSOAuthorizer\\:\\:authSSOGetAttr\\(\\) expects string, int given\\.$#"
count: 2

View File

@@ -1,90 +0,0 @@
<?php
/**
* addhostTest.php
*
* Tests for addhost funcion
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @link https://www.librenms.org
*
* @copyright 2020 Lars Elgtvedt Susaas
* @author Lars Elgtvedt Susaas
*/
namespace LibreNMS\Tests;
use App\Models\Device;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use LibreNMS\Config;
class AddHostTest extends DBTestCase
{
use DatabaseTransactions;
private $host = 'testHost';
public function testAddsnmpV1(): void
{
addHost($this->host, 'v1', 111, 'tcp', 0, true, 'ifIndex');
$device = Device::findByHostname($this->host);
$this->assertNotNull($device);
$this->assertEquals(0, $device->snmp_disable, 'snmp is disabled');
$this->assertEquals(1, $device->port_association_mode, 'Wrong port association mode');
$this->assertEquals('v1', $device->snmpver, 'Wrong snmp version');
$this->assertEquals(111, $device->port, 'Wrong snmp port');
$this->assertEquals('tcp', $device->transport, 'Wrong snmp transport (udp/tcp)');
}
public function testAddsnmpV2(): void
{
addHost($this->host, 'v2c', 111, 'tcp', 0, true, 'ifName');
$device = Device::findByHostname($this->host);
$this->assertNotNull($device);
$this->assertEquals(0, $device->snmp_disable, 'snmp is disabled');
$this->assertEquals(2, $device->port_association_mode, 'Wrong port association mode');
$this->assertEquals(Config::get('snmp.community')[0], $device->community, 'Wrong snmp community');
$this->assertEquals('v2c', $device->snmpver, 'Wrong snmp version');
}
public function testAddsnmpV3(): void
{
addHost($this->host, 'v3', 111, 'tcp', 0, true, 'ifIndex');
$device = Device::findByHostname($this->host);
$this->assertNotNull($device);
$this->assertEquals(0, $device->snmp_disable, 'snmp is disabled');
$this->assertEquals(1, $device->port_association_mode, 'Wrong port association mode');
$this->assertEquals(Config::get('snmp.v3')[0]['authlevel'], $device->authlevel, 'Wrong snmp v3 authlevel');
$this->assertEquals('v3', $device->snmpver, 'Wrong snmp version');
$this->assertEquals(Config::get('snmp.v3')[0]['authname'], $device->authname, 'Wrong snmp v3 username');
$this->assertEquals(Config::get('snmp.v3')[0]['authpass'], $device->authpass, 'Wrong snmp v3 password');
}
public function testAddping(): void
{
$additional = [
'snmp_disable' => 1,
'os' => 'nameOfOS',
'hardware' => 'hardware',
];
addHost($this->host, '', 0, 0, 0, true, 'ifIndex', $additional);
$device = Device::findByHostname($this->host);
$this->assertNotNull($device);
$this->assertEquals(1, $device->snmp_disable, 'snmp is not disabled');
$this->assertEquals('hardware', $device->hardware, 'Wrong hardware');
$this->assertEquals('nameOfOS', $device->os, 'Wrong os');
}
}