mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Added global VLAN ports page (#16415)
* Global VLAN ports page * Show a list of devices too * Fix a little theme color issues * oops * Just put css in the theme * Apply fixes from StyleCI --------- Co-authored-by: Tony Murray <murrant@users.noreply.github.com> Co-authored-by: Neil Lathwood <gh+n@laf.io>
This commit is contained in:
67
app/Http/Controllers/Table/VlanDevicesController.php
Normal file
67
app/Http/Controllers/Table/VlanDevicesController.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Table;
|
||||
|
||||
use App\Models\Device;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use LibreNMS\Util\Url;
|
||||
|
||||
class VlanDevicesController extends TableController
|
||||
{
|
||||
protected function sortFields($request)
|
||||
{
|
||||
return [
|
||||
'device' => 'device_id',
|
||||
'ports_count',
|
||||
'domain' => 'vlans.vlan_domain',
|
||||
'name' => 'vlans.vlan_name',
|
||||
'type' => 'vlans.vlan_type',
|
||||
'mtu' => 'vlans.vlan_mtu',
|
||||
];
|
||||
}
|
||||
|
||||
private int $vlanId;
|
||||
|
||||
protected function baseQuery(Request $request)
|
||||
{
|
||||
$this->validate($request, ['vlan' => 'integer']);
|
||||
$this->vlanId = $request->get('vlan', 1);
|
||||
|
||||
return Device::distinct()
|
||||
->select([
|
||||
'devices.*',
|
||||
'vlans.vlan_name',
|
||||
'vlans.vlan_type',
|
||||
'vlans.vlan_mtu',
|
||||
])
|
||||
->withCount(['ports' => function ($query) {
|
||||
$query->distinct()->where('ifVlan', $this->vlanId)
|
||||
->orWhereHas('vlans', fn ($q) => $q->where('vlan', $this->vlanId));
|
||||
}])
|
||||
->where(function ($query) {
|
||||
$query->where('vlans.vlan_vlan', $this->vlanId)
|
||||
->orWhereHas('ports', fn ($q) => $q->where('ifVlan', $this->vlanId));
|
||||
})
|
||||
->leftJoin('vlans', function ($join) {
|
||||
$join->on('devices.device_id', '=', 'vlans.device_id')
|
||||
->on('vlans.vlan_vlan', '=', DB::raw($this->vlanId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Device $model
|
||||
*/
|
||||
public function formatItem($model): array
|
||||
{
|
||||
return [
|
||||
'device' => Url::deviceLink($model),
|
||||
'ports_count' => $model->ports_count,
|
||||
// left joined fields
|
||||
'domain' => $model['vlan_domain'],
|
||||
'name' => $model['vlan_name'],
|
||||
'type' => $model['vlan_type'],
|
||||
'mtu' => $model['vlan_mtu'],
|
||||
];
|
||||
}
|
||||
}
|
68
app/Http/Controllers/Table/VlanPortsController.php
Normal file
68
app/Http/Controllers/Table/VlanPortsController.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Table;
|
||||
|
||||
use App\Models\Port;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use LibreNMS\Util\Url;
|
||||
|
||||
class VlanPortsController extends TableController
|
||||
{
|
||||
protected function sortFields($request): array
|
||||
{
|
||||
return [
|
||||
'device' => 'device_id',
|
||||
'port' => 'port_id',
|
||||
'untagged',
|
||||
'state' => 'ports_vlans.state',
|
||||
'cost' => 'ports_vlans.cost',
|
||||
];
|
||||
}
|
||||
|
||||
private int $vlanId;
|
||||
|
||||
protected function baseQuery(Request $request): Builder
|
||||
{
|
||||
$this->validate($request, ['vlan' => 'integer']);
|
||||
$this->vlanId = $request->get('vlan', 1);
|
||||
|
||||
return Port::with('device')
|
||||
->leftJoin('ports_vlans', 'ports.port_id', 'ports_vlans.port_id')
|
||||
->where(function ($query) {
|
||||
$query->where('ifVlan', $this->vlanId)
|
||||
->orWhere('ports_vlans.vlan', $this->vlanId);
|
||||
})
|
||||
->select([
|
||||
'ports.port_id',
|
||||
'ports.device_id',
|
||||
'ports.ifName',
|
||||
'ports.ifIndex',
|
||||
'ports.ifDescr',
|
||||
'ports.ifAlias',
|
||||
'ports.ifVlan',
|
||||
'ports.ifAdminStatus',
|
||||
'ports.ifOperStatus',
|
||||
'ports_vlans.untagged',
|
||||
'ports_vlans.state',
|
||||
'ports_vlans.cost',
|
||||
DB::raw("CASE WHEN ports.ifVlan = $this->vlanId or ports_vlans.untagged <> 0 THEN \"yes\" ELSE \"no\" END as untagged"),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Port $model
|
||||
*/
|
||||
public function formatItem($model): array
|
||||
{
|
||||
return [
|
||||
'device' => Url::deviceLink($model->device),
|
||||
'port' => Url::portLink($model),
|
||||
// left joined columns
|
||||
'untagged' => $model['untagged'],
|
||||
'state' => $model['state'],
|
||||
'cost' => $model['cost'],
|
||||
];
|
||||
}
|
||||
}
|
19
app/Http/Controllers/VlansController.php
Normal file
19
app/Http/Controllers/VlansController.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Vlan;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
class VlansController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
return view('vlans.index', [
|
||||
'vlanIds' => Vlan::distinct()
|
||||
->where('vlan_vlan', '>', 0)
|
||||
->orderBy('vlan_vlan')
|
||||
->pluck('vlan_vlan'),
|
||||
]);
|
||||
}
|
||||
}
|
@@ -123,6 +123,11 @@
|
||||
}
|
||||
|
||||
.devices-graphs-select {
|
||||
margin-right: 5px;
|
||||
margin-right: 5px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.panel-title select {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
@@ -322,6 +322,9 @@
|
||||
</a></li>
|
||||
@endif
|
||||
|
||||
<li><a href="{{ route('vlans.index') }}"><i class="fa fa-tasks fa-fw fa-lg"
|
||||
aria-hidden="true"></i> {{ __('VLANs') }}</a></li>
|
||||
|
||||
@config('enable_billing')
|
||||
<li><a href="{{ url('bills') }}"><i class="fa fa-money fa-fw fa-lg"
|
||||
aria-hidden="true"></i> {{ __('Traffic Bills') }}</a></li>
|
||||
|
75
resources/views/vlans/index.blade.php
Normal file
75
resources/views/vlans/index.blade.php
Normal file
@@ -0,0 +1,75 @@
|
||||
@extends('layouts.librenmsv1')
|
||||
|
||||
@section('title', __('Vlans'))
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<x-panel body-class="!tw-p-0">
|
||||
<x-slot name="heading">
|
||||
<h2 class="panel-title">{{ __('VLAN') }}
|
||||
<select id="vlan-select">
|
||||
@foreach($vlanIds as $vlanId)
|
||||
<option>{{ $vlanId }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</h2>
|
||||
</x-slot>
|
||||
|
||||
<x-tabs>
|
||||
<x-tab name="{{ __('Devices') }}">
|
||||
<table id="vlan-devices" class="table table-hover table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="device">{{ __('Device') }}</th>
|
||||
<th data-column-id="ports_count">{{ __('Ports') }}</th>
|
||||
<th data-column-id="name">{{ __('Local Name') }}</th>
|
||||
<th data-column-id="domain" data-visible="false">{{ __('Domain') }}</th>
|
||||
<th data-column-id="type">{{ __('Type') }}</th>
|
||||
<th data-column-id="mtu">{{ __('MTU') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</x-tab>
|
||||
<x-tab value="image" name="{{ __('Ports') }}">
|
||||
<table id="vlan-ports" class="table table-hover table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="device">{{ __('Device') }}</th>
|
||||
<th data-column-id="port">{{ __('Port') }}</th>
|
||||
<th data-column-id="untagged">{{ __('Untagged') }}</th>
|
||||
<th data-column-id="state">{{ __('State') }}</th>
|
||||
<th data-column-id="cost">{{ __('Cost') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</x-tab>
|
||||
</x-tabs>
|
||||
</x-panel>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
var vlan_id = {{ (int) $vlanIds->first() }};
|
||||
var grid = $("#vlan-ports").bootgrid({
|
||||
ajax: true,
|
||||
post: function () {
|
||||
return {vlan: vlan_id}
|
||||
},
|
||||
url: "{{ route('table.vlan-ports') }}"
|
||||
});
|
||||
var grid = $("#vlan-devices").bootgrid({
|
||||
ajax: true,
|
||||
post: function () {
|
||||
return {vlan: vlan_id}
|
||||
},
|
||||
url: "{{ route('table.vlan-devices') }}"
|
||||
});
|
||||
|
||||
$('#vlan-select').on('change', function () {
|
||||
vlan_id = this.value;
|
||||
$("#vlan-ports").bootgrid('reload');
|
||||
$("#vlan-devices").bootgrid('reload');
|
||||
});
|
||||
</script>
|
||||
@endpush
|
@@ -46,6 +46,7 @@ Route::middleware(['auth'])->group(function () {
|
||||
Route::any('inventory', \App\Http\Controllers\InventoryController::class)->name('inventory');
|
||||
Route::get('inventory/purge', [\App\Http\Controllers\InventoryController::class, 'purge'])->name('inventory.purge');
|
||||
Route::resource('port', 'PortController')->only('update');
|
||||
Route::get('vlans', [\App\Http\Controllers\VlansController::class, 'index'])->name('vlans.index');
|
||||
Route::prefix('poller')->group(function () {
|
||||
Route::get('', 'PollerController@pollerTab')->name('poller.index');
|
||||
Route::get('log', 'PollerController@logTab')->name('poller.log');
|
||||
@@ -215,6 +216,8 @@ Route::middleware(['auth'])->group(function () {
|
||||
Route::post('routes', 'RoutesTablesController');
|
||||
Route::post('syslog', 'SyslogController');
|
||||
Route::post('tnmsne', 'TnmsneController')->name('table.tnmsne');
|
||||
Route::post('vlan-ports', 'VlanPortsController')->name('table.vlan-ports');
|
||||
Route::post('vlan-devices', 'VlanDevicesController')->name('table.vlan-devices');
|
||||
Route::post('vminfo', 'VminfoController');
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user