mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Hook many commands into the lnms script (#9699)
* Pass through commands for lnms. * WIP * Add device kind of working * fill in more commands debug * text update
This commit is contained in:
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
use App\Jobs\PingCheck;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Console Routes
|
||||
@ -13,7 +11,312 @@ use App\Jobs\PingCheck;
|
||||
|
|
||||
*/
|
||||
|
||||
Artisan::command('ping {--d|debug} {groups?* : Optional List of distributed poller groups to poll}', function () {
|
||||
$this->alert("Do not use this command yet, use ./ping.php");
|
||||
use App\Models\Device;
|
||||
use LibreNMS\Exceptions\HostUnreachableException;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
Artisan::command('device:rename
|
||||
{old hostname : ' . __('The existing hostname, IP, or device id') . '}
|
||||
{new hostname : ' . __('The new hostname or IP') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
(new Process([
|
||||
base_path('renamehost.php'),
|
||||
$this->argument('old hostname'),
|
||||
$this->argument('new hostname'),
|
||||
]))->setTty(true)->run();
|
||||
})->describe(__('Rename a device, this can be used to change the hostname or IP of a device'));
|
||||
|
||||
Artisan::command('device:add
|
||||
{device spec : Hostname or IP to add}
|
||||
{--v1 : ' . __('Use SNMP v1') . '}
|
||||
{--v2c : ' . __('Use SNMP v2c') . '}
|
||||
{--v3 : ' . __('Use SNMP v3') . '}
|
||||
{--f|force : ' . __('Just add the device, do not make any safety checks') . '}
|
||||
{--g|group= : ' . __('Poller group (for distributed polling)') . '}
|
||||
{--b|ping-fallback : ' . __('Add the device as ping only if it does not respond to SNMP') . '}
|
||||
{--p|port-association-mode=ifIndex : ' . __('Sets how ports are mapped :modes, ifName is suggested for Linux/Unix', ['modes' => '[ifIndex, ifName, ifDescr, ifAlias]']) . '}
|
||||
{--c|community= : ' . __('SNMP v1 or v2 community') . '}
|
||||
{--t|transport=udp : ' . __('Transport to connect to the device') . ' [udp, udp6, tcp, tcp6]}
|
||||
{--r|port=161 : ' . __('SNMP transport port') . '}
|
||||
{--u|security-name=root : ' . __('SNMPv3 security username') . '}
|
||||
{--A|auth-password= : ' . __('SNMPv3 authentication password') . '}
|
||||
{--a|auth-protocol=md5 : ' . __('SNMPv3 authentication protocol') . ' [md5, sha, sha-512, sha-384, sha-256, sha-224]}
|
||||
{--x|privacy-protocol=aes : ' . __('SNMPv3 privacy protocol') . ' [des, aes]}
|
||||
{--X|privacy-password= : ' . __('SNMPv3 privacy password') . '}
|
||||
{--P|ping-only : ' . __('Add a ping only device') . '}
|
||||
{--o|os=ping : ' . __('Ping only: specify OS') . '}
|
||||
{--w|hardware= : ' . __('Ping only: specify hardware') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
// Value Checks
|
||||
if (!in_array($this->option('port-association-mode'), ['ifIndex', 'ifName', 'ifDescr', 'ifAlias'])) {
|
||||
$this->error(__('Invalid port association mode'));
|
||||
}
|
||||
|
||||
if (!in_array($this->option('transport'), ['udp', 'udp6', 'tcp', 'tcp6'])) {
|
||||
$this->error(__('Invalid SNMP transport'));
|
||||
}
|
||||
|
||||
if (!in_array($this->option('auth-protocol'), ['md5', 'sha', 'sha-512', 'sha-384', 'sha-256', 'sha-224'])) {
|
||||
$this->error(__('Invalid authentication protocol'));
|
||||
}
|
||||
|
||||
if (!in_array($this->option('privacy-protocol'), ['des', 'aes'])) {
|
||||
$this->error(__('Invalid privacy protocol'));
|
||||
}
|
||||
|
||||
$port = (int)$this->option('port');
|
||||
if ($port < 1 || $port > 65535) {
|
||||
$this->error(__('Port should be 1-65535'));
|
||||
}
|
||||
|
||||
// build additional
|
||||
$additional = [
|
||||
'os' => $this->option('os'),
|
||||
'hardware' => $this->option('hardware'),
|
||||
];
|
||||
if ($this->option('ping-only')) {
|
||||
$additional['snmp_disable'] = 1;
|
||||
} elseif ($this->option('ping-fallback')) {
|
||||
$additional['ping_fallback'] = 1;
|
||||
}
|
||||
|
||||
global $config;
|
||||
|
||||
if ($this->option('community')) {
|
||||
array_unshift($config['snmp']['community'], $this->option('community'));
|
||||
}
|
||||
$auth = $this->option('auth-password');
|
||||
$priv = $this->option('privacy-password');
|
||||
array_unshift($config['snmp']['v3'], [
|
||||
'authlevel' => ($auth ? 'auth' : 'noAuth') . (($priv && $auth) ? 'Priv' : 'NoPriv'),
|
||||
'authname' => $this->option('security-name'),
|
||||
'authpass' => $this->option('auth-password'),
|
||||
'authalgo' => $this->option('auth-protocol'),
|
||||
'cryptopass' => $this->option('privacy-password'),
|
||||
'cryptoalgo' => $this->option('privacy-protocol'),
|
||||
]);
|
||||
|
||||
try {
|
||||
$init_modules = [];
|
||||
include(base_path('includes/init.php'));
|
||||
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
set_debug();
|
||||
if ($verbosity >= 256) {
|
||||
global $verbose;
|
||||
$verbose = true;
|
||||
}
|
||||
}
|
||||
|
||||
$device_id = addHost(
|
||||
$this->argument('device spec'),
|
||||
$this->option('v3') ? 'v3' : ($this->option('v2c') ? 'v2c' : ($this->option('v1') ? 'v1' : '')),
|
||||
$port,
|
||||
$this->option('transport'),
|
||||
$this->option('group'),
|
||||
$this->option('force'),
|
||||
$this->option('port-association-mode'),
|
||||
$additional
|
||||
);
|
||||
$hostname = Device::where('device_id', $device_id)->value('hostname');
|
||||
$this->info("Added device $hostname ($device_id)");
|
||||
return 0;
|
||||
} catch (HostUnreachableException $e) {
|
||||
$this->error($e->getMessage() . PHP_EOL . implode(PHP_EOL, $e->getReasons()));
|
||||
return 1;
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
return 3;
|
||||
}
|
||||
})->describe('Add a new device');
|
||||
|
||||
Artisan::command('device:remove
|
||||
{device spec : ' . __('Hostname, IP, or device id to remove') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
(new Process([
|
||||
base_path('delhost.php'),
|
||||
$this->argument('device spec'),
|
||||
]))->setTty(true)->run();
|
||||
})->describe('Remove a device');
|
||||
|
||||
Artisan::command('update', function () {
|
||||
(new Process(base_path('daily.sh')))->setTty(true)->run();
|
||||
})->describe(__('Update LibreNMS and run maintenance routines'));
|
||||
|
||||
Artisan::command('poller:ping
|
||||
{groups?* : ' . __('Optional List of distributed poller groups to poll') . '}
|
||||
', function () {
|
||||
// PingCheck::dispatch(new PingCheck($this->argument('groups')));
|
||||
})->describe('Check if devices are up or down via icmp');
|
||||
$command = [base_path('ping.php')];
|
||||
if ($this->argument('groups')) {
|
||||
$command[] = '-g';
|
||||
$command[] = implode(',', $this->argument('groups'));
|
||||
}
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
$command[] = '-d';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Check if devices are up or down via icmp'));
|
||||
|
||||
Artisan::command('poller:discovery
|
||||
{device spec : ' . __('Device spec to discover: device_id, hostname, wildcard, odd, even, all, new') . '}
|
||||
{--o|os= : ' . __('Only devices with the specified operating system') . '}
|
||||
{--t|type= : ' . __('Only devices with the specified type') . '}
|
||||
{--m|modules= : ' . __('Specify single module to be run. Comma separate modules, submodules may be added with /') . '}
|
||||
', function () {
|
||||
$command = [base_path('discovery.php'), '-h', $this->argument('device spec')];
|
||||
if ($this->option('os')) {
|
||||
$command[] = '-o';
|
||||
$command[] = $this->option('os');
|
||||
}
|
||||
if ($this->option('type')) {
|
||||
$command[] = '-t';
|
||||
$command[] = $this->option('type');
|
||||
}
|
||||
if ($this->option('modules')) {
|
||||
$command[] = '-m';
|
||||
$command[] = $this->option('modules');
|
||||
}
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
$command[] = '-d';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Discover information about existing devices, defines what will be polled'));
|
||||
|
||||
Artisan::command('poller:poll
|
||||
{device spec : ' . __('Device spec to poll: device_id, hostname, wildcard, odd, even, all') . '}
|
||||
{--m|modules= : ' . __('Specify single module to be run. Comma separate modules, submodules may be added with /') . '}
|
||||
{--x|no-data : ' . __('Do not update datastores (RRD, InfluxDB, etc)') . '}
|
||||
', function () {
|
||||
$command = [base_path('poller.php'), '-h', $this->argument('device spec')];
|
||||
if ($this->option('no-data')) {
|
||||
array_push($command, '-r', '-f', '-p');
|
||||
}
|
||||
if ($this->option('modules')) {
|
||||
$command[] = '-m';
|
||||
$command[] = $this->option('modules');
|
||||
}
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
$command[] = '-d';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Poll data from devices as defined by discovery'));
|
||||
|
||||
Artisan::command('poller:alerts', function () {
|
||||
$command = [base_path('alerts.php')];
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
$command[] = '-d';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Check for any pending alerts and deliver them via defined transports'));
|
||||
|
||||
Artisan::command('poller:billing
|
||||
{bill id? : ' . __('The bill id to poll') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
$command = [base_path('poll-billing.php')];
|
||||
if ($this->argument('bill id')) {
|
||||
$command[] = '-b';
|
||||
$command[] = $this->argument('bill id');
|
||||
}
|
||||
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
$command[] = '-d';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Collect billing data'));
|
||||
|
||||
Artisan::command('poller:services
|
||||
{device spec : ' . __('Device spec to poll: device_id, hostname, wildcard, all') . '}
|
||||
{--x|no-data : ' . __('Do not update datastores (RRD, InfluxDB, etc)') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
$command = [base_path('check-services.php')];
|
||||
if ($this->option('no-data')) {
|
||||
array_push($command, '-r', '-f', '-p');
|
||||
}
|
||||
if ($this->argument('device spec') !== 'all') {
|
||||
$command[] = '-h';
|
||||
$command[] = $this->argument('device spec');
|
||||
}
|
||||
|
||||
if (($verbosity = $this->getOutput()->getVerbosity()) >= 128) {
|
||||
$command[] = '-d';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Update LibreNMS and run maintenance routines'));
|
||||
|
||||
Artisan::command('poller:billing-calculate
|
||||
{--c|clear-history : ' . __('Delete all billing history') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
$command = [base_path('billing-calculate.php')];
|
||||
if ($this->option('clear-history')) {
|
||||
$command[] = '-r';
|
||||
}
|
||||
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Run billing calculations'));
|
||||
|
||||
Artisan::command('scan
|
||||
{network?* : ' . __('CIDR notation network(s) to scan, can be ommited if \'nets\' config is set') . '}
|
||||
{--P|ping-only : ' . __('Add the device as a ping only device if it replies to ping but not SNMP') . '}
|
||||
{--t|threads=32 : ' . __('How many IPs to scan at a time, more will increase the scan speed, but could overload your system') . '}
|
||||
{--l|legend : ' . __('Print the legend') . '}
|
||||
', function () {
|
||||
/** @var \Illuminate\Console\Command $this */
|
||||
$command = [base_path('snmp-scan.py')];
|
||||
|
||||
if (empty($this->argument('network')) && !Config::has('nets')) {
|
||||
$this->error(__('Network is required if \'nets\' is not set in the config'));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($this->option('ping-only')) {
|
||||
$command[] = '-P';
|
||||
}
|
||||
|
||||
$command[] = '-t';
|
||||
$command[] = $this->option('threads');
|
||||
|
||||
if ($this->option('legend')) {
|
||||
$command[] = '-l';
|
||||
}
|
||||
|
||||
$verbosity = $this->getOutput()->getVerbosity();
|
||||
if ($verbosity >= 64) {
|
||||
$command[] = '-v';
|
||||
if ($verbosity >= 128) {
|
||||
$command[] = '-v';
|
||||
if ($verbosity >= 256) {
|
||||
$command[] = '-v';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$command = array_merge($command, $this->argument('network'));
|
||||
|
||||
(new Process($command))->setTty(true)->run();
|
||||
})->describe(__('Scan the network for hosts and try to add them to LibreNMS'));
|
||||
|
Reference in New Issue
Block a user