Skip to content

Commit

Permalink
Port pages fixes and cleanups (librenms#14310)
Browse files Browse the repository at this point in the history
* Port pages fixes and cleanups
Fix mac display on device port page
Move ports query building into the graph page where it is used
Add the filter ui to the all ports graphs pages

* whitespace
  • Loading branch information
murrant authored Sep 7, 2022
1 parent 8a4d803 commit ae15c8e
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 168 deletions.
21 changes: 8 additions & 13 deletions includes/html/pages/device/ports.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,25 +144,20 @@

$i = '1';

global $port_cache, $port_index_cache;
global $port_index_cache;

$ports = dbFetchRows("SELECT * FROM `ports` WHERE `device_id` = ? AND `deleted` = '0' AND `disabled` = 0 ORDER BY `ifIndex` ASC", [$device['device_id']]);
// As we've dragged the whole database, lets pre-populate our caches :)
// FIXME - we should probably split the fetching of link/stack/etc into functions and cache them here too to cut down on single row queries.
/** @var \Illuminate\Support\Collection<\App\Models\Port> $ports */
$ports = DeviceCache::getPrimary()->ports()->orderBy('ifIndex')->isValid()->get();

// As we've dragged the whole database, lets pre-populate our caches :)
foreach ($ports as $key => $port) {
$port_cache[$port['port_id']] = $port;
$port_index_cache[$port['device_id']][$port['ifIndex']] = $port;
$ports[$key]['ifOctets_rate'] = $port['ifInOctets_rate'] + $port['ifOutOctets_rate'];
}

switch ($vars['sort'] ?? '') {
case 'traffic':
$ports = array_sort_by_column($ports, 'ifOctets_rate', SORT_DESC);
break;
default:
$ports = array_sort_by_column($ports, 'ifIndex', SORT_ASC);
break;
if (isset($vars['sort']) && $vars['sort'] == 'traffic') {
$ports = $ports->sortByDesc(function (Port $port) {
return $port->ifInOctets_rate + $port->ifOutOctets_rate;
});
}

foreach ($ports as $port) {
Expand Down
169 changes: 16 additions & 153 deletions includes/html/pages/ports.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
$vars['format'] = 'list_basic';
}

$displayLists = '';
$displayLists .= '<span style="font-weight: bold;">Ports lists</span> &#187; ';
$displayLists = '<span style="font-weight: bold;">Ports lists</span> &#187; ';

$menu_options = ['basic' => 'Basic', 'detail' => 'Detail'];

Expand Down Expand Up @@ -86,8 +85,7 @@
$displayLists .= '</div>';

if ((isset($vars['searchbar']) && $vars['searchbar'] != 'hide') || ! isset($vars['searchbar'])) {
$output = "<div class='pull-left'>";
$output .= "<form method='post' action='' class='form-inline' role='form'>";
$output = "<form method='post' action='' class='form-inline' role='form'>";
$output .= addslashes(csrf_field());
$output .= "<div style='margin-bottom:4px;text-align:left;'>";
$output .= "<div class='form-group'>";
Expand Down Expand Up @@ -268,11 +266,8 @@
$output .= '</div>';

$output .= '</form>';
$output .= '</div>';
}

$param = [];

if (! isset($vars['ignore'])) {
$vars['ignore'] = '0';
}
Expand All @@ -283,158 +278,26 @@
$vars['deleted'] = '0';
}

$where = '';
$ignore_filter = 0;
$disabled_filter = 0;

foreach ($vars as $var => $value) {
if ($value != '') {
switch ($var) {
case 'hostname':
$where .= ' AND D.hostname LIKE ?';
$param[] = '%' . $value . '%';
break;
case 'location':
if (is_int($value)) {
$where .= ' AND L.id = ?';
$param[] = $value;
} else {
$where .= ' AND L.location LIKE ?';
$param[] = '%' . $value . '%';
}
break;
case 'device_id':
$where .= ' AND D.device_id = ?';
$param[] = $value;
break;
case 'deleted':
if ($value == 1 || $value == 'yes') {
$where .= ' AND `I`.`deleted` = 1';
$ignore_filter = 1;
}
break;
case 'ignore':
if ($value == 1 || $value == 'yes') {
$where .= ' AND (I.ignore = 1 OR D.ignore = 1) AND I.deleted = 0';
$ignore_filter = 1;
}
break;
case 'disabled':
if ($value == 1 || $value == 'yes') {
$where .= ' AND `I`.`disabled` = 1 AND `I`.`deleted` = 0';
$disabled_filter = 1;
}
break;
case 'ifSpeed':
if (is_numeric($value)) {
$where .= " AND I.$var = ?";
$param[] = $value;
}
break;
case 'ifType':
$where .= " AND I.$var = ?";
$param[] = $value;
break;
case 'ifAlias':
case 'port_descr_type':
$where .= " AND I.$var LIKE ?";
$param[] = '%' . $value . '%';
break;
case 'errors':
if ($value == 1 || $value == 'yes') {
$where .= " AND (I.`ifInErrors_delta` > '0' OR I.`ifOutErrors_delta` > '0')";
}
break;
case 'state':
if ($value == 'down') {
$where .= ' AND I.ifAdminStatus = ? AND I.ifOperStatus = ?';
$param[] = 'up';
$param[] = 'down';
} elseif ($value == 'up') {
$where .= ' AND I.ifAdminStatus = ? AND I.ifOperStatus = ?';
$param[] = 'up';
$param[] = 'up';
} elseif ($value == 'admindown') {
$where .= ' AND I.ifAdminStatus = ? AND D.ignore = 0';
$param[] = 'down';
}
break;
case 'purge':
if ($vars['purge'] === 'all') {
Port::hasAccess(Auth::user())->with(['device' => function ($query) {
$query->select('device_id', 'hostname');
}])->isDeleted()->chunk(100, function ($ports) {
foreach ($ports as $port) {
$port->delete();
}
});
} else {
try {
Port::hasAccess(Auth::user())->where('port_id', $vars['purge'])->firstOrFail()->delete();
} catch (ModelNotFoundException $e) {
echo "<div class='alert alert-danger'>Port ID {$vars['purge']} not found! Could not purge port.</div>";
}
}
break;
case 'group':
$where .= ' AND port_id IN (SELECT `port_id` FROM `port_group_port` WHERE `port_group_id` = ?)';
$param[] = $vars['group'];
break;
if (isset($vars['purge'])) {
if ($vars['purge'] === 'all') {
Port::hasAccess(Auth::user())->with(['device' => function ($query) {
$query->select('device_id', 'hostname');
}])->isDeleted()->chunk(100, function ($ports) {
foreach ($ports as $port) {
$port->delete();
}
});
} else {
try {
Port::hasAccess(Auth::user())->where('port_id', $vars['purge'])->firstOrFail()->delete();
} catch (ModelNotFoundException $e) {
echo "<div class='alert alert-danger'>Port ID {$vars['purge']} not found! Could not purge port.</div>";
}
}
}

if ($ignore_filter == 0 && $disabled_filter == 0) {
$where .= ' AND `I`.`ignore` = 0 AND `I`.`disabled` = 0 AND `I`.`deleted` = 0';
}

$query = 'SELECT * FROM `ports` AS I, `devices` AS D LEFT JOIN `locations` AS L ON D.location_id = L.id WHERE I.device_id = D.device_id' . $where;
$row = 1;

[$format, $subformat] = explode('_', basename($vars['format']));

// only grab list of ports for graph pages, table uses ajax
$ports = $format == 'graph' ? dbFetchRows($query, $param) : [];

switch ($vars['sort'] ?? '') {
case 'traffic':
$ports = array_sort_by_column($ports, 'ifOctets_rate', SORT_DESC);
break;
case 'traffic_in':
$ports = array_sort_by_column($ports, 'ifInOctets_rate', SORT_DESC);
break;
case 'traffic_out':
$ports = array_sort_by_column($ports, 'ifOutOctets_rate', SORT_DESC);
break;
case 'packets':
$ports = array_sort_by_column($ports, 'ifUcastPkts_rate', SORT_DESC);
break;
case 'packets_in':
$ports = array_sort_by_column($ports, 'ifInUcastOctets_rate', SORT_DESC);
break;
case 'packets_out':
$ports = array_sort_by_column($ports, 'ifOutUcastOctets_rate', SORT_DESC);
break;
case 'errors':
$ports = array_sort_by_column($ports, 'ifErrors_rate', SORT_DESC);
break;
case 'speed':
$ports = array_sort_by_column($ports, 'ifSpeed', SORT_DESC);
break;
case 'port':
$ports = array_sort_by_column($ports, 'ifDescr', SORT_ASC);
break;
case 'media':
$ports = array_sort_by_column($ports, 'ifType', SORT_ASC);
break;
case 'descr':
$ports = array_sort_by_column($ports, 'ifAlias', SORT_ASC);
break;
case 'device':
default:
$ports = array_sort_by_column($ports, 'hostname', SORT_ASC);
}

if (file_exists('includes/html/pages/ports/' . $format . '.inc.php')) {
require 'includes/html/pages/ports/' . $format . '.inc.php';
}
138 changes: 138 additions & 0 deletions includes/html/pages/ports/graph.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,144 @@
echo $displayLists;
echo '</div>';
echo '<div class="panel-body">';
echo '<div style="padding-bottom: 10px;">';
echo stripcslashes($output);
echo '</div>';

$param = [];
$where = '';
$ignore_filter = 0;
$disabled_filter = 0;

foreach ($vars as $var => $value) {
if ($value != '') {
switch ($var) {
case 'hostname':
$where .= ' AND D.hostname LIKE ?';
$param[] = '%' . $value . '%';
break;
case 'location':
if (is_int($value)) {
$where .= ' AND L.id = ?';
$param[] = $value;
} else {
$where .= ' AND L.location LIKE ?';
$param[] = '%' . $value . '%';
}
break;
case 'device_id':
$where .= ' AND D.device_id = ?';
$param[] = $value;
break;
case 'deleted':
if ($value == 1 || $value == 'yes') {
$where .= ' AND `I`.`deleted` = 1';
$ignore_filter = 1;
}
break;
case 'ignore':
if ($value == 1 || $value == 'yes') {
$where .= ' AND (I.ignore = 1 OR D.ignore = 1) AND I.deleted = 0';
$ignore_filter = 1;
}
break;
case 'disabled':
if ($value == 1 || $value == 'yes') {
$where .= ' AND `I`.`disabled` = 1 AND `I`.`deleted` = 0';
$disabled_filter = 1;
}
break;
case 'ifSpeed':
if (is_numeric($value)) {
$where .= " AND I.$var = ?";
$param[] = $value;
}
break;
case 'ifType':
$where .= " AND I.$var = ?";
$param[] = $value;
break;
case 'ifAlias':
case 'port_descr_type':
$where .= " AND I.$var LIKE ?";
$param[] = '%' . $value . '%';
break;
case 'errors':
if ($value == 1 || $value == 'yes') {
$where .= " AND (I.`ifInErrors_delta` > '0' OR I.`ifOutErrors_delta` > '0')";
}
break;
case 'state':
if ($value == 'down') {
$where .= ' AND I.ifAdminStatus = ? AND I.ifOperStatus = ?';
$param[] = 'up';
$param[] = 'down';
} elseif ($value == 'up') {
$where .= ' AND I.ifAdminStatus = ? AND I.ifOperStatus = ?';
$param[] = 'up';
$param[] = 'up';
} elseif ($value == 'admindown') {
$where .= ' AND I.ifAdminStatus = ? AND D.ignore = 0';
$param[] = 'down';
}
break;
case 'group':
$where .= ' AND port_id IN (SELECT `port_id` FROM `port_group_port` WHERE `port_group_id` = ?)';
$param[] = $vars['group'];
break;
}
}
}

if ($ignore_filter == 0 && $disabled_filter == 0) {
$where .= ' AND `I`.`ignore` = 0 AND `I`.`disabled` = 0 AND `I`.`deleted` = 0';
}

$query = 'SELECT * FROM `ports` AS I, `devices` AS D LEFT JOIN `locations` AS L ON D.location_id = L.id WHERE I.device_id = D.device_id' . $where;

// only grab list of ports for graph pages, table uses ajax
$ports = array_map(function ($value) {
return (array) $value;
}, DB::select($query, $param));

switch ($vars['sort'] ?? '') {
case 'traffic':
$ports = array_sort_by_column($ports, 'ifOctets_rate', SORT_DESC);
break;
case 'traffic_in':
$ports = array_sort_by_column($ports, 'ifInOctets_rate', SORT_DESC);
break;
case 'traffic_out':
$ports = array_sort_by_column($ports, 'ifOutOctets_rate', SORT_DESC);
break;
case 'packets':
$ports = array_sort_by_column($ports, 'ifUcastPkts_rate', SORT_DESC);
break;
case 'packets_in':
$ports = array_sort_by_column($ports, 'ifInUcastOctets_rate', SORT_DESC);
break;
case 'packets_out':
$ports = array_sort_by_column($ports, 'ifOutUcastOctets_rate', SORT_DESC);
break;
case 'errors':
$ports = array_sort_by_column($ports, 'ifErrors_rate', SORT_DESC);
break;
case 'speed':
$ports = array_sort_by_column($ports, 'ifSpeed', SORT_DESC);
break;
case 'port':
$ports = array_sort_by_column($ports, 'ifDescr', SORT_ASC);
break;
case 'media':
$ports = array_sort_by_column($ports, 'ifType', SORT_ASC);
break;
case 'descr':
$ports = array_sort_by_column($ports, 'ifAlias', SORT_ASC);
break;
case 'device':
default:
$ports = array_sort_by_column($ports, 'hostname', SORT_ASC);
}

foreach ($ports as $port) {
$speed = \LibreNMS\Util\Number::formatSi($port['ifSpeed'], 2, 3, 'bps');
Expand Down
2 changes: 1 addition & 1 deletion includes/html/pages/ports/list.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,6 @@ function formatUnits(units,decimals,display,base) {
url: '<?php echo route('table.ports') ?>'
});

$(".actionBar").append("<?php echo $output; ?>");
$(".actionBar").append("<div class=\"pull-left\"><?php echo $output; ?></div>");

</script>
Loading

0 comments on commit ae15c8e

Please sign in to comment.