Migrate addhost.php to lnms device:add (#13870)

* Migrate addhost.php to lnms device:add
Have snmp-scan.py call lnms device:add (make exit codes line up so this works)
Fix issue with ping only devices trying to detect os via snmp
Reorder options in device:add help and improve formatting
Update docs to remove references to addhost.php
Fix a bit of code that was in functional code

* fixes

* fix snmp version message
This commit is contained in:
Tony Murray
2022-04-04 10:41:18 -05:00
committed by GitHub
parent 96b708a10e
commit 75ba74fe5b
13 changed files with 167 additions and 187 deletions

View File

@@ -33,6 +33,7 @@ use LibreNMS\Config;
use LibreNMS\Exceptions\InvalidOidException; use LibreNMS\Exceptions\InvalidOidException;
use LibreNMS\Interfaces\Discovery\DiscoveryItem; use LibreNMS\Interfaces\Discovery\DiscoveryItem;
use LibreNMS\OS; use LibreNMS\OS;
use LibreNMS\Util\Compare;
class YamlDiscovery class YamlDiscovery
{ {
@@ -352,7 +353,7 @@ class YamlDiscovery
} }
} }
if (compare_var($tmp_value, $skip_value['value'], $op)) { if (Compare::values($tmp_value, $skip_value['value'], $op)) {
return true; return true;
} }
} }

View File

@@ -48,7 +48,7 @@ class HostUnreachableException extends \Exception
public function addReason(string $snmpVersion, string $credentials) public function addReason(string $snmpVersion, string $credentials)
{ {
$vars = [ $vars = [
'snmpver' => $snmpVersion, 'version' => $snmpVersion,
'credentials' => $credentials, 'credentials' => $credentials,
]; ];

View File

@@ -31,6 +31,7 @@ use LibreNMS\Config;
use LibreNMS\Interfaces\Module; use LibreNMS\Interfaces\Module;
use LibreNMS\OS; use LibreNMS\OS;
use LibreNMS\RRD\RrdDefinition; use LibreNMS\RRD\RrdDefinition;
use LibreNMS\Util\Compare;
use LibreNMS\Util\Time; use LibreNMS\Util\Time;
use Log; use Log;
use SnmpQuery; use SnmpQuery;
@@ -201,7 +202,7 @@ class Core implements Module
->mibDir($value['mib_dir'] ?? $mibdir) ->mibDir($value['mib_dir'] ?? $mibdir)
->get(isset($value['mib']) ? "{$value['mib']}::{$value['oid']}" : $value['oid']) ->get(isset($value['mib']) ? "{$value['mib']}::{$value['oid']}" : $value['oid'])
->value(); ->value();
if (compare_var($get_value, $value['value'], $value['op'] ?? 'contains') == $check) { if (Compare::values($get_value, $value['value'], $value['op'] ?? 'contains') == $check) {
return false; return false;
} }
} elseif ($key == 'snmpwalk') { } elseif ($key == 'snmpwalk') {
@@ -210,7 +211,7 @@ class Core implements Module
->mibDir($value['mib_dir'] ?? $mibdir) ->mibDir($value['mib_dir'] ?? $mibdir)
->walk(isset($value['mib']) ? "{$value['mib']}::{$value['oid']}" : $value['oid']) ->walk(isset($value['mib']) ? "{$value['mib']}::{$value['oid']}" : $value['oid'])
->raw(); ->raw();
if (compare_var($walk_value, $value['value'], $value['op'] ?? 'contains') == $check) { if (Compare::values($walk_value, $value['value'], $value['op'] ?? 'contains') == $check) {
return false; return false;
} }
} }

94
LibreNMS/Util/Compare.php Normal file
View File

