webui: Paginate the all ports pages (#4401)

* feature: Paginate the all ports pages
fixes: #2705

* Stopped ports not belonging to any devices from showing up

* phpcs fix
This commit is contained in:
Tony Murray
2016-09-11 10:23:16 -05:00
committed by Neil Lathwood
parent a6ed7cc888
commit d1ae83a378
4 changed files with 264 additions and 104 deletions

View File

@@ -577,7 +577,7 @@ function generate_port_link($port, $text = null, $type = null, $overlib = 1, $si
$graph_array = array();
$port = ifNameDescr($port);
if (!$text) {
$text = fixIfName($port['label']);
$text = fixifName($port['label']);
}
if ($type) {

View File

@@ -0,0 +1,180 @@
<?php
/**
* ports.inc.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2016 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
list($sort_column, $sort_order) = explode(' ', trim($sort));
$where = "`D`.`hostname` != '' ";
$param = array();
$sql = 'FROM `ports`';
if (is_admin() === false && is_read() === false) {
$sql .= ' LEFT JOIN `devices_perms` AS `DP` ON `ports`.`device_id` = `DP`.`device_id`';
$sql .= ' LEFT JOIN `ports_perms` AS `PP` ON `ports`.`port_id` = `PP`.`port_id`';
$where .= ' AND (`DP`.`user_id`=? OR `PP`.`user_id`=?)';
$param[] = $_SESSION['user_id'];
$param[] = $_SESSION['user_id'];
}
$sql .= ' LEFT JOIN `devices` AS `D` ON `ports`.`device_id` = `D`.`device_id`';
if (!empty($_POST['hostname']) || !empty($_POST['location']) || $sort_column == 'device') {
if (!empty($_POST['hostname'])) {
$where .= ' AND `D`.`hostname` LIKE ?';
$param[] = '%' . $_POST['hostname'] . '%';
}
if (!empty($_POST['location'])) {
$where .= " AND `D`.`location` = ?";
$param[] = $_POST['location'];
}
}
$sql .= " WHERE $where ";
if (!empty($_POST['errors'])) {
$sql .= " AND (`ports`.`ifInErrors_delta` > 0 OR `ports`.`ifOutErrors_delta` > 0)";
}
if (!empty($_POST['device_id'])) {
$sql .= ' AND `ports`.`device_id`=?';
$param[] = $_POST['device_id'];
}
if (!empty($_POST['state'])) {
$sql .= ' AND `ports`.`ifOperStatus`=?';
$param[] = $_POST['state'];
}
if (!empty($_POST['ifSpeed'])) {
$sql .= ' AND `ports`.`ifSpeed`=?';
$param[] = $_POST['ifSpeed'];
}
if (!empty($_POST['ifType'])) {
$sql .= ' AND `ports`.`ifType`=?';
$param[] = $_POST['ifType'];
}
if (!empty($_POST['port_descr_type'])) {
$sql .= ' AND `ports`.`port_descr_type`=?';
$param[] = $_POST['port_descr_type'];
}
if (!empty($_POST['ifAlias'])) {
$sql .= ' AND `ports`.`ifAlias` LIKE ?';
$param[] = '%'.$_POST['ifAlias'].'%';
}
if (!empty($_POST['disabled'])) {
$sql .= ' AND `ports`.`disabled`=?';
$param[] = $_POST['disabled'];
}
if (!empty($_POST['ignore'])) {
$sql .= ' AND `ports`.`ignore`=?';
$param[] = $_POST['ignore'];
}
if (!empty($_POST['deleted'])) {
$sql .= ' AND `ports`.`deleted`=?';
$param[] = $_POST['deleted'];
}
$count_sql = "SELECT COUNT(`ports`.`port_id`) $sql";
$total = dbFetchCell($count_sql, $param);
if (empty($total)) {
$total = 0;
}
if (isset($sort) && !empty($sort)) {
if ($sort_column == 'device') {
$sql .= " ORDER BY `D`.`hostname` $sort_order";
} elseif ($sort_column == 'port') {
$sql .= " ORDER BY `ifDescr` $sort_order";
} else {
$sql .= " ORDER BY `$sort_column` $sort_order";
}
}
if (isset($current)) {
$limit_low = (($current * $rowCount) - ($rowCount));
$limit_high = $rowCount;
}
if ($rowCount != -1) {
$sql .= " LIMIT $limit_low,$limit_high";
}
$sql = "SELECT DISTINCT(`ports`.`port_id`),`ports`.* $sql";
foreach (dbFetchRows($sql, $param) as $port) {
$device = device_by_id_cache($port['device_id']);
// FIXME what actions should we have?
$actions = '<div class="container-fluid"><div class="row">';
$actions .= '<div class="col-xs-1"><a href="';
$actions .= generate_device_url($device, array('tab' => 'alerts'));
$actions .= '"><img src="images/16/bell.png" border="0" align="absmiddle" alt="View alerts" title="View alerts" /></a></div>';
if ($_SESSION['userlevel'] >= '7') {
$actions .= '<div class="col-xs-1"><a href="';
$actions .= generate_device_url($device, array('tab' => 'edit', 'section' => 'ports'));
$actions .= '"><img src="images/16/wrench.png" border="0" align="absmiddle" alt="Edit ports" title="Edit ports" /></a></div>';
}
$actions .= '</div></div>';
$response[] = array(
'device' => generate_device_link($device),
'port' => generate_port_link($port),
'ifSpeed' => $port['ifSpeed'],
'ifInOctets_rate' => $port['ifInOctets_rate'],
'ifOutOctets_rate' => $port['ifOutOctets_rate'],
'ifInUcastPkts_rate' => $port['ifInUcastPkts_rate'],
'ifOutUcastPkts_rate' => $port['ifOutUcastPkts_rate'],
'ifInErrors' => $port['ifInErrors'],
'ifOutErrors' => $port['ifOutErrors'],
'ifType' => humanmedia($port['ifType']),
'description' => $port['ifAlias'],
'actions' => $actions,
);
}
// debug
//$vals = $param;
//$query = preg_replace_callback('/\?/', function ($match) use (&$vals) {
// return array_shift($vals); // wrap in quotes and sanitize
//}, $sql);
$output = array(
'current' => $current,
'rowCount' => $rowCount,
'rows' => $response,
'total' => $total,
// 'sql' => $query,
);
echo _json_encode($output);

View File

@@ -114,7 +114,7 @@ foreach ($results as $data) {
?>
</select>
<input type="hostname" name="hostname" id="hostname" title="Hostname" class="form-control input-sm" <?php if (strlen($vars['hostname'])) {
<input type="text" name="hostname" id="hostname" title="Hostname" class="form-control input-sm" <?php if (strlen($vars['hostname'])) {
echo('value="'.$vars['hostname'].'"');
} ?> placeholder="Hostname" />
</div>
@@ -203,7 +203,7 @@ foreach ($ports as $data) {
<input title="Port Description" type="text" name="ifAlias" id="ifAlias" class="form-control input-sm" <?php if (strlen($vars['ifAlias'])) {
echo('value="'.$vars['ifAlias'].'"');
} ?> placeholder="Port Description"/>
<select name="location" id="location" class="form-control input-sm">
<select title="Location" name="location" id="location" class="form-control input-sm">
<option value="">All Locations</option>
<?php
@@ -222,46 +222,17 @@ foreach (getlocations() as $location) {
</div>
<div class="form-group">
<label for="ignore">Ignored</label>
<input type=checkbox id="ignore" name="ignore" value="1" class="" <?php if ($vars['ignore']) {
<input type=checkbox id="ignore" name="ignore" value="1" <?php if ($vars['ignore']) {
echo("checked");
} ?> ></input>
} ?> >
<label for="disabled">Disabled</label>
<input type=checkbox id="disabled" name="disabled" value=1 class="" <?php if ($vars['disabled']) {
<input type=checkbox id="disabled" name="disabled" value=1 <?php if ($vars['disabled']) {
echo("checked");
} ?> ></input>
</label>
} ?> >
<label for="deleted">Deleted</label>
<input type=checkbox id="deleted" name="deleted" value=1 class="" <?php if ($vars['deleted']) {
<input type=checkbox id="deleted" name="deleted" value=1 <?php if ($vars['deleted']) {
echo("checked");
} ?> ></input>
</label>
</div>
<div class="form-group">
<select name="sort" id="sort" class="form-control input-sm">
<?php
$sorts = array('device' => 'Device',
'port' => 'Port',
'speed' => 'Speed',
'traffic' => 'Traffic',
'traffic_in' => 'Traffic In',
'traffic_out' => 'Traffic Out',
'packets' => 'Packets',
'packets_in' => 'Packets In',
'packets_out' => 'Packets Out',
'errors' => 'Errors',
'media' => 'Media',
'descr' => 'Description');
foreach ($sorts as $sort => $sort_text) {
echo('<option value="'.$sort.'" ');
if ($vars['sort'] == $sort) {
echo("selected");
}
echo('>'.$sort_text.'</option>');
}
?>
</select>
} ?> >
</div>
<button type="submit" class="btn btn-default btn-sm">Search</button>
<a class="btn btn-default btn-sm" href="<?php echo(generate_url(array('page' => 'ports', 'section' => $vars['section'], 'bare' => $vars['bare']))); ?>" title="Reset critera to default." >Reset</a>

View File

@@ -1,73 +1,82 @@
<table cellpadding="3" cellspacing="0" class="table table-striped table-condensed" width="100%">
<?php
$details_visible = var_export($vars['format'] == 'list_detail', 1);
$errors_visible = var_export($vars['format'] == 'list_detail' || $vars['errors'], 1);
echo '<tr class="tablehead">';
if ($vars['errors']) {
$error_sort = ' data-order="desc"';
$sort = '';
} else {
$error_sort = '';
$sort = ' data-order="asc"';
}
?>
<div class="panel panel-default panel-condensed">
<div class="table-responsive">
<table id="ports" class="table table-condensed table-hover">
<thead>
<tr>
<th data-column-id="device">Device</th>
<th data-column-id="port"<?php echo $sort ?>>Port</th>
<th data-column-id="ifSpeed" data-formatter="human-bps">Speed</th>
<th data-column-id="ifInOctets_rate" data-searchable="false" data-css-class="green" data-formatter="human-bps">Down</th>
<th data-column-id="ifOutOctets_rate" data-searchable="false" data-css-class="blue" data-formatter="human-bps">Up</th>
<th data-column-id="ifInUcastPkts_rate" data-searchable="false" data-visible="<?php echo $details_visible ?>" data-css-class="green" data-formatter="human-pps">Packets In</th>
<th data-column-id="ifOutUcastPkts_rate" data-searchable="false" data-visible="<?php echo $details_visible ?>" data-css-class="blue" data-formatter="human-pps">Packets Out</th>
<th data-column-id="ifInErrors" data-searchable="false" data-visible="<?php echo $errors_visible ?>" data-css-class="red"<?php echo $error_sort ?>>Errors In</th>
<th data-column-id="ifOutErrors" data-searchable="false" data-visible="<?php echo $errors_visible ?>" data-css-class="red">Errors Out</th>
<th data-column-id="ifType">Media</th>
<th data-column-id="description">Description</th>
<th data-column-id="actions" data-sortable="false" data-searchable="false">Actions</th>
</tr>
</thead>
</table>
</div>
</div>
<script>
$cols = array(
'device' => 'Device',
'port' => 'Port',
'speed' => 'Speed',
'traffic_in' => 'Down',
'traffic_out' => 'Up',
'media' => 'Media',
'descr' => 'Description',
);
foreach ($cols as $sort => $col) {
if (isset($vars['sort']) && $vars['sort'] == $sort) {
echo '<th>'.$col.' *</th>';
} else {
echo '<th><a href="'.generate_url($vars, array('sort' => $sort)).'">'.$col.'</a></th>';
}
function formatUnits(units,decimals,display,base) {
if(!units) return '';
if(display === undefined) display = ['bps', 'Kbps', 'Mbps', 'Gbps', 'Tbps', 'Pbps', 'Ebps', 'Zbps', 'Ybps'];
if(units == 0) return units + display[0];
base = base || 1000; // or 1024 for binary
var dm = decimals || 2;
var i = Math.floor(Math.log(units) / Math.log(base));
return parseFloat((units / Math.pow(base, i)).toFixed(dm)) + display[i];
}
echo ' </tr>';
$ports_disabled = 0;
$ports_down = 0;
$ports_up = 0;
$ports_total = 0;
foreach ($ports as $port) {
if (port_permitted($port['port_id'], $port['device_id'])) {
if ($port['ifAdminStatus'] == 'down') {
$ports_disabled++;
} elseif ($port['ifAdminStatus'] == 'up' && $port['ifOperStatus'] == 'down') {
$ports_down++;
} elseif ($port['ifAdminStatus'] == 'up' && $port['ifOperStatus'] == 'up') {
$ports_up++;
var grid = $("#ports").bootgrid({
ajax: true,
rowCount: [25, 50,100,250,-1],
formatters: {
'human-bps': function(column, row) {
return formatUnits(row[column.id]);
},
'human-pps': function(column, row) {
return formatUnits(row[column.id], 2, ['pps', 'Kpps', 'Mpps', 'Gpps', 'Tpps', 'Ppps', 'Epps', 'Zpps', 'Ypps']);
}
},
templates: {
search: ""
},
post: function ()
{
return {
id: "ports",
device_id: '<?php echo mres($vars['device_id']); ?>',
hostname: '<?php echo htmlspecialchars($vars['hostname']); ?>',
state: '<?php echo mres($vars['state']); ?>',
ifSpeed: '<?php echo mres($vars['ifSpeed']); ?>',
ifType: '<?php echo mres($vars['ifType']); ?>',
port_descr_type: '<?php echo mres($vars['port_descr_type']); ?>',
ifAlias: '<?php echo htmlspecialchars($vars['ifAlias']); ?>',
location: '<?php echo mres($vars['location']); ?>',
disabled: '<?php echo mres($vars['disabled']); ?>',
ignore: '<?php echo mres($vars['ignore']); ?>',
deleted: '<?php echo mres($vars['deleted']); ?>',
errors: '<?php echo mres($vars['errors']); ?>',
};
},
url: "ajax_table.php"
});
$ports_total++;
$speed = humanspeed($port['ifSpeed']);
$type = humanmedia($port['ifType']);
$ifclass = ifclass($port['ifOperStatus'], $port['ifAdminStatus']);
if ((isset($port['in_errors']) && $port['in_errors'] > 0) || (isset($ports['out_errors']) && $port['out_errors'] > 0)) {
$error_img = generate_port_link($port, "<img src='images/16/chart_curve_error.png' alt='Interface Errors' border=0>", errors);
} else {
$error_img = '';
}
$port['in_rate'] = formatRates(($port['ifInOctets_rate'] * 8));
$port['out_rate'] = formatRates(($port['ifOutOctets_rate'] * 8));
$port = ifLabel($port, $device);
echo "<tr class='ports'>
<td width=200 class=list-bold>".generate_device_link($port, shorthost($port['hostname'], '20'))."</td>
<td width=150 class=list-bold><a class='".$ifclass."'href='".generate_port_url($port)."'>".fixIfName($port['label'])." $error_img</td>
<td width=110 >$speed</td>
<td width=100 class=green>".$port['in_rate'].'</td>
<td width=100 class=blue>'.$port['out_rate']."</td>
<td width=150>$type</td>
<td>".$port['ifAlias']."</td>
</tr>\n";
}//end if
}//end foreach
echo '<tr><td colspan="7">';
echo "<strong>Matched Ports: $ports_total ( <span class=green>Up $ports_up</span> | <span class=red>Down $ports_down</span> | Disabled $ports_disabled )</strong>";
echo '</td></tr></table>';
</script>