Allow device actions to appear in device list and improve docs (#13177)

* Improve Device menu links and documentation

* device list actions functionality

* phpstan :/
This commit is contained in:
Tony Murray
2021-08-27 22:48:57 -05:00
committed by GitHub
parent 9b8b1b814a
commit 94ee737f3d
6 changed files with 147 additions and 31 deletions

View File

@@ -27,6 +27,7 @@ namespace App\Http\Controllers\Table;
use App\Models\Device;
use App\Models\Location;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use LibreNMS\Config;
use LibreNMS\Util\Rewrite;
@@ -150,7 +151,7 @@ class DeviceController extends TableController
'os' => $this->getOsText($device),
'uptime' => (! $device->status && ! $device->last_polled) ? __('Never polled') : Time::formatInterval($device->status ? $device->uptime : $device->last_polled->diffInSeconds(), 'short'),
'location' => $this->getLocation($device),
'actions' => $this->getActions($device),
'actions' => view('device.actions', ['actions' => $this->getActions($device)])->__toString(),
'device_id' => $device->device_id,
];
}
@@ -282,38 +283,68 @@ class DeviceController extends TableController
: substr($device->location, 0, 32);
}
/**
* @param Device $device
* @return string
*/
private function getActions($device)
private function getActions(Device $device): array
{
$actions = '<div class="container-fluid"><div class="row">';
$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>';
$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>';
$actions = [
[
[
'title' => 'View Device',
'href' => Url::deviceUrl($device),
'icon' => 'fa-id-card',
'external' => false,
],
[
'title' => 'View alerts',
'href' => Url::deviceUrl($device, ['tab' => 'alerts']),
'icon' => 'fa-exclamation-circle',
'external' => false,
],
],
];
if (\Auth::user()->hasGlobalAdmin()) {
$actions .= '<div class="col-xs-1"><a href="' . Url::deviceUrl($device, ['tab' => 'edit']) . '"> <i class="fa fa-gear fa-lg icon-theme" title="Edit device"></i></a></div>';
$actions[0][] = [
'title' => 'Edit device',
'href' => Url::deviceUrl($device, ['tab' => 'edit']),
'icon' => 'fa-gear',
'external' => false,
];
}
$row = $this->isDetailed() ? 1 : 0;
if ($this->isDetailed()) {
$actions .= '</div><div class="row">';
}
$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>';
$actions[$row][] = [
'title' => 'Telnet to ' . $device->hostname,
'href' => 'telnet://' . $device->hostname,
'icon' => 'fa-terminal',
];
$ssh_href = 'ssh://' . $device->hostname;
if ($server = Config::get('gateone.server')) {
if (Config::get('gateone.use_librenms_user')) {
$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>';
} else {
$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>';
}
} else {
$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>';
$ssh_href = Config::get('gateone.use_librenms_user')
? $server . '?ssh=ssh://' . Auth::user()->username . '@' . $device->hostname . '&location=' . $device->hostname
: $server . '?ssh=ssh://' . $device->hostname . '&location=' . $device->hostname;
}
$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>';
$actions .= '</div></div>';
$actions[$row][] = [
'title' => 'SSH to ' . $device->hostname,
'href' => $ssh_href,
'icon' => 'fa-lock',
];
$actions[$row][] = [
'title' => 'Launch browser to ' . $device->hostname,
'href' => 'https://' . $device->hostname,
'onclick' => 'http_fallback(this); return false;',
'icon' => 'fa-globe',
];
foreach (array_values(Arr::wrap(Config::get('html.device.links'))) as $index => $custom) {
if ($custom['action'] ?? false) {
$row = $this->isDetailed() ? $index % 2 : 0;
$custom['href'] = view(['template' => $custom['url']], ['device' => $device])->__toString(); // @phpstan-ignore-line
$actions[$row][] = $custom;
}
}
return $actions;
}

View File