@@ -0,0 +1,94 @@
<?php
/**
* Compare.php
*
* -Description-
*
* 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 2022 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Util;
use Illuminate\Support\Str;
class Compare
{
/**
* Perform comparison of two items based on give comparison method
* Valid comparisons: =, !=, ==, !==, >=, <=, >, <, contains, starts, ends, regex
* contains, starts, ends: $a haystack, $b needle(s)
* regex: $a subject, $b regex
*
* @param mixed $a
* @param mixed $b
* @param string $comparison =, !=, ==, !== >=, <=, >, <, contains, starts, ends, regex
* @return bool
*/
public static function values($a, $b, $comparison = '=')
{
// handle PHP8 change to implicit casting
if (is_numeric($a) || is_numeric($b)) {
$a = cast_number($a);
$b = is_array($b) ? $b : cast_number($b);
}
switch ($comparison) {
case '=':
return $a == $b;
case '!=':
return $a != $b;
case '==':
return $a === $b;
case '!==':
return $a !== $b;
case '>=':
return $a >= $b;
case '<=':
return $a <= $b;
case '>':
return $a > $b;
case '<':
return $a < $b;
case 'contains':
return Str::contains($a, $b);
case 'not_contains':
return ! Str::contains($a, $b);
case 'starts':
return Str::startsWith($a, $b);
case 'not_starts':
return ! Str::startsWith($a, $b);
case 'ends':
return Str::endsWith($a, $b);
case 'not_ends':
return ! Str::endsWith($a, $b);
case 'regex':
return (bool) preg_match($b, $a);
case 'not_regex':
return ! ((bool) preg_match($b, $a));
case 'in_array':
return in_array($a, $b);
case 'not_in_array':
return ! in_array($a, $b);
case 'exists':
return isset($a) == $b;
default:
return false;
}
}
}

View File

