diff --git a/app/Http/Controllers/Table/DeviceController.php b/app/Http/Controllers/Table/DeviceController.php index 8efae96b59..4aa5281d34 100644 --- a/app/Http/Controllers/Table/DeviceController.php +++ b/app/Http/Controllers/Table/DeviceController.php @@ -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 = '
'; - $actions .= ''; - $actions .= ''; + $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 .= ''; + $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 .= '
'; - } - - $actions .= '
'; + $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 .= '
'; - } else { - $actions .= '
'; - } - } else { - $actions .= '
'; + $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 .= '
'; - $actions .= '
'; + $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; } diff --git a/doc/Extensions/Customizing-the-Web-UI.md b/doc/Extensions/Customizing-the-Web-UI.md index 2661e10b66..32ee8e30d5 100644 --- a/doc/Extensions/Customizing-the-Web-UI.md +++ b/doc/Extensions/Customizing-the-Web-UI.md @@ -30,18 +30,76 @@ Example contents: ``` -## 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:` +!!! 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 -```php -$config['html']['device']['links'][] = ['url' => 'http://atssrv/open-audit/index/devices/{{ $device[\'sysName\'] }}', 'title' => 'Open-AudIT']; ``` +[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 /webui/device + +!!! 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 | + diff --git a/includes/html/pages/devices.inc.php b/includes/html/pages/devices.inc.php index 542aca949b..98382ebc2c 100644 --- a/includes/html/pages/devices.inc.php +++ b/includes/html/pages/devices.inc.php @@ -302,7 +302,7 @@ if ($format == 'graph') { Operating System Up/Down Time Location - Actions + Actions diff --git a/misc/config_definitions.json b/misc/config_definitions.json index 8540b3ceb2..73d8b62ef3 100644 --- a/misc/config_definitions.json +++ b/misc/config_definitions.json @@ -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", diff --git a/resources/views/device/action-icon.blade.php b/resources/views/device/action-icon.blade.php new file mode 100644 index 0000000000..123f8ccf7a --- /dev/null +++ b/resources/views/device/action-icon.blade.php @@ -0,0 +1,5 @@ +
+ + + +
diff --git a/resources/views/device/actions.blade.php b/resources/views/device/actions.blade.php new file mode 100644 index 0000000000..d008f7301a --- /dev/null +++ b/resources/views/device/actions.blade.php @@ -0,0 +1,9 @@ +
+ @foreach($actions as $row) +
+ @foreach($row as $action) + @include('device.action-icon', $action) + @endforeach +
+ @endforeach +