Passed
Push — master ( bad050...86740a )
by
unknown
22:19 queued 09:25
created

DeviceController::getStatus()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
/**
3
 * DeviceController.php
4
 *
5
 * -Description-
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * @package    LibreNMS
21
 * @link       http://librenms.org
22
 * @copyright  2019 Tony Murray
23
 * @author     Tony Murray <[email protected]>
24
 */
25
26
namespace App\Http\Controllers\Table;
27
28
use App\Models\Device;
29
use App\Models\Location;
30
use Illuminate\Database\Eloquent\Builder;
31
use LibreNMS\Config;
32
use LibreNMS\Util\Rewrite;
33
use LibreNMS\Util\Url;
34
use LibreNMS\Util\Time;
35
36
class DeviceController extends TableController
37
{
38
    private $detailed; // display format is detailed
39
40
    protected function rules()
41
    {
42
        return [
43
            'format' => 'nullable|in:list_basic,list_detail',
44
            'os' => 'nullable|string',
45
            'version' => 'nullable|string',
46
            'hardware' => 'nullable|string',
47
            'features' => 'nullable|string',
48
            'location' => 'nullable|string',
49
            'type' => 'nullable|string',
50
            'state' => 'nullable|in:0,1,up,down',
51
            'disabled' => 'nullable|in:0,1',
52
            'ignore' => 'nullable|in:0,1',
53
            'group' => 'nullable|int',
54
        ];
55
    }
56
57
    protected function filterFields($request)
58
    {
59
        return ['os', 'version', 'hardware', 'features', 'type', 'status' => 'state', 'disabled', 'ignore', 'location_id' => 'location'];
60
    }
61
62
    protected function searchFields($request)
63
    {
64
        return ['sysName', 'hostname', 'hardware', 'os', 'locations.location'];
65
    }
66
67
    /**
68
     * Defines the base query for this resource
69
     *
70
     * @param \Illuminate\Http\Request $request
71
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
72
     */
73
    protected function baseQuery($request)
74
    {
75
        /** @var Builder $query */
76
        $query = Device::hasAccess($request->user())->with('location')->select('devices.*');
77
78
        // if searching or sorting the location field, join the locations table
79
        if ($request->get('searchPhrase') || in_array('location', array_keys($request->get('sort', [])))) {
80
            $query->leftJoin('locations', 'locations.id', 'devices.location_id');
81
        }
82
83
        // filter device group, not sure this is the most efficient query
84
        if ($group = $request->get('group')) {
85
            $query->whereHas('groups', function ($query) use ($group) {
86
                $query->where('id', $group);
87
            });
88
        }
89
90
        return $query;
91
    }
92
93
    protected function adjustFilterValue($field, $value)
94
    {
95
        if ($field == 'location' && !is_numeric($value)) {
96
            return Location::query()->where('location', $value)->value('id');
97
        }
98
99
        if ($field == 'state' && !is_numeric($value)) {
100
            return str_replace(['up', 'down'], [1, 0], $value);
101
        }
102
103
        return $value;
104
    }
105
106
    private function isDetailed()
107
    {
108
        if (is_null($this->detailed)) {
109
            $this->detailed = \Request::get('format', 'list_detail') == 'list_detail';
110
        }
111
112
        return $this->detailed;
113
    }
114
115
    /**
116
     * @param Device $device
117
     * @return array|\Illuminate\Database\Eloquent\Model|\Illuminate\Support\Collection
118
     */
119
    public function formatItem($device)
120
    {
121
        return [
122
            'extra' => $this->getLabel($device),
123
            'status' => $this->getStatus($device),
124
            'icon' => '<img src="' . asset($device->icon) . '" title="' . pathinfo($device->icon, PATHINFO_FILENAME) . '">',
125
            'hostname' => $this->getHostname($device),
126
            'metrics' => $this->getMetrics($device),
127
            'hardware' => Rewrite::ciscoHardware($device),
128
            'os' => $this->getOsText($device),
129
            'uptime' => (!$device->status && !$device->last_polled) ? __('Never polled') : Time::formatInterval($device->status ? $device->uptime : $device->last_polled->diffInSeconds(), 'short'),
130
            'location' => $this->getLocation($device),
131
            'actions' => $this->getActions($device),
132
        ];
133
    }
134
135
    /**
136
     * Get the device up/down status
137
     * @param Device $device
138
     * @return string
139
     */
140
    private function getStatus($device)
141
    {
142
        if ($device->disabled == 1) {
143
            return 'disabled';
144
        } elseif ($device->status == 0) {
145
            return 'down';
146
        }
147
148
        return 'up';
149
    }
150
151
    /**
152
     * Get the status label class
153
     * @param Device $device
154
     * @return string
155
     */
156
    private function getLabel($device)
157
    {
158
        if ($device->disabled == 1) {
159
            return 'blackbg';
160
        } elseif ($device->ignore == 1) {
161
            return 'label-default';
162
        } elseif ($device->status == 0) {
163
            return 'label-danger';
164
        } else {
165
            $warning_time = \LibreNMS\Config::get('uptime_warning', 84600);
166
            if ($device->uptime < $warning_time && $device->uptime != 0) {
167
                return 'label-warning';
168
            }
169
170
            return 'label-success';
171
        }
172
    }
173
174
    /**
175
     * @param Device $device
176
     * @return string
177
     */
178
    private function getHostname($device)
179
    {
180
        $hostname = Url::deviceLink($device);
181
182
        if ($this->isDetailed()) {
183
            $hostname .= '<br />' . $device->name();
184
        }
185
186
        return $hostname;
187
    }
188
189
    /**
190
     * @param Device $device
191
     * @return string
192
     */
193
    private function getOsText($device)
194
    {
195
        $device->loadOs();
196
        $os_text = Config::getOsSetting($device->os, 'text');
197
198
        if ($this->isDetailed()) {
199
            $os_text .= '<br />' . $device->version . ($device->features ? " ($device->features)" : '');
200
        }
201
202
        return $os_text;
203
    }
204
205
    /**
206
     * @param Device $device
207
     * @return string
208
     */
209
    private function getMetrics($device)
210
    {
211
        $port_count = $device->ports()->count();
212
        $sensor_count = $device->sensors()->count();
213
        $wireless_count = $device->wirelessSensors()->count();
214
215
        $metrics = [];
216
        if ($port_count) {
217
            $metrics[] = $this->formatMetric($device, $port_count, 'ports', 'fa-link');
218
        }
219
220
        if ($sensor_count) {
221
            $metrics[] = $this->formatMetric($device, $sensor_count, 'health', 'fa-dashboard');
222
        }
223
224
        if ($wireless_count) {
225
            $metrics[] = $this->formatMetric($device, $wireless_count, 'wireless', 'fa-wifi');
226
        }
227
228
        $glue = $this->isDetailed() ? '<br />' : ' ';
229
        $metrics_content = implode(count($metrics) == 2 ? $glue : '', $metrics);
230
        return '<div class="device-table-metrics">' . $metrics_content . '</div>';
231
    }
232
233
    /**
234
     * @param $device
235
     * @param $count
236
     * @param $tab
237
     * @param $icon
238
     * @return string
239
     */
240
    private function formatMetric($device, $count, $tab, $icon)
241
    {
242
        $html = '<a href="' . Url::deviceUrl($device, ['tab' => $tab]) . '">';
243
        $html .= '<span><i class="fa ' . $icon . ' fa-lg icon-theme"></i> ' . $count;
244
        $html .= '</span></a> ';
245
        return $html;
246
    }
247
248
    /**
249
     * @param Device $device
250
     * @return string
251
     */
252
    private function getLocation($device)
253
    {
254
        if ($device->location) {
255
            if (extension_loaded('mbstring')) {
256
                return mb_substr($device->location->location, 0, 32, 'utf8');
257
            } else {
258
                return substr($device->location->location, 0, 32);
259
            }
260
        }
261
262
        return '';
263
    }
264
265
    /**
266
     * @param Device $device
267
     * @return string
268
     */
269
    private function getActions($device)
270
    {
271
        $actions = '<div class="container-fluid"><div class="row">';
272
        $actions .= '<div class="col-xs-1"><a href="' . Url::deviceUrl($device) . '"> <i class="fa fa-id-card fa-lg icon-theme" title="View device"></i></a></div>';
273
        $actions .= '<div class="col-xs-1"><a href="' . Url::deviceUrl($device, ['tab' => 'alerts']) . '"> <i class="fa fa-exclamation-circle fa-lg icon-theme" title="View alerts"></i></a></div>';
274
275
        if (\Auth::user()->hasGlobalAdmin()) {
276
            $actions .= '<div class="col-xs-1"><a href="' . Url::deviceUrl($device, ['tab' => 'edit']) . '"> <i class="fa fa-pencil fa-lg icon-theme" title="Edit device"></i></a></div>';
277
        }
278
279
        if ($this->isDetailed()) {
280
            $actions .= '</div><div class="row">';
281
        }
282
283
        $actions .= '<div class="col-xs-1"><a href="telnet://' . $device->hostname . '"><i class="fa fa-terminal fa-lg icon-theme" title="Telnet to ' . $device->hostname . '"></i></a></div>';
284
285
        if ($server = Config::get('gateone.server')) {
286
            if (Config::get('gateone.use_librenms_user')) {
287
                $actions .= '<div class="col-xs-1"><a href="' . $server . '?ssh=ssh://' . \Auth::user()->username . '@' . $device->hostname . '&location=' . $device->hostname . '" target="_blank" rel="noopener"><i class="fa fa-lock fa-lg icon-theme" title="SSH to ' . $device->hostname . '"></i></a></div>';
288
            } else {
289
                $actions .= '<div class="col-xs-1"><a href="' . $server . '?ssh=ssh://' . $device->hostname . '&location=' . $device->hostname . '" target="_blank" rel="noopener"><i class="fa fa-lock fa-lg icon-theme" title="SSH to ' . $device->hostname . '"></i></a></div>';
290
            }
291
        } else {
292
            $actions .= '<div class="col-xs-1"><a href="ssh://' . $device->hostname . '"><i class="fa fa-lock fa-lg icon-theme" title="SSH to ' . $device->hostname . '"></i></a></div>';
293
        }
294
295
        $actions .= '<div class="col-xs-1"><a href="https://' . $device->hostname . '" onclick="http_fallback(this); return false;" target="_blank" rel="noopener"><i class="fa fa-globe fa-lg icon-theme" title="Launch browser https://' . $device->hostname . '"></i></a></div>';
296
        $actions .= '</div></div>';
297
298
        return $actions;
299
    }
300
}
301