@@ -9,6 +9,8 @@
* @copyright (C) 2006 - 2012 Adam Armstrong * @copyright (C) 2006 - 2012 Adam Armstrong
*/ */
use App\Actions\Device\ValidateDeviceAndCreate;
use App\Models\Device;
use LibreNMS\Config; use LibreNMS\Config;
use LibreNMS\Enum\PortAssociationMode; use LibreNMS\Enum\PortAssociationMode;
use LibreNMS\Exceptions\HostUnreachableException; use LibreNMS\Exceptions\HostUnreachableException;
@@ -18,16 +20,14 @@ require __DIR__ . '/includes/init.php';
$options = getopt('Pbg:p:f::'); $options = getopt('Pbg:p:f::');
$device = new Device;
if (isset($options['g']) && $options['g'] >= 0) { if (isset($options['g']) && $options['g'] >= 0) {
$cmd = array_shift($argv); $cmd = array_shift($argv);
array_shift($argv); array_shift($argv);
array_shift($argv); array_shift($argv);
array_unshift($argv, $cmd); array_unshift($argv, $cmd);
$poller_group = $options['g']; $device->poller_group = $options['g'];
} elseif (Config::get('distributed_poller') === true) {
$poller_group = Config::get('default_poller_group');
} else {
$poller_group = 0;
} }
if (isset($options['f']) && $options['f'] == 0) { if (isset($options['f']) && $options['f'] == 0) {
@@ -39,12 +39,11 @@ if (isset($options['f']) && $options['f'] == 0) {
$force_add = false; $force_add = false;
} }
$port_assoc_mode = Config::get('default_port_association_mode');
$valid_assoc_modes = PortAssociationMode::getModes(); $valid_assoc_modes = PortAssociationMode::getModes();
if (isset($options['p'])) { if (isset($options['p'])) {
$port_assoc_mode = $options['p']; $device->port_association_mode = $options['p'];
if (! in_array($port_assoc_mode, $valid_assoc_modes)) { if (! in_array($device->port_association_mode, $valid_assoc_modes)) {
echo "Invalid port association mode '" . $port_assoc_mode . "'\n"; echo "Invalid port association mode '" . $device->port_association_mode . "'\n";
echo 'Valid modes: ' . join(', ', $valid_assoc_modes) . "\n"; echo 'Valid modes: ' . join(', ', $valid_assoc_modes) . "\n";
exit(1); exit(1);
} }
@@ -69,138 +68,95 @@ if (isset($options['b'])) {
$transports_regex = implode('|', Config::get('snmp.transports')); $transports_regex = implode('|', Config::get('snmp.transports'));
if (! empty($argv[1])) { if (! empty($argv[1])) {
$host = strtolower($argv[1]); $device->hostname = strtolower($argv[1]);
$community = $argv[2]; $device->snmpver = strtolower($argv[3]);
$snmpver = strtolower($argv[3]);
$port = 161;
$transport = 'udp';
$additional = [];
if (isset($options['b'])) {
$additional = [
'ping_fallback' => 1,
];
}
if (isset($options['P'])) { if (isset($options['P'])) {
$community = ''; $device->snmp_disable = 1;
$snmpver = 'v2c'; $device->os = $argv[2] ?: 'ping';
$additional = [ $device->hardware = $argv[3] ?: '';
'snmp_disable' => 1, } elseif ($device->snmpver === 'v3') {
'os' => $argv[2] ? $argv[2] : 'ping', $seclevel = $argv[2];
'hardware' => $argv[3] ? $argv[3] : '',
];
} elseif ($snmpver === 'v3') {
$seclevel = $community;
// These values are the same as in defaults.inc.php
$v3 = [
'authlevel' => 'noAuthNoPriv',
'authname' => 'root',
'authpass' => '',
'authalgo' => 'MD5',
'cryptopass' => '',
'cryptoalgo' => 'AES',
];
// v3 // v3
if ($seclevel === 'nanp' or $seclevel === 'any' or $seclevel === 'noAuthNoPriv') { if ($seclevel === 'nanp' or $seclevel === 'any' or $seclevel === 'noAuthNoPriv') {
$v3['authlevel'] = 'noAuthNoPriv'; $device->authlevel = 'noAuthNoPriv';
$v3args = array_slice($argv, 4); $v3args = array_slice($argv, 4);
while ($arg = array_shift($v3args)) { while ($arg = array_shift($v3args)) {
// parse all remaining args // parse all remaining args
if (is_numeric($arg)) { if (is_numeric($arg)) {
$port = $arg; $device->port = $arg;
} elseif (preg_match('/^(' . $transports_regex . ')$/', $arg)) { } elseif (preg_match('/^(' . $transports_regex . ')$/', $arg)) {
$transport = $arg; $device->transport = $arg;
} else { } else {
// should add a sanity check of chars allowed in user // should add a sanity check of chars allowed in user
$user = $arg; $device->authname = $arg;
} }
} }
if ($seclevel === 'nanp') {
$v3_config = Config::get('snmp.v3');
array_unshift($v3_config, $v3);
Config::set('snmp.v3', $v3_config);
}
} elseif ($seclevel === 'anp' or $seclevel === 'authNoPriv') { } elseif ($seclevel === 'anp' or $seclevel === 'authNoPriv') {
$v3['authlevel'] = 'authNoPriv'; $device->authlevel = 'authNoPriv';
$v3args = array_slice($argv, 4); $v3args = array_slice($argv, 4);
$v3['authname'] = array_shift($v3args); $device->authname = array_shift($v3args);
$v3['authpass'] = array_shift($v3args); $device->authpass = array_shift($v3args);
while ($arg = array_shift($v3args)) { while ($arg = array_shift($v3args)) {
// parse all remaining args // parse all remaining args
if (is_numeric($arg)) { if (is_numeric($arg)) {
$port = $arg; $device->port = $arg;
} elseif (preg_match('/^(' . $transports_regex . ')$/i', $arg)) { } elseif (preg_match('/^(' . $transports_regex . ')$/i', $arg)) {
$transport = $arg; $device->transport = $arg;
} elseif (preg_match('/^(sha|md5)$/i', $arg)) { } elseif (preg_match('/^(sha|md5)$/i', $arg)) {
$v3['authalgo'] = $arg; $device->authalgo = $arg;
} else { } else {
echo 'Invalid argument: ' . $arg . "\n"; echo 'Invalid argument: ' . $arg . "\n";
exit(1); exit(1);
} }
} }
$v3_config = Config::get('snmp.v3');
array_unshift($v3_config, $v3);
Config::set('snmp.v3', $v3_config);
} elseif ($seclevel === 'ap' or $seclevel === 'authPriv') { } elseif ($seclevel === 'ap' or $seclevel === 'authPriv') {
$v3['authlevel'] = 'authPriv'; $device->authlevel = 'authPriv';
$v3args = array_slice($argv, 4); $v3args = array_slice($argv, 4);
$v3['authname'] = array_shift($v3args); $device->authname = array_shift($v3args);
$v3['authpass'] = array_shift($v3args); $device->authpass = array_shift($v3args);
$v3['cryptopass'] = array_shift($v3args); $device->cryptopass = array_shift($v3args);
while ($arg = array_shift($v3args)) { while ($arg = array_shift($v3args)) {
// parse all remaining args // parse all remaining args
if (is_numeric($arg)) { if (is_numeric($arg)) {
$port = $arg; $device->port = $arg;
} elseif (preg_match('/^(' . $transports_regex . ')$/i', $arg)) { } elseif (preg_match('/^(' . $transports_regex . ')$/i', $arg)) {
$transport = $arg; $device->transport = $arg;
} elseif (preg_match('/^(sha|md5)$/i', $arg)) { } elseif (preg_match('/^(sha|md5)$/i', $arg)) {
$v3['authalgo'] = $arg; $device->authalgo = $arg;
} elseif (preg_match('/^(aes|des)$/i', $arg)) { } elseif (preg_match('/^(aes|des)$/i', $arg)) {
$v3['cryptoalgo'] = $arg; $device->cryptoalgo = $arg;
} else { } else {
echo 'Invalid argument: ' . $arg . "\n"; echo 'Invalid argument: ' . $arg . "\n";
exit(1); exit(1);
} }
}//end while }//end while
$v3_config = Config::get('snmp.v3');
array_unshift($v3_config, $v3);
Config::set('snmp.v3', $v3_config);
} }
} else { } else {
// v2c or v1 // v2c or v1
$v2args = array_slice($argv, 2); $v2args = array_slice($argv, 2);
$device->community = $argv[2];
while ($arg = array_shift($v2args)) { while ($arg = array_shift($v2args)) {
// parse all remaining args // parse all remaining args
if (is_numeric($arg)) { if (is_numeric($arg)) {
$port = $arg; $device->port = $arg;
} elseif (preg_match('/(' . $transports_regex . ')/i', $arg)) { } elseif (preg_match('/(' . $transports_regex . ')/i', $arg)) {
$transport = $arg; $device->transport = $arg;
} elseif (preg_match('/^(v1|v2c)$/i', $arg)) { } elseif (preg_match('/^(v1|v2c)$/i', $arg)) {
$snmpver = $arg; $device->snmpver = $arg;
} }
} }
if ($community) {
$comm_config = Config::get('snmp.community');
array_unshift($comm_config, $community);
Config::set('snmp.community', $comm_config);
}
}//end if }//end if
try { try {
$device_id = addHost($host, $snmpver, $port, $transport, $poller_group, $force_add, $port_assoc_mode, $additional); $result = (new ValidateDeviceAndCreate($device, $force_add, isset($options['b'])))->execute();
$device = device_by_id_cache($device_id);
echo "Added device {$device['hostname']} ($device_id)\n"; echo "Added device $device->hostname ($device->device_id)\n";
exit(0); exit(0);
} catch (HostUnreachableException $e) { } catch (HostUnreachableException $e) {
print_error($e->getMessage()); print_error($e->getMessage());

View File

@@ -92,10 +92,12 @@ class ValidateDeviceAndCreate
$this->detectCredentials(); $this->detectCredentials();
$this->cleanCredentials(); $this->cleanCredentials();
$this->device->sysName = SnmpQuery::device($this->device)->get('SNMPv2-MIB::sysName.0')->value(); if (! $this->device->snmp_disable) {
$this->exceptIfSysNameExists(); $this->device->sysName = SnmpQuery::device($this->device)->get('SNMPv2-MIB::sysName.0')->value();
$this->exceptIfSysNameExists();
$this->device->os = Core::detectOS($this->device); $this->device->os = Core::detectOS($this->device);
}
} }
return $this->device->save(); return $this->device->save();

View File

@@ -48,22 +48,22 @@ class DeviceAdd extends LnmsCommand
]; ];
$this->addArgument('device spec', InputArgument::REQUIRED); $this->addArgument('device spec', InputArgument::REQUIRED);
$this->addOption('v1', null, InputOption::VALUE_NONE); $this->addOption('v1', '1', InputOption::VALUE_NONE);
$this->addOption('v2c', null, InputOption::VALUE_NONE); $this->addOption('v2c', '2', InputOption::VALUE_NONE);
$this->addOption('v3', null, InputOption::VALUE_NONE); $this->addOption('v3', '3', InputOption::VALUE_NONE);
$this->addOption('display-name', 'd', InputOption::VALUE_REQUIRED);
$this->addOption('force', 'f', InputOption::VALUE_NONE);
$this->addOption('poller-group', 'g', InputOption::VALUE_REQUIRED, null, Config::get('default_poller_group'));
$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('community', 'c', InputOption::VALUE_REQUIRED);
$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('port', 'r', InputOption::VALUE_REQUIRED, null, Config::get('snmp.port', 161));
$this->addOption('transport', 't', InputOption::VALUE_REQUIRED, null, Config::get('snmp.transports.0', 'udp'));
$this->addOption('display-name', 'd', InputOption::VALUE_REQUIRED);
$this->addOption('security-name', 'u', InputOption::VALUE_REQUIRED, null, 'root'); $this->addOption('security-name', 'u', InputOption::VALUE_REQUIRED, null, 'root');
$this->addOption('auth-password', 'A', InputOption::VALUE_REQUIRED); $this->addOption('auth-password', 'A', InputOption::VALUE_REQUIRED);
$this->addOption('auth-protocol', 'a', InputOption::VALUE_REQUIRED, null, 'MD5'); $this->addOption('auth-protocol', 'a', InputOption::VALUE_REQUIRED, null, 'MD5');
$this->addOption('privacy-password', 'X', InputOption::VALUE_REQUIRED); $this->addOption('privacy-password', 'X', InputOption::VALUE_REQUIRED);
$this->addOption('privacy-protocol', 'x', InputOption::VALUE_REQUIRED, null, 'AES'); $this->addOption('privacy-protocol', 'x', InputOption::VALUE_REQUIRED, null, 'AES');
$this->addOption('force', 'f', InputOption::VALUE_NONE);
$this->addOption('ping-fallback', 'b', InputOption::VALUE_NONE);
$this->addOption('poller-group', 'g', InputOption::VALUE_REQUIRED, null, Config::get('default_poller_group'));
$this->addOption('port-association-mode', 'p', InputOption::VALUE_REQUIRED, null, Config::get('default_port_association_mode'));
$this->addOption('ping-only', 'P', InputOption::VALUE_NONE); $this->addOption('ping-only', 'P', InputOption::VALUE_NONE);
$this->addOption('os', 'o', InputOption::VALUE_REQUIRED); $this->addOption('os', 'o', InputOption::VALUE_REQUIRED);
$this->addOption('hardware', 'w', InputOption::VALUE_REQUIRED); $this->addOption('hardware', 'w', InputOption::VALUE_REQUIRED);
@@ -127,7 +127,7 @@ class DeviceAdd extends LnmsCommand
$this->error($e->getMessage() . PHP_EOL . implode(PHP_EOL, $e->getReasons())); $this->error($e->getMessage() . PHP_EOL . implode(PHP_EOL, $e->getReasons()));
$this->line(trans('commands.device:add.messages.try_force')); $this->line(trans('commands.device:add.messages.try_force'));
return 1; return 2;
} catch (HostExistsException $e) { } catch (HostExistsException $e) {
// host exists errors // host exists errors
$this->error($e->getMessage()); $this->error($e->getMessage());
@@ -136,12 +136,12 @@ class DeviceAdd extends LnmsCommand
$this->line(trans('commands.device:add.messages.try_force')); $this->line(trans('commands.device:add.messages.try_force'));
} }
return 2; return 3;
} catch (Exception $e) { } catch (Exception $e) {
// other errors? // other errors?
$this->error(get_class($e) . ': ' . $e->getMessage()); $this->error(get_class($e) . ': ' . $e->getMessage());
return 3; return 1;
} }
} }
} }

