1 | <?php |
||||
2 | |||||
3 | namespace App\Console\Commands; |
||||
4 | |||||
5 | use App\Console\LnmsCommand; |
||||
6 | use App\Models\Device; |
||||
7 | use Illuminate\Support\Str; |
||||
8 | use LibreNMS\Util\Snmpsim; |
||||
9 | use Symfony\Component\Console\Input\InputArgument; |
||||
10 | use Symfony\Component\Console\Input\InputOption; |
||||
11 | use Symfony\Component\Process\Process; |
||||
12 | |||||
13 | class DevSimulate extends LnmsCommand |
||||
14 | { |
||||
15 | protected $name = 'dev:simulate'; |
||||
16 | protected $developer = true; |
||||
17 | /** |
||||
18 | * @var Snmpsim |
||||
19 | */ |
||||
20 | protected $snmpsim = null; |
||||
21 | |||||
22 | /** |
||||
23 | * The console command description. |
||||
24 | * |
||||
25 | * @var string |
||||
26 | */ |
||||
27 | protected $description = 'Simulate devices using test data'; |
||||
28 | |||||
29 | /** |
||||
30 | * Create a new command instance. |
||||
31 | * |
||||
32 | * @return void |
||||
33 | */ |
||||
34 | public function __construct() |
||||
35 | { |
||||
36 | parent::__construct(); |
||||
37 | |||||
38 | $this->addArgument('file', InputArgument::OPTIONAL); |
||||
39 | $this->addOption('multiple', 'm', InputOption::VALUE_NONE); |
||||
40 | $this->addOption('remove', 'r', InputOption::VALUE_NONE); |
||||
41 | } |
||||
42 | |||||
43 | /** |
||||
44 | * Execute the console command. |
||||
45 | * |
||||
46 | * @return int |
||||
47 | */ |
||||
48 | public function handle() |
||||
49 | { |
||||
50 | $this->snmpsim = new Snmpsim(); |
||||
51 | $snmprec_dir = $this->snmpsim->getDir(); |
||||
52 | $listen = $this->snmpsim->getIp() . ':' . $this->snmpsim->getPort(); |
||||
53 | |||||
54 | $snmpsim = new Process([ |
||||
55 | $this->snmpsim->findSnmpsimd(), |
||||
56 | "--data-dir=$snmprec_dir", |
||||
57 | "--agent-udpv4-endpoint=$listen", |
||||
58 | ]); |
||||
59 | $snmpsim->setTimeout(null); |
||||
60 | |||||
61 | $snmpsim->run(function ($type, $buffer) use ($listen) { |
||||
62 | if (Process::ERR === $type) { |
||||
63 | if (Str::contains($buffer, $listen)) { |
||||
64 | $this->line(trim($buffer)); |
||||
65 | $this->started(); |
||||
66 | $this->line(trans('commands.dev:simulate.exit')); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
67 | } |
||||
68 | } |
||||
69 | }); |
||||
70 | |||||
71 | if (! $snmpsim->isSuccessful()) { |
||||
72 | $this->line($snmpsim->getErrorOutput()); |
||||
73 | } |
||||
74 | |||||
75 | return 0; |
||||
76 | } |
||||
77 | |||||
78 | private function started() |
||||
79 | { |
||||
80 | if ($file = $this->argument('file')) { |
||||
81 | $this->addDevice($file); |
||||
82 | } |
||||
83 | } |
||||
84 | |||||
85 | private function addDevice($community) |
||||
86 | { |
||||
87 | $hostname = $this->option('multiple') ? $community : 'snmpsim'; |
||||
88 | $device = Device::firstOrNew(['hostname' => $hostname]); |
||||
89 | $action = $device->exists ? 'updated' : 'added'; |
||||
90 | |||||
91 | $device->overwrite_ip = $this->snmpsim->getIp(); |
||||
92 | $device->port = $this->snmpsim->getPort(); |
||||
93 | $device->snmpver = 'v2c'; |
||||
94 | $device->transport = 'udp'; |
||||
95 | $device->community = $community; |
||||
96 | $device->last_discovered = null; |
||||
97 | $device->status_reason = ''; |
||||
98 | $device->save(); |
||||
99 | |||||
100 | $this->info(trans("commands.dev:simulate.$action", ['hostname' => $device->hostname, 'id' => $device->device_id])); |
||||
0 ignored issues
–
show
It seems like
trans('commands.dev:simu...=> $device->device_id)) can also be of type array and array ; however, parameter $string of Illuminate\Console\Command::info() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
101 | |||||
102 | // set up removal shutdown function if requested |
||||
103 | if ($this->option('remove')) { |
||||
104 | $this->queueRemoval($device->device_id); |
||||
105 | } |
||||
106 | } |
||||
107 | |||||
108 | private function queueRemoval($device_id) |
||||
109 | { |
||||
110 | if (function_exists('pcntl_signal')) { |
||||
111 | pcntl_signal(SIGINT, function () { |
||||
112 | exit(); // exit normally on SIGINT |
||||
0 ignored issues
–
show
|
|||||
113 | }); |
||||
114 | } |
||||
115 | |||||
116 | register_shutdown_function(function () use ($device_id) { |
||||
117 | Device::findOrNew($device_id)->delete(); |
||||
118 | $this->info(trans('commands.dev:simulate.removed', ['id' => $device_id])); |
||||
0 ignored issues
–
show
It seems like
trans('commands.dev:simu...ay('id' => $device_id)) can also be of type array and array ; however, parameter $string of Illuminate\Console\Command::info() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
119 | exit(); |
||||
0 ignored issues
–
show
|
|||||
120 | }); |
||||
121 | } |
||||
122 | |||||
123 | public function completeArgument($name, $value) |
||||
124 | { |
||||
125 | if ($name == 'file') { |
||||
126 | return collect(glob(base_path('tests/snmpsim/*.snmprec')))->map(function ($file) { |
||||
127 | return basename($file, '.snmprec'); |
||||
128 | })->filter(function ($snmprec) use ($value) { |
||||
129 | return ! $value || Str::startsWith($snmprec, $value); |
||||
130 | })->all(); |
||||
131 | } |
||||
132 | |||||
133 | return false; |
||||
134 | } |
||||
135 | } |
||||
136 |