net/wireguard - refactor dashboard widget, use shared service diagnostics endpoint (/api/wireguard/service/show), mark old one for deprecation in 24.1 and fix latest-handshake presentation in diagnostics screen.

This commit is contained in:
Ad Schellevis
2023-09-03 11:28:13 +02:00
parent 61333a74d8
commit 7e42d0b554
6 changed files with 66 additions and 70 deletions
@@ -40,6 +40,9 @@ class GeneralController extends ApiMutableModelControllerBase
protected static $internalModelClass = '\OPNsense\Wireguard\General';
protected static $internalModelName = 'general';
/**
* XXX: remove in 24.1 unused
*/
public function getStatusAction()
{
// get wireguard configuration
@@ -103,11 +103,13 @@ class ServiceController extends ApiMutableServiceControllerBase
$payload = json_decode((new Backend())->configdRun("wireguard show") ?? '', true);
$records = !empty($payload) && !empty($payload['records']) ? $payload['records'] : [];
$key_descriptions = [];
$ifnames = [];
foreach ((new Client())->clients->client->iterateItems() as $key => $client) {
$key_descriptions[(string)$client->pubkey] = (string)$client->name;
}
foreach ((new Server())->servers->server->iterateItems() as $key => $server) {
$key_descriptions[(string)$server->pubkey] = (string)$server->name;
$ifnames[(string)$server->interface] = (string)$server->name;
}
foreach ($records as &$record) {
if (!empty($record['public-key']) && !empty($key_descriptions[$record['public-key']])) {
@@ -115,6 +117,7 @@ class ServiceController extends ApiMutableServiceControllerBase
} else {
$record['name'] = '';
}
$record['ifname'] = $ifnames[$record['if']];
}
$filter_funct = null;
$types = $this->request->get('type');
@@ -30,6 +30,13 @@ namespace OPNsense\Wireguard;
class DiagnosticsController extends \OPNsense\Base\IndexController
{
protected function templateJSIncludes()
{
$result = parent::templateJSIncludes();
$result[] = '/ui/js/moment-with-locales.min.js';
return $result;
}
public function indexAction()
{
$this->view->pick('OPNsense/Wireguard/diagnostics');
@@ -27,7 +27,7 @@
<script>
$( document ).ready(function() {
let grid_phase1 = $("#grid-sessions").UIBootgrid({
$("#grid-sessions").UIBootgrid({
search:'/api/wireguard/service/show',
options:{
multiSelect: false,
@@ -39,6 +39,14 @@
return byteFormat(row[column.id], 2);
}
return row[column.id];
},
epoch: function(column, row) {
if (row[column.id]) {
return moment.unix(row[column.id]).local().format('YYYY-MM-DD HH:mm:ss');
} else {
return '';
}
}
},
requestHandler: function(request){
@@ -77,7 +85,7 @@
<th data-column-id="public-key" data-type="string" data-identifier="true">{{ lang._('Public key') }}</th>
<th data-column-id="name" data-type="string">{{ lang._('Name') }}</th>
<th data-column-id="endpoint" data-type="string">{{ lang._('Port / Endpoint') }}</th>
<th data-column-id="latest-handshake" data-type="numeric">{{ lang._('Handshake') }}</th>
<th data-column-id="latest-handshake" data-formatter="epoch" data-type="numeric">{{ lang._('Handshake') }}</th>
<th data-column-id="transfer-tx" data-formatter="bytes" data-type="numeric">{{ lang._('Send') }}</th>
<th data-column-id="transfer-rx" data-formatter="bytes" data-type="numeric">{{ lang._('Received') }}</th>
@@ -1,4 +1,4 @@
<?php
$wireguard_title = gettext('WireGuard');
$wireguard_title_link = 'ui/wireguard/general/index';
$wireguard_title_link = 'ui/wireguard/general/';
@@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2020 Deciso B.V.
* Copyright (C) 2020-2023 Deciso B.V.
* Copyright (C) 2020 D. Domig
* Copyright (C) 2022 Patrik Kernstock <patrik@kernstock.net>
* All rights reserved.
@@ -27,94 +27,69 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("widgets/include/wireguard.inc");
$enabled = ($config["OPNsense"]["wireguard"]["general"]["enabled"] === "1" ? true : false);
?>
<table class="table table-striped table-condensed">
<table class="table table-striped table-condensed" id="wg-table">
<thead>
<tr>
<th><?= gettext("Name") ?></th>
<th><?= gettext("Interface") ?></th>
<th><?= gettext("Endpoint") ?></th>
<th><?= gettext("Public Key") ?></th>
<th><?= gettext("Latest Handshake") ?></th>
</tr>
</thead>
<tbody id="wg-table-tbody">
<?php if (!$enabled): ?>
<tr>
<td colspan="5"><?= gettext("No WireGuard instance defined or enabled.") ?></td>
</tr>
<?php endif; ?>
<tbody>
</tbody>
<tfoot style="display: none;">
<tr>
<td colspan="4"><?= gettext("No WireGuard instance defined or enabled.") ?></td>
</tr>
</tfoot>
</table>
<style>
.psk_td {
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
text-decoration: underline;
}
</style>
<script>
$(window).on("load", function() {
function wgGenerateRow(name, interface, peerName, publicKey, latestHandshake, status)
{
var tr = ''
+'<tr>'
+' <td>' + name + '</td>'
+' <td>' + interface + '</td>'
+' <td>' + peerName + '</td>'
+' <td style="overflow: hidden; text-overflow: ellipsis;" title="' + publicKey + '">' + publicKey + '</td>'
+' <td>' + latestHandshake + '</td>'
+'</tr>';
return tr;
}
function wgUpdateStatusIf(obj)
{
// check if at least one peer is set. If not, ignore it.
if (Object.keys(obj.peers).length == 0) {
return '';
}
// generate row based on data
row = '';
for (var peerId in obj.peers) {
var peer = obj.peers[peerId];
// generate table row
row += wgGenerateRow(
obj.name,
obj.interface,
peer.name,
peer.publicKey,
peer.lastHandshake,
status
);
}
return row;
}
function wgUpdateStatus()
{
var table = '';
ajaxGet("/api/wireguard/general/getStatus", {}, function(data, status) {
if (status === 'success') {
for (var interface in data.items) {
table += wgUpdateStatusIf(data.items[interface]);
ajaxGet("/api/wireguard/service/show", {}, function(data, status) {
let $target = $("#wg-table > tbody").empty();
if (data.rows !== undefined && data.rows.length > 0) {
$("#wg-table > tfoot").hide();
for (let i=0; data.rows.length > i; ++i) {
let row = data.rows[i];
let $tr = $("<tr/>");
let ifname = row.ifname ? row.if + ' (' + row.ifname + ') ' : row.if;
$tr.append($("<td>").append(ifname));
$tr.append($("<td>").append(row.name));
$tr.append($("<td class='psk_td'>").append(row['public-key']));
let latest_handhake = '';
if (row['latest-handshake']) {
latest_handhake = moment.unix(row['latest-handshake']).local().format('YYYY-MM-DD HH:mm:ss');
}
$tr.append($("<td>").append(latest_handhake));
$target.append($tr);
}
$(".psk_td").each(function(){
$(this).tooltip({title: $(this).text(), container: 'body', trigger: 'hover'});
});
} else{
$("#wg-table > tfoot").show();
}
// update table accordingly
document.getElementById("wg-table-tbody").innerHTML = table;
setTimeout(wgUpdateStatus, 10000);
});
};
<?php if ($enabled): ?>
wgUpdateStatus();
<?php endif; ?>
});
</script>