View File

@@ -23,32 +23,20 @@ Using the command line via ssh you can add a new device by changing to
the directory of your LibreNMS install and typing (be sure to put the the directory of your LibreNMS install and typing (be sure to put the
correct details). correct details).
Preferred method:
```bash ```bash
./lnms device:add [--v1|--v2c] [-c yourSNMPcommunity] yourhostname ./lnms device:add yourhostname [--v1|--v2c] [-c yourSNMPcommunity]
``` ```
You can use `./lnms device:add --help` for a list of available options and defaults. You can use `./lnms device:add --help` for a list of available options and defaults.
Alternative:
```bash
./addhost.php yourhostname [community] [v1|v2c] [port] [udp|udp6|tcp|tcp6]
```
As an example, if your device with the name `mydevice.example.com` is As an example, if your device with the name `mydevice.example.com` is
configured to use the community `my_company` using snmp `v2c` then you configured to use the community `my_company` using snmp `v2c` then you
would enter: would enter:
Preferred method:
```bash ```bash
./lnms device:add --v2c -c my_company mydevice.example.com ./lnms device:add --v2c -c my_company mydevice.example.com
``` ```
Alternative:
```bash
./addhost.php mydevice.example.com my_company v2c
```
> Please note that if the community contains special characters such > Please note that if the community contains special characters such
> as `$` then you will need to wrap it in `'`. I.e: `'Pa$$w0rd'`. > as `$` then you will need to wrap it in `'`. I.e: `'Pa$$w0rd'`.

