mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-04-19 19:59:13 +03:00
Implements Wake On Lan and management features (#164)
This commit is contained in:
parent
037a6c56d3
commit
0224e1f137
12 changed files with 638 additions and 21 deletions
196
custom/js/wake_on_lan_hosts.js
Normal file
196
custom/js/wake_on_lan_hosts.js
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
const wake_on_lan_new_template = '<div class="col-sm-4" id="{{ .Id }}">\n' +
|
||||||
|
'\t<div class="info-box">\n' +
|
||||||
|
'\t\t<div class="info-box-content">\n' +
|
||||||
|
'\t\t\t<div class="btn-group">\n' +
|
||||||
|
'\t\t\t\t<button type="button" class="btn btn-outline-success btn-sm"\n' +
|
||||||
|
'\t\t\t\t\t\tdata-mac-address="{{ .MacAddress }}">Wake On\n' +
|
||||||
|
'\t\t\t\t</button>\n' +
|
||||||
|
'\t\t\t\t<button type="button"\n' +
|
||||||
|
'\t\t\t\t\t\tclass="btn btn-outline-primary btn-sm btn_modify_wake_on_lan_host"\n' +
|
||||||
|
'\t\t\t\t\t\tdata-toggle="modal" data-target="#modal_wake_on_lan_host"\n' +
|
||||||
|
'\t\t\t\t\t\tdata-name="{{ .Name }}" data-mac-address="{{ .MacAddress }}">Edit\n' +
|
||||||
|
'\t\t\t\t</button>\n' +
|
||||||
|
'\t\t\t\t<button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"\n' +
|
||||||
|
'\t\t\t\t\t\tdata-target="#modal_remove_wake_on_lan_host"\n' +
|
||||||
|
'\t\t\t\t\t\tdata-mac-address="{{ .MacAddress }}">Remove\n' +
|
||||||
|
'\t\t\t\t</button>\n' +
|
||||||
|
'\t\t\t</div>\n' +
|
||||||
|
'\t\t\t<hr>\n' +
|
||||||
|
'\t\t\t<span class="info-box-text"><i class="fas fa-address-card"></i> <span class="name">{{ .Name }}</span></span>\n' +
|
||||||
|
'\t\t\t<span class="info-box-text"><i class="fas fa-ethernet"></i> <span class="mac-address">{{ .MacAddress }}</span></span>\n' +
|
||||||
|
'\t\t\t<span class="info-box-text"><i class="fas fa-clock"></i> <span class="latest-used">Unused</span></span>\n' +
|
||||||
|
'\t\t</div>\n' +
|
||||||
|
'\t</div>\n' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
jQuery(function ($) {
|
||||||
|
$.validator.addMethod('mac', function (value, element) {
|
||||||
|
return this.optional(element) || /^([0-9A-F]{2}[:]){5}([0-9A-F]{2})$/.test(value);
|
||||||
|
}, 'Please enter a valid MAC Address.(uppercase letters and numbers, : only) ex: 00:AB:12:EF:DD:AA');
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.each(["put", "delete"], function (i, method) {
|
||||||
|
jQuery[method] = function (url, data, callback, type) {
|
||||||
|
if (jQuery.isFunction(data)) {
|
||||||
|
type = type || callback;
|
||||||
|
callback = data;
|
||||||
|
data = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jQuery.ajax({
|
||||||
|
url: url,
|
||||||
|
type: method,
|
||||||
|
dataType: type,
|
||||||
|
data: data,
|
||||||
|
success: callback
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery(function ($) {
|
||||||
|
let newHostHtml = '<div class="col-sm-2 offset-md-4" style=" text-align: right;"><button style="" id="btn_new_wake_on_lan_host" type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#modal_wake_on_lan_host"><i class="nav-icon fas fa-plus"></i> New Host</button></div>';
|
||||||
|
$('h1').parents(".row").append(newHostHtml);
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery(function ($) {
|
||||||
|
$('.btn-outline-success').click(function () {
|
||||||
|
const $this = $(this);
|
||||||
|
$.put('/wake_on_lan_host/' + $this.data('mac-address'), function (result) {
|
||||||
|
$this.parents('.info-box').find('.latest-used').text(prettyDateTime(result));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery(function ($) {
|
||||||
|
let $modal_remove_wake_on_lan_host = $('#modal_remove_wake_on_lan_host');
|
||||||
|
let $remove_client_confirm = $('#remove_wake_on_host_confirm');
|
||||||
|
|
||||||
|
$modal_remove_wake_on_lan_host.on('show.bs.modal', function (event) {
|
||||||
|
const $btn = $(event.relatedTarget);
|
||||||
|
const $modal = $(this);
|
||||||
|
|
||||||
|
const $editBtn = $btn.parents('.btn-group').find('.btn_modify_wake_on_lan_host');
|
||||||
|
$modal.find('.modal-body').text("You are about to remove Wake On Lan Host " + $editBtn.data('name'));
|
||||||
|
$remove_client_confirm.val($editBtn.data('mac-address'));
|
||||||
|
})
|
||||||
|
|
||||||
|
$remove_client_confirm.click(function () {
|
||||||
|
const macAddress = $remove_client_confirm.val().replaceAll(":", "-");
|
||||||
|
$.delete('/wake_on_lan_host/' + macAddress);
|
||||||
|
$('#' + macAddress).remove();
|
||||||
|
|
||||||
|
$modal_remove_wake_on_lan_host.modal('hide');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery(function ($) {
|
||||||
|
$('.latest-used').each(function () {
|
||||||
|
const $this = $(this);
|
||||||
|
$this.text(prettyDateTime($this.text().trim()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery(function ($) {
|
||||||
|
let $modal_wake_on_lan_host = $("#modal_wake_on_lan_host");
|
||||||
|
let $name = $('#frm_wake_on_lan_host_name');
|
||||||
|
let $macAddress = $('#frm_wake_on_lan_host_mac_address');
|
||||||
|
let $oldMacAddress = $('#frm_wake_on_lan_host_old_mac_address');
|
||||||
|
let $contentRow = $('.content .row');
|
||||||
|
let $frm_wake_on_lan_host = $("#frm_wake_on_lan_host");
|
||||||
|
|
||||||
|
// https://jqueryvalidation.org/
|
||||||
|
let validator = $frm_wake_on_lan_host.validate({
|
||||||
|
submitHandler: function () {
|
||||||
|
let data = {
|
||||||
|
name: $name.val(),
|
||||||
|
mac_address: $macAddress.val().toUpperCase(),
|
||||||
|
old_mac_address: $oldMacAddress.val().toUpperCase()
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
method: 'POST',
|
||||||
|
url: '/wake_on_lan_host',
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: "application/json",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
success: function (response) {
|
||||||
|
/** @type {string} */
|
||||||
|
let oldMacAddress = $oldMacAddress.val().toUpperCase();
|
||||||
|
|
||||||
|
if (oldMacAddress != '') {
|
||||||
|
let macAddress = response.MacAddress;
|
||||||
|
let name = response.Name;
|
||||||
|
|
||||||
|
let $container = $('#' + oldMacAddress.replaceAll(":", "-"));
|
||||||
|
if (macAddress != oldMacAddress) {
|
||||||
|
$container.attr('id', macAddress.replaceAll(":", "-"));
|
||||||
|
$container.find('.mac-address').text(macAddress);
|
||||||
|
$container.find('[data-mac-address]').data('mac-address', macAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container.find('.name').text(name);
|
||||||
|
$container.find('[data-name]').data('name', name);
|
||||||
|
} else {
|
||||||
|
const $template = $(
|
||||||
|
wake_on_lan_new_template
|
||||||
|
.replace(/{{ .Id }}/g, response.MacAddress.replaceAll(":", "-").toUpperCase())
|
||||||
|
.replace(/{{ .MacAddress }}/g, response.MacAddress.toUpperCase())
|
||||||
|
.replace(/{{ .Name }}/g, response.Name)
|
||||||
|
);
|
||||||
|
|
||||||
|
$contentRow.append($template);
|
||||||
|
}
|
||||||
|
$modal_wake_on_lan_host.modal('hide');
|
||||||
|
toastr.success('Wake on Lan Host Save successfully');
|
||||||
|
},
|
||||||
|
error: function (jqXHR, exception) {
|
||||||
|
const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
||||||
|
toastr.error(responseJson['message']);
|
||||||
|
|
||||||
|
if (typeof (console) != 'undefined')
|
||||||
|
console.log(exception);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
name: {
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
mac_address: {
|
||||||
|
required: true,
|
||||||
|
mac: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
name: {
|
||||||
|
required: "Please enter a name"
|
||||||
|
},
|
||||||
|
mac_address: {
|
||||||
|
required: "Please enter a Mac Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
errorElement: 'span',
|
||||||
|
errorPlacement: function (error, element) {
|
||||||
|
error.addClass('invalid-feedback');
|
||||||
|
element.closest('.form-group').append(error);
|
||||||
|
},
|
||||||
|
highlight: function (element) {
|
||||||
|
$(element).addClass('is-invalid');
|
||||||
|
},
|
||||||
|
unhighlight: function (element) {
|
||||||
|
$(element).removeClass('is-invalid');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal_wake_on_lan_host.on('show.bs.modal', function (e) {
|
||||||
|
const $btn = $(e.relatedTarget);
|
||||||
|
validator.resetForm();
|
||||||
|
$macAddress.removeClass('is-invalid');
|
||||||
|
|
||||||
|
$name.val($btn.data('name'));
|
||||||
|
$macAddress.val($btn.data('mac-address'));
|
||||||
|
$oldMacAddress.val($btn.data('mac-address'));
|
||||||
|
});
|
||||||
|
});
|
3
go.mod
3
go.mod
|
@ -18,8 +18,9 @@ require (
|
||||||
github.com/sendgrid/sendgrid-go v3.10.0+incompatible
|
github.com/sendgrid/sendgrid-go v3.10.0+incompatible
|
||||||
github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086
|
github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086
|
||||||
github.com/xhit/go-simple-mail/v2 v2.10.0
|
github.com/xhit/go-simple-mail/v2 v2.10.0
|
||||||
golang.zx2c4.com/wireguard v0.0.20200121 // indirect
|
//golang.zx2c4.com/wireguard v0.0.20200121 // indirect
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||||
gopkg.in/go-playground/validator.v9 v9.31.0
|
gopkg.in/go-playground/validator.v9 v9.31.0
|
||||||
|
github.com/sabhiram/go-wol v0.0.0-20211224004021-c83b0c2f887d
|
||||||
)
|
)
|
||||||
|
|
33
go.sum
33
go.sum
|
@ -11,10 +11,10 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
github.com/coreos/bbolt v1.3.1-coreos.6.0.20180223184059-4f5275f4ebbf/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
|
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
|
||||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
@ -50,6 +50,7 @@ github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYb
|
||||||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8=
|
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8=
|
||||||
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw=
|
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw=
|
||||||
|
github.com/jessevdk/go-flags v0.0.0-20150816100521-1acbbaff2f34/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA=
|
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA=
|
||||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
|
@ -59,7 +60,6 @@ github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqo
|
||||||
github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
|
github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
|
||||||
github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs=
|
github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs=
|
||||||
github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA=
|
github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA=
|
||||||
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b h1:c3NTyLNozICy8B4mlMXemD3z/gXgQzVXZS/HqT+i3do=
|
|
||||||
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
|
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
@ -77,14 +77,15 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL
|
||||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
|
||||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
|
||||||
|
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY=
|
|
||||||
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo=
|
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo=
|
||||||
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
||||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||||
|
@ -98,7 +99,6 @@ github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnN
|
||||||
github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys=
|
github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys=
|
||||||
github.com/mdlayher/netlink v1.4.0 h1:n3ARR+Fm0dDv37dj5wSWZXDKcy+U0zwcXS3zKMnSiT0=
|
github.com/mdlayher/netlink v1.4.0 h1:n3ARR+Fm0dDv37dj5wSWZXDKcy+U0zwcXS3zKMnSiT0=
|
||||||
github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8=
|
github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8=
|
||||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
|
||||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
@ -109,7 +109,6 @@ github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYX
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
@ -123,6 +122,9 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
||||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
|
github.com/sabhiram/go-colorize v0.0.0-20210403184538-366f55d711cf/go.mod h1:GvlEbMJBpbAXFn06UajbdBlGZ18iLvHyuIrgG//L8uk=
|
||||||
|
github.com/sabhiram/go-wol v0.0.0-20211224004021-c83b0c2f887d h1:NDtoSmsxTpDYTqvUurn2ooAzDaYbJSB9/tOhLzaewgo=
|
||||||
|
github.com/sabhiram/go-wol v0.0.0-20211224004021-c83b0c2f887d/go.mod h1:SVPBBd492Gk7Cq5lPd6OAYtIGk2r1FsyH8KT3IB8h7c=
|
||||||
github.com/sdomino/scribble v0.0.0-20191024200645-4116320640ba h1:8QAc9wFAf2b/9cAXskm0wBylObZ0bTpRcaP7ThjLPVQ=
|
github.com/sdomino/scribble v0.0.0-20191024200645-4116320640ba h1:8QAc9wFAf2b/9cAXskm0wBylObZ0bTpRcaP7ThjLPVQ=
|
||||||
github.com/sdomino/scribble v0.0.0-20191024200645-4116320640ba/go.mod h1:W6zxGUBCXRR5QugSd/nFcFVmwoGnvpjiNY/JwT03Wew=
|
github.com/sdomino/scribble v0.0.0-20191024200645-4116320640ba/go.mod h1:W6zxGUBCXRR5QugSd/nFcFVmwoGnvpjiNY/JwT03Wew=
|
||||||
github.com/sendgrid/rest v2.6.4+incompatible h1:lq6gAQxLwVBf3mVyCCSHI6mgF+NfaJFJHjT0kl6SSo8=
|
github.com/sendgrid/rest v2.6.4+incompatible h1:lq6gAQxLwVBf3mVyCCSHI6mgF+NfaJFJHjT0kl6SSo8=
|
||||||
|
@ -135,9 +137,9 @@ github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086/go.mod h1:PLPIyL7i
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
github.com/stretchr/testify v0.0.0-20150929183540-2b15294402a8/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||||
github.com/uber/jaeger-client-go v2.19.1-0.20191002155754-0be28c34dabf+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
github.com/uber/jaeger-client-go v2.19.1-0.20191002155754-0be28c34dabf+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
|
@ -153,7 +155,6 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
|
@ -165,7 +166,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
@ -192,7 +192,6 @@ golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -209,8 +208,11 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 h1:cdsMqa2nXzqlgs183pHxtvoVwU7CyzaCTAUOg94af4c=
|
|
||||||
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -221,21 +223,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b h1:XDLXhn7ryprJVo+Lpkiib6CIuXE2031GDwtfEm7vLjI=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
||||||
golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8=
|
|
||||||
golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4=
|
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c h1:ADNrRDI5NR23/TUCnEmlLZLt4u9DnZ2nwRkPrAcFvto=
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c h1:ADNrRDI5NR23/TUCnEmlLZLt4u9DnZ2nwRkPrAcFvto=
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c/go.mod h1:+1XihzyZUBJcSc5WO9SwNA7v26puQwOEDwanaxfNXPQ=
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c/go.mod h1:+1XihzyZUBJcSc5WO9SwNA7v26puQwOEDwanaxfNXPQ=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M=
|
gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M=
|
||||||
gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
171
handler/routes_wake_on_lan.go
Normal file
171
handler/routes_wake_on_lan.go
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/labstack/gommon/log"
|
||||||
|
"github.com/ngoduykhanh/wireguard-ui/model"
|
||||||
|
"github.com/ngoduykhanh/wireguard-ui/store"
|
||||||
|
"github.com/sabhiram/go-wol/wol"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WakeOnLanHostSavePayload struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
MacAddress string `json:"mac_address"`
|
||||||
|
OldMacAddress string `json:"old_mac_address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func createError(c echo.Context, err error, msg string) error {
|
||||||
|
log.Error(msg, err)
|
||||||
|
return c.JSON(
|
||||||
|
http.StatusInternalServerError,
|
||||||
|
jsonHTTPResponse{
|
||||||
|
false,
|
||||||
|
msg})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWakeOnLanHosts(db store.IStore) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
hosts, err := db.GetWakeOnLanHosts()
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("wake_on_lan_hosts database error: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.Render(http.StatusOK, "wake_on_lan_hosts.html", map[string]interface{}{
|
||||||
|
"baseData": model.BaseData{Active: "wake_on_lan_hosts", CurrentUser: currentUser(c)},
|
||||||
|
"hosts": hosts,
|
||||||
|
"error": "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("wake_on_lan_hosts.html render error: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SaveWakeOnLanHost(db store.IStore) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
var payload WakeOnLanHostSavePayload
|
||||||
|
err := c.Bind(&payload)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Wake On Host Save Payload Bind Error: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
var host = model.WakeOnLanHost{
|
||||||
|
MacAddress: payload.MacAddress,
|
||||||
|
Name: payload.Name,
|
||||||
|
}
|
||||||
|
if len(payload.OldMacAddress) != 0 { // Edit
|
||||||
|
if payload.OldMacAddress != payload.MacAddress { // modified mac address
|
||||||
|
oldHost, err := db.GetWakeOnLanHost(payload.OldMacAddress)
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Wake On Host Update Err: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if payload.OldMacAddress != payload.MacAddress {
|
||||||
|
existHost, _ := db.GetWakeOnLanHost(payload.MacAddress)
|
||||||
|
if existHost != nil {
|
||||||
|
return createError(c, nil, "Mac Address already exists.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.DeleteWakeOnHostLanHost(payload.OldMacAddress)
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Wake On Host Update Err: %s", err))
|
||||||
|
}
|
||||||
|
host.LatestUsed = oldHost.LatestUsed
|
||||||
|
}
|
||||||
|
err = db.SaveWakeOnLanHost(host)
|
||||||
|
} else { // new
|
||||||
|
existHost, _ := db.GetWakeOnLanHost(payload.MacAddress)
|
||||||
|
if existHost != nil {
|
||||||
|
return createError(c, nil, "Mac Address already exists.")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.SaveWakeOnLanHost(host)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Wake On Host Save Error: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, host)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteWakeOnHost(db store.IStore) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
var macAddress = c.Param("mac_address")
|
||||||
|
var host, err = db.GetWakeOnLanHost(macAddress)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Wake On Host Delete Error: ", err)
|
||||||
|
return createError(c, err, fmt.Sprintf("Wake On Host Delete Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.DeleteWakeOnHost(*host)
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Wake On Host Delete Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WakeOnHost(db store.IStore) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
macAddress := c.Param("mac_address")
|
||||||
|
host, err := db.GetWakeOnLanHost(macAddress)
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
host.LatestUsed = &now
|
||||||
|
err = db.SaveWakeOnLanHost(*host)
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Latest Used Update Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
magicPacket, err := wol.New(macAddress)
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Magic Packet Create Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := magicPacket.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Magic Packet Bytestream Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
udpAddr, err := net.ResolveUDPAddr("udp", "255.255.255.255:0")
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("ResolveUDPAddr Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab a UDP connection to send our packet of bytes.
|
||||||
|
conn, err := net.DialUDP("udp", nil, udpAddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func(conn *net.UDPConn) {
|
||||||
|
err := conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
}(conn)
|
||||||
|
|
||||||
|
n, err := conn.Write(bytes)
|
||||||
|
if err == nil && n != 102 {
|
||||||
|
return createError(c, nil, fmt.Sprintf("magic packet sent was %d bytes (expected 102 bytes sent)", n))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return createError(c, err, fmt.Sprintf("Network Send Error: %s", macAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, host.LatestUsed)
|
||||||
|
}
|
||||||
|
}
|
7
main.go
7
main.go
|
@ -3,12 +3,11 @@ package main
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
rice "github.com/GeertJohan/go.rice"
|
rice "github.com/GeertJohan/go.rice"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
|
|
||||||
"github.com/ngoduykhanh/wireguard-ui/emailer"
|
"github.com/ngoduykhanh/wireguard-ui/emailer"
|
||||||
"github.com/ngoduykhanh/wireguard-ui/handler"
|
"github.com/ngoduykhanh/wireguard-ui/handler"
|
||||||
"github.com/ngoduykhanh/wireguard-ui/router"
|
"github.com/ngoduykhanh/wireguard-ui/router"
|
||||||
|
@ -147,6 +146,10 @@ func main() {
|
||||||
app.GET("/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession)
|
app.GET("/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession)
|
||||||
app.GET("/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession)
|
app.GET("/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession)
|
||||||
app.GET("/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession)
|
app.GET("/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession)
|
||||||
|
app.GET("/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession)
|
||||||
|
app.POST("/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession)
|
||||||
|
app.DELETE("/wake_on_lan_host/:mac_address", handler.DeleteWakeOnHost(db), handler.ValidSession)
|
||||||
|
app.PUT("/wake_on_lan_host/:mac_address", handler.WakeOnHost(db), handler.ValidSession)
|
||||||
|
|
||||||
// servers other static files
|
// servers other static files
|
||||||
app.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler)))
|
app.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler)))
|
||||||
|
|
24
model/wake_on_lan_host.go
Normal file
24
model/wake_on_lan_host.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WakeOnLanHost struct {
|
||||||
|
MacAddress string `json:"MacAddress"`
|
||||||
|
Name string `json:"Name"`
|
||||||
|
LatestUsed *time.Time `json:"LatestUsed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (host WakeOnLanHost) ResolveResourceName() (string, error) {
|
||||||
|
resourceName := strings.Trim(host.MacAddress, " \t\r\n\000")
|
||||||
|
if len(resourceName) == 0 {
|
||||||
|
return "", errors.New("mac Address is Empty")
|
||||||
|
}
|
||||||
|
resourceName = strings.ToUpper(resourceName)
|
||||||
|
return strings.ReplaceAll(resourceName, ":", "-"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const WakeOnLanHostCollectionName = "wake_on_lan_hosts"
|
|
@ -79,6 +79,11 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmplWakeOnLanHostsString, err := tmplBox.String("wake_on_lan_hosts.html")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// create template list
|
// create template list
|
||||||
templates := make(map[string]*template.Template)
|
templates := make(map[string]*template.Template)
|
||||||
templates["login.html"] = template.Must(template.New("login").Parse(tmplLoginString))
|
templates["login.html"] = template.Must(template.New("login").Parse(tmplLoginString))
|
||||||
|
@ -86,6 +91,7 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
|
||||||
templates["server.html"] = template.Must(template.New("server").Parse(tmplBaseString + tmplServerString))
|
templates["server.html"] = template.Must(template.New("server").Parse(tmplBaseString + tmplServerString))
|
||||||
templates["global_settings.html"] = template.Must(template.New("global_settings").Parse(tmplBaseString + tmplGlobalSettingsString))
|
templates["global_settings.html"] = template.Must(template.New("global_settings").Parse(tmplBaseString + tmplGlobalSettingsString))
|
||||||
templates["status.html"] = template.Must(template.New("status").Parse(tmplBaseString + tmplStatusString))
|
templates["status.html"] = template.Must(template.New("status").Parse(tmplBaseString + tmplStatusString))
|
||||||
|
templates["wake_on_lan_hosts.html"] = template.Must(template.New("wake_on_lan_hosts").Parse(tmplBaseString + tmplWakeOnLanHostsString))
|
||||||
|
|
||||||
e.Logger.SetLevel(log.DEBUG)
|
e.Logger.SetLevel(log.DEBUG)
|
||||||
e.Pre(middleware.RemoveTrailingSlash())
|
e.Pre(middleware.RemoveTrailingSlash())
|
||||||
|
|
|
@ -38,6 +38,7 @@ func New(dbPath string) (*JsonDB, error) {
|
||||||
func (o *JsonDB) Init() error {
|
func (o *JsonDB) Init() error {
|
||||||
var clientPath string = path.Join(o.dbPath, "clients")
|
var clientPath string = path.Join(o.dbPath, "clients")
|
||||||
var serverPath string = path.Join(o.dbPath, "server")
|
var serverPath string = path.Join(o.dbPath, "server")
|
||||||
|
var wakeOnLanHostsPath string = path.Join(o.dbPath, "wake_on_lan_hosts")
|
||||||
var serverInterfacePath string = path.Join(serverPath, "interfaces.json")
|
var serverInterfacePath string = path.Join(serverPath, "interfaces.json")
|
||||||
var serverKeyPairPath string = path.Join(serverPath, "keypair.json")
|
var serverKeyPairPath string = path.Join(serverPath, "keypair.json")
|
||||||
var globalSettingPath string = path.Join(serverPath, "global_settings.json")
|
var globalSettingPath string = path.Join(serverPath, "global_settings.json")
|
||||||
|
@ -49,6 +50,9 @@ func (o *JsonDB) Init() error {
|
||||||
if _, err := os.Stat(serverPath); os.IsNotExist(err) {
|
if _, err := os.Stat(serverPath); os.IsNotExist(err) {
|
||||||
os.MkdirAll(serverPath, os.ModePerm)
|
os.MkdirAll(serverPath, os.ModePerm)
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(wakeOnLanHostsPath); os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(wakeOnLanHostsPath, os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
// server's interface
|
// server's interface
|
||||||
if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) {
|
if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) {
|
||||||
|
|
78
store/jsondb/jsondb_wake_on_lan.go
Normal file
78
store/jsondb/jsondb_wake_on_lan.go
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package jsondb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/ngoduykhanh/wireguard-ui/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *JsonDB) GetWakeOnLanHosts() ([]model.WakeOnLanHost, error) {
|
||||||
|
var hosts []model.WakeOnLanHost
|
||||||
|
|
||||||
|
// read all client json file in "hosts" directory
|
||||||
|
records, err := o.conn.ReadAll(model.WakeOnLanHostCollectionName)
|
||||||
|
if err != nil {
|
||||||
|
return hosts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the ClientData list
|
||||||
|
for _, f := range records {
|
||||||
|
host := model.WakeOnLanHost{}
|
||||||
|
|
||||||
|
// get client info
|
||||||
|
if err := json.Unmarshal([]byte(f), &host); err != nil {
|
||||||
|
return hosts, fmt.Errorf("cannot decode client json structure: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the list of hosts and their qrcode data
|
||||||
|
hosts = append(hosts, host)
|
||||||
|
}
|
||||||
|
|
||||||
|
return hosts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JsonDB) GetWakeOnLanHost(macAddress string) (*model.WakeOnLanHost, error) {
|
||||||
|
host := &model.WakeOnLanHost{
|
||||||
|
MacAddress: macAddress,
|
||||||
|
}
|
||||||
|
resourceName, err := host.ResolveResourceName()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = o.conn.Read(model.WakeOnLanHostCollectionName, resourceName, host)
|
||||||
|
if err != nil {
|
||||||
|
host = nil
|
||||||
|
}
|
||||||
|
return host, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JsonDB) DeleteWakeOnHostLanHost(macAddress string) error {
|
||||||
|
host := &model.WakeOnLanHost{
|
||||||
|
MacAddress: macAddress,
|
||||||
|
}
|
||||||
|
resourceName, err := host.ResolveResourceName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.conn.Delete(model.WakeOnLanHostCollectionName, resourceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JsonDB) SaveWakeOnLanHost(host model.WakeOnLanHost) error {
|
||||||
|
resourceName, err := host.ResolveResourceName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.conn.Write(model.WakeOnLanHostCollectionName, resourceName, host)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JsonDB) DeleteWakeOnHost(host model.WakeOnLanHost) error {
|
||||||
|
resourceName, err := host.ResolveResourceName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.conn.Delete(model.WakeOnLanHostCollectionName, resourceName)
|
||||||
|
}
|
|
@ -16,4 +16,9 @@ type IStore interface {
|
||||||
SaveServerInterface(serverInterface model.ServerInterface) error
|
SaveServerInterface(serverInterface model.ServerInterface) error
|
||||||
SaveServerKeyPair(serverKeyPair model.ServerKeypair) error
|
SaveServerKeyPair(serverKeyPair model.ServerKeypair) error
|
||||||
SaveGlobalSettings(globalSettings model.GlobalSetting) error
|
SaveGlobalSettings(globalSettings model.GlobalSetting) error
|
||||||
|
GetWakeOnLanHosts() ([]model.WakeOnLanHost, error)
|
||||||
|
GetWakeOnLanHost(macAddress string) (*model.WakeOnLanHost, error)
|
||||||
|
DeleteWakeOnHostLanHost(macAddress string) error
|
||||||
|
SaveWakeOnLanHost(host model.WakeOnLanHost) error
|
||||||
|
DeleteWakeOnHost(host model.WakeOnLanHost) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,15 @@
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/wake_on_lan_hosts" class="nav-link {{if eq .baseData.Active "wake_on_lan_hosts" }}active{{end}}">
|
||||||
|
<i class="nav-icon fas fa-solid fa-power-off"></i>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Wake On Lan Hosts
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<!-- /.sidebar-menu -->
|
<!-- /.sidebar-menu -->
|
||||||
|
|
123
templates/wake_on_lan_hosts.html
Normal file
123
templates/wake_on_lan_hosts.html
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
{{define "title"}}
|
||||||
|
Wake On Lan Hosts
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "top_css"}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "username"}}
|
||||||
|
{{ .username }}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "page_title"}}
|
||||||
|
Wake On Lan Hosts
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "page_content"}}
|
||||||
|
|
||||||
|
<div class="modal fade" id="modal_wake_on_lan_host">
|
||||||
|
<!-- MacAddress string `json:"MacAddress"`-->
|
||||||
|
<!-- Name string `json:"Name"`-->
|
||||||
|
<!-- LatestIPAddress string `json:"LatestIPAddress"`-->
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">New Wake On Lan Host</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form name="frm_wake_on_lan_host" id="frm_wake_on_lan_host">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" id="frm_wake_on_lan_host_old_mac_address" name="old_mac_address">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="frm_wake_on_lan_host_name" class="control-label">Name</label>
|
||||||
|
<input type="text" class="form-control" id="frm_wake_on_lan_host_name" name="name">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="frm_wake_on_lan_host_mac_address" class="control-label">Mac Address</label>
|
||||||
|
<input type="text" class="form-control" id="frm_wake_on_lan_host_mac_address"
|
||||||
|
name="mac_address">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer justify-content-between">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- /.modal-content -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modal_remove_wake_on_lan_host">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content bg-danger">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Remove</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer justify-content-between">
|
||||||
|
<button type="button" class="btn btn-outline-dark" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-outline-dark" id="remove_wake_on_host_confirm">Apply</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.modal-content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.modal-dialog -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
{{ if .error }}
|
||||||
|
<div class="alert alert-warning" role="alert">{{.error}}</div>
|
||||||
|
{{ end}}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{{ range $idx, $host := .hosts }}
|
||||||
|
{{- /*gotype: github.com/ngoduykhanh/wireguard-ui/model.WakeOnLanHost*/ -}}
|
||||||
|
<div class="col-sm-4" id="{{ $host.ResolveResourceName }}">
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-box-content">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-outline-success btn-sm"
|
||||||
|
data-mac-address="{{ .MacAddress }}">Wake On
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-outline-primary btn-sm btn_modify_wake_on_lan_host"
|
||||||
|
data-toggle="modal" data-target="#modal_wake_on_lan_host"
|
||||||
|
data-name="{{ .Name }}" data-mac-address="{{ .MacAddress }}">Edit
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
|
||||||
|
data-target="#modal_remove_wake_on_lan_host"
|
||||||
|
data-mac-address="{{ .MacAddress }}">Remove
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<span class="info-box-text"><i class="fas fa-address-card"></i> <span class="name">{{ .Name }}</span></span>
|
||||||
|
<span class="info-box-text"><i class="fas fa-ethernet"></i> <span class="mac-address">{{ .MacAddress }}</span></span>
|
||||||
|
<span class="info-box-text"><i class="fas fa-clock"></i>
|
||||||
|
<span class="latest-used">
|
||||||
|
{{ if .LatestUsed }}
|
||||||
|
{{ .LatestUsed }}
|
||||||
|
{{ else }}
|
||||||
|
Unused
|
||||||
|
{{ end }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
{{define "bottom_js"}}
|
||||||
|
<script src="/static/custom/js/wake_on_lan_hosts.js"></script>
|
||||||
|
{{end}}
|
Loading…
Add table
Reference in a new issue