@@ -30,18 +30,76 @@ Example contents:
</li>
```
## Custom device menu entry
## Custom device menu action
You can add custom external links in the menu on the device page.
This feature allows you to easily link applications to related
systems, as shown in the example of Open-audIT.
The Links value is parsed by Laravel Blade's templating engine so you
can use Device variables such as `hostname`, `sysName` and more.
The url value is parsed by the [Laravel Blade](https://laravel.com/docs/blade) templating engine. You
can access device variables such as `$device->hostname`, `$device->sysName` and use full PHP.
`config.php:`
```php
$config['html']['device']['links'][] = ['url' => 'http://atssrv/open-audit/index/devices/{{ $device[\'sysName\'] }}', 'title' => 'Open-AudIT'];
!!! setting "webui/device"
```bash
lnms config:set html.device.links.+ '{"url": "http://atssrv/open-audit/index/devices/{{ $device->sysName }}", "title": "Open-AudIT"}'
```
| Field | Description |
| ---- | ----------- |
| url | Url blade template resulting in valid url. Required. |
| title | Title text displayed in the menu. Required. |
| icon | [Font Awesome icon](https://fontawesome.com/v4.7/icons/) class. Default: fa-external-link |
| external | Open link in new window. Default: true |
| action | Show as action on device list. Default: false |
### Launching Windows programs from the LibreNMS device menu
You can launch windows programs from links in LibreNMS, but it does take
some registry entries on the client device
```
[HKEY_CLASSES_ROOT\winbox]
@= '@="URL:winbox Protocol"'=@
"URL Protocol"=""
[HKEY_CLASSES_ROOT\winbox\shell]
[HKEY_CLASSES_ROOT\winbox\shell\open]
[HKEY_CLASSES_ROOT\winbox\shell\open\command]
@= '@="c:\winbox.exe" "%1"' =@
```
Now we can use that in the device menu entry to open winbox
!!! setting "webui/device"
```bash
lnms config:set html.device.links.+ '{"url": "winbox://{{ $device->ip }}", "title": "Winbox"}'
```
## Setting the primary device menu action
You can change the icon that is clickable in the device without having to open the dropdown menu.
The primary button is edit device by default.
Web UI <span class="setting-link">/webui/device</span>
!!! setting "webui/device"
```bash
lnms config:set html.device.primary_link web
```
| Value | Description |
| ----- | ----------- |
| edit | Edit device |
| web | Connect to the device via https/http |
| ssh | launch ssh:// protocol to the device, make sure you have a handler registered |
| telnet | launch telnet:// protocol to the device |
| capture | Link to the device capture page |
| custom1 | Custom Link 1 |
| custom2 | Custom Link 2 |
| custom3 | Custom Link 3 |
| custom4 | Custom Link 4 |
| custom5 | Custom Link 5 |
| custom6 | Custom Link 6 |
| custom7 | Custom Link 7 |
| custom8 | Custom Link 8 |

View File

@@ -302,7 +302,7 @@ if ($format == 'graph') {
<th data-column-id="os">Operating System</th>
<th data-column-id="uptime" data-formatter="uptime">Up/Down Time</th>
<th data-column-id="location" data-visible="<?php echo $detailed ? 'true' : 'false'; ?>">Location</th>
<th data-column-id="actions" data-width="<?php echo $detailed ? '90px' : '200px'; ?>" data-sortable="false" data-searchable="false" data-header-css-class="device-table-header-actions">Actions</th>
<th data-column-id="actions" data-width="<?php echo $detailed ? '120px' : '240px'; ?>" data-sortable="false" data-searchable="false" data-header-css-class="device-table-header-actions">Actions</th>
</tr>
</thead>
</table>

View File

@@ -3435,6 +3435,19 @@
"new": "New"
}
},
"html.device.links": {
"default": [],
"type": "array",
"validate": {
"value": "array",
"value.*": "object",
"value.*.action": "boolean",
"value.*.icon": "string",
"value.*.external": "boolean",
"value.*.title": "required|string",
"value.*.url": "required|string"
}
},
"html.device.primary_link": {
"group": "webui",
"section": "device",

View File

@@ -0,0 +1,5 @@
<div class="col-xs-1">
<a href="{{ $href }}" @if($external ?? true)target="_blank" rel="noopener" @endif title="{{ $title }}">
<i class="fa fa-lg icon-theme {{ $icon ?? 'fa-external-link' }}"></i>
</a>
</div>

View File

@@ -0,0 +1,9 @@
<div class="container-fluid" style="padding-left: 0; padding-right: 0;">
@foreach($actions as $row)
<div class="row" style="padding-bottom: 5px">
@foreach($row as $action)
@include('device.action-icon', $action)
@endforeach
</div>
@endforeach
</div>