View File

@@ -11,13 +11,14 @@ Please see the following [doc](/Installation/Install-LibreNMS.md)
You have two options for adding a new device into LibreNMS. You have two options for adding a new device into LibreNMS.
1: Using the command line via ssh you can add a new device by changing 1: Using the command line via ssh you can add a new device by changing
to the directory of your LibreNMS install and typing (be sure to to the directory of your LibreNMS install and typing:
put the correct details).
```bash ```bash
./addhost.php [community] [v1|v2c] [port] [udp|udp6|tcp|tcp6] lnms device:add [hostname or ip]
``` ```
To see all options run: `lnms device:add -h`
> Please note that if the community contains special characters such > Please note that if the community contains special characters such
> as `$` then you will need to wrap it in `'`. I.e: `'Pa$$w0rd'`. > as `$` then you will need to wrap it in `'`. I.e: `'Pa$$w0rd'`.

View File

@@ -114,69 +114,6 @@ function logfile($string)
fclose($fd); fclose($fd);
} }
/**
* Perform comparison of two items based on give comparison method
* Valid comparisons: =, !=, ==, !==, >=, <=, >, <, contains, starts, ends, regex
* contains, starts, ends: $a haystack, $b needle(s)
* regex: $a subject, $b regex
*
* @param mixed $a
* @param mixed $b
* @param string $comparison =, !=, ==, !== >=, <=, >, <, contains, starts, ends, regex
* @return bool
*/
function compare_var($a, $b, $comparison = '=')
{
// handle PHP8 change to implicit casting
if (is_numeric($a) || is_numeric($b)) {
$a = cast_number($a);
$b = is_array($b) ? $b : cast_number($b);
}
switch ($comparison) {
case '=':
return $a == $b;
case '!=':
return $a != $b;
case '==':
return $a === $b;
case '!==':
return $a !== $b;
case '>=':
return $a >= $b;
case '<=':
return $a <= $b;
case '>':
return $a > $b;
case '<':
return $a < $b;
case 'contains':
return Str::contains($a, $b);
case 'not_contains':
return ! Str::contains($a, $b);
case 'starts':
return Str::startsWith($a, $b);
case 'not_starts':
return ! Str::startsWith($a, $b);
case 'ends':
return Str::endsWith($a, $b);
case 'not_ends':
return ! Str::endsWith($a, $b);
case 'regex':
return (bool) preg_match($b, $a);
case 'not_regex':
return ! ((bool) preg_match($b, $a));
case 'in_array':
return in_array($a, $b);
case 'not_in_array':
return ! in_array($a, $b);
case 'exists':
return isset($a) == $b;
default:
return false;
}
}
function percent_colour($perc) function percent_colour($perc)
{ {
$r = min(255, 5 * ($perc - 25)); $r = min(255, 5 * ($perc - 25));

View File

@@ -73,7 +73,7 @@ return [
'v1' => 'Use SNMP v1', 'v1' => 'Use SNMP v1',
'v2c' => 'Use SNMP v2c', 'v2c' => 'Use SNMP v2c',
'v3' => 'Use SNMP v3', 'v3' => 'Use SNMP v3',
'display-name' => 'A string to display as the name of this device, defaults to hostname. May be a simple template using replacements: {{ $hostname }}, {{ $sysName }}, {{ $sysName_fallback }}, {{ $ip }}', 'display-name' => "A string to display as the name of this device, defaults to hostname.\nMay be a simple template using replacements: {{ \$hostname }}, {{ \$sysName }}, {{ \$sysName_fallback }}, {{ \$ip }}",
'force' => 'Just add the device, do not make any safety checks', 'force' => 'Just add the device, do not make any safety checks',
'group' => 'Poller group (for distributed polling)', 'group' => 'Poller group (for distributed polling)',
'ping-fallback' => 'Add the device as ping only if it does not respond to SNMP', 'ping-fallback' => 'Add the device as ping only if it does not respond to SNMP',

View File

@@ -128,8 +128,8 @@ def scan_host(scan_ip):
arguments = [ arguments = [
"/usr/bin/env", "/usr/bin/env",
"php", "lnms",
"addhost.php", "device:add",
"-g", "-g",
POLLER_GROUP, POLLER_GROUP,
hostname or scan_ip, hostname or scan_ip,
@@ -261,7 +261,7 @@ Example: """
networks = [] networks = []
for net in netargs if netargs else CONFIG.get("nets", []): for net in netargs if netargs else CONFIG.get("nets", []):
try: try:
networks.append(ip_network(u"%s" % net, True)) networks.append(ip_network("%s" % net, True))
debug("Network parsed: {}".format(net), 2) debug("Network parsed: {}".format(net), 2)
except ValueError as e: except ValueError as e:
parser.error("Invalid network format {}".format(e)) parser.error("Invalid network format {}".format(e))

View File

@@ -164,7 +164,7 @@ class AddHostCliTest extends DBTestCase
->assertExitCode(0) ->assertExitCode(0)
->execute(); ->execute();
$this->artisan('device:add', ['device spec' => 'existing']) $this->artisan('device:add', ['device spec' => 'existing'])
->assertExitCode(2) ->assertExitCode(3)
->execute(); ->execute();
} }
} }