WOL widget rewrite for new dashboard (#4192)

This commit is contained in:
Michał Brzeziński
2024-08-26 11:48:10 +02:00
committed by GitHub
parent 6cacfaa34f
commit e553f5691f
5 changed files with 117 additions and 92 deletions
+1 -2
View File
@@ -1,6 +1,5 @@
PLUGIN_NAME= wol
PLUGIN_VERSION= 2.4
PLUGIN_REVISION= 2
PLUGIN_VERSION= 2.5
PLUGIN_DEPENDS= wol
PLUGIN_COMMENT= Wake on LAN Service
PLUGIN_MAINTAINER= franco@opnsense.org
@@ -0,0 +1,17 @@
<metadata>
<wol>
<filename>WakeOnLan.js</filename>
<endpoints>
<endpoint>/api/wol/wol/searchHost</endpoint>
<endpoint>/api/wol/wol/set</endpoint>
<endpoint>/diagnostics/interface/getArp</endpoint>
</endpoints>
<translations>
<title>WakeOnLan</title>
<msg_empty_wol>No saved WOL addresses</msg_empty_wol>
<h_device>Device</h_device>
<h_interface>Interface</h_interface>
<h_status>Status</h_status>
</translations>
</wol>
</metadata>
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2024 Michał Brzeziński
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
export default class WakeOnLan extends BaseTableWidget {
constructor() {
super();
}
getGridOptions() {
return {
// trigger overflow-y:scroll after 650px height
sizeToContent: 650
}
}
getMarkup() {
let $container = $('<div id="wol-clients-container"></div>');
let $wol_table = this.createTable('wol-table', {
headerPosition: 'none'
});
$container.append($wol_table);
return $container;
}
async onWidgetTick() {
const data = await this.ajaxCall('/api/wol/wol/searchHost');
let rows = [];
if (data.total == 0) {
const empty_list = [`<b>${this.translations.msg_empty_wol}</b>`];
rows.push(empty_list);
} else {
const header = [`<b>${this.translations.h_device}</b>`,
`<b>${this.translations.h_interface}</b>`,
`<b>${this.translations.h_status}</b>`,
''];
rows.push(header);
//NOTE: this ARP list call is the most expensive one and can grow substantialy in big networks
//With previous widget it had been done on the backend side with direct exec of 'arp -an | grep ...'
const arp = await this.ajaxCall('/api/diagnostics/interface/getArp');
for(let it = 0; it < data.rows.length; it++){
const item = data.rows[it];
let is_active = this.checkActive(arp, item.mac, item.interface);
let row = [
`${item.descr.length !== 0 ? item.descr + '<br/>': ''} ${item.mac}`,
`${item.interface}`,
`<i class="fa fa-${is_active == 1 ? "play" : "remove"} fa-fw text-${is_active == 1 ? "success" : "danger"}" ></i>
${ is_active == 1 ? "Online" : "Offline"}`,
`<button class="btn btn-primary btn-xs wakeupbtn" data-mac="${item.mac}" data-interface="${item.interface}" data-uuid="${item.uuid}">
<i class="fa fa-bolt fa-fw" title="Wake Up"></i>
</button>`
];
rows.push(row);
}
}
super.updateTable('wol-table', rows);
$('.wakeupbtn').on('click', async (event) => {
event.preventDefault();
const data = {uuid: $(event.currentTarget).data('uuid')};
const result = await this.ajaxCall('/api/wol/wol/set', JSON.stringify(data), 'POST');
});
}
checkActive(arp_list, mac, intf) {
const arp = arp_list.find((obj) => obj.mac === mac);
if (arp === undefined) {
return 0;
} else {
return (arp.expired === false && arp.intf_description === intf);
}
}
}
@@ -1,4 +0,0 @@
<?php
$wake_on_lan_title = gettext('Wake On Lan');
$wake_on_lan_title_link = 'ui/wol';
@@ -1,86 +0,0 @@
<?php
/*
* Copyright (C) 2014-2016 Deciso B.V.
* Copyright (C) 2010 Yehuda Katz
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INClUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* 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/wake_on_lan.inc");
require_once("interfaces.inc");
use OPNsense\Wol\Wol;
$wol = new Wol();
?>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th><?=gettext("Computer / Device");?></th>
<th><?=gettext("Interface");?></th>
<th><?=gettext("Status");?></th>
<th></th>
</tr>
</thead>
<tbody>
<?php
foreach ($wol->wolentry->iterateItems() as $wolent):
$is_active = exec("/usr/sbin/arp -an |/usr/bin/grep -i {$wolent->mac}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");?>
<tr>
<td><?= !empty((string)$wolent->descr) ? $wolent->descr : gettext('Unnamed entry') ?><br/><?= $wolent->mac ?></td>
<td><?=htmlspecialchars(convert_friendly_interface_to_friendly_descr((string)$wolent->interface));?></td>
<td>
<i class="fa fa-<?=$is_active == 1 ? "play" : "remove";?> fa-fw text-<?=$is_active == 1 ? "success" : "danger";?>" ></i>
<?=$is_active == 1 ? gettext("Online") : gettext("Offline");?>
</td>
<td>
<button class="btn btn-primary btn-xs wakeupbtn" data-mac="<?= $wolent->mac ?>" data-interface="<?= $wolent->interface ?>" data-uuid="<?= $wolent->getAttributes()['uuid'] ?>">
<i class="fa fa-bolt fa-fw" title="<?=gettext("Wake Up");?>"></i>
</button>
</td>
</tr>
<?php
endforeach;
if (count(iterator_to_array($wol->wolentry->iterateItems())) == 0):?>
<tr>
<td colspan="4" ><?=gettext("No saved WoL addresses");?></td>
</tr>
<?php
endif;?>
</tbody>
<tfoot>
<tr>
<td colspan="4"><a href="ui/dhcpv4/leases" class="navlink"><?= gettext('DHCP Leases Status') ?></a></td>
</tr>
</tfoot>
</table>
<script>
$("#dashboard_container").on("WidgetsReady", function() {
$('.wakeupbtn').click(function(event) {
event.preventDefault();
var data = this.dataset;
$.post('/api/wol/wol/set', {'uuid': data['uuid']}, function(result) {
});
})
});
</script>