openwrt-bgme-feed/luci-app-einat/htdocs/luci-static/resources/view/einat.js

184 lines
4.7 KiB
JavaScript

'use strict';
'require form';
'require fs';
'require uci';
'require ui';
'require rpc';
'require poll';
'require view';
'require network';
'require tools.widgets as widgets';
const conf = 'einat';
const instance = 'einat';
const callServiceList = rpc.declare({
object: 'service',
method: 'list',
params: ['name'],
expect: { '': {} }
});
const callRcInit = rpc.declare({
object: 'rc',
method: 'init',
params: ['name', 'action']
});
const callGetFeatures = rpc.declare({
object: 'luci.einat',
method: 'get_features',
expect: { '': {} }
});
function getServiceStatus() {
return L.resolveDefault(callServiceList(conf), {})
.then((res) => {
let isrunning = false;
try {
isrunning = res[conf]['instances'][instance]['running'];
} catch (e) { }
return isrunning;
});
}
function handleAction(action, ev) {
return callRcInit("einat", action).then((ret) => {
if (ret)
throw _('Command failed');
return true;
}).catch((e) => {
ui.addNotification(null, E('p', _('Failed to execute "/etc/init.d/%s %s" action: %s').format("einat", action, e)));
});
}
return view.extend({
load() {
return Promise.all([
getServiceStatus(),
L.resolveDefault(fs.stat('/usr/bin/einat'), null),
callGetFeatures(),
uci.load('einat')
]);
},
poll_status(nodes, stat) {
const isRunning = stat[0];
let view = nodes.querySelector('#service_status');
if (isRunning) {
view.innerHTML = "<span style=\"color:green;font-weight:bold\">" + instance + " - " + _("SERVER RUNNING") + "</span>";
} else {
view.innerHTML = "<span style=\"color:red;font-weight:bold\">" + instance + " - " + _("SERVER NOT RUNNING") + "</span>";
}
return;
},
render(res) {
const isRunning = res[0];
const has_einat = res[1] ? res[1].path : null;
const features = res[2];
let m, s, o;
m = new form.Map('einat', _('einat-ebpf'), _('eBPF-based Endpoint-Independent NAT'));
s = m.section(form.NamedSection, '_status');
s.anonymous = true;
s.render = function(section_id) {
return E('div', { class: 'cbi-section' }, [
E('div', { id: 'service_status' }, _('Collecting data ...'))
]);
};
s = m.section(form.NamedSection, 'config', instance);
s.anonymous = true;
o = s.option(form.Button, '_reload', _('Reload'));
o.inputtitle = _('Reload');
o.inputstyle = 'apply';
o.onclick = function() {
return handleAction('reload');
};
o = s.option(form.Flag, 'enabled', _('Enable'));
o.default = o.disabled;
o.rmempty = false;
if (! has_einat) {
o.description = _('To enable you need install <b>einat-ebpf</b> first');
o.readonly = true;
}
o = s.option(form.ListValue, 'bpf_log_level', _('BPF tracing log level'));
o.default = '0';
o.value('0', 'disable - ' + _('Disable'));
o.value('1', 'error - ' + _('Error'));
o.value('2', 'warn - ' + _('Warn'));
o.value('3', 'info - ' + _('Info'));
o.value('4', 'debug - ' + _('Debug'));
o.value('5', 'trace - ' + _('Trace'));
o = s.option(form.ListValue, 'bpf_loader', _('BPF loading backend'));
o.value('', _('Default'));
if (features.features.includes('aya'))
o.value('aya', _('aya'));
if (features.features.includes('libbpf'))
o.value('libbpf', _('libbpf'));
o = s.option(form.Flag, 'nat44', _('NAT44'));
o.default = o.disabled;
o.rmempty = false;
//o = s.option(form.Flag, 'nat66', _('NAT66'));
//o.default = o.disabled;
//o.rmempty = false;
o = s.option(widgets.DeviceSelect, 'ifname', _('External interface'));
o.multiple = false;
o.noaliases = true;
o.nobridges = true;
o.nocreate = true;
o = s.option(form.Value, 'ports', _('External TCP/UDP port ranges'),
_('Please avoid conflicts with external ports used by other applications'));
o.datatype = 'portrange';
o.placeholder = '20000-29999';
o.rmempty = true;
o = s.option(widgets.NetworkSelect, 'internal_ifaces', _('Internal interfaces'),
_('Perform source NAT for these internal networks only.'));
o.multiple = true;
o.nocreate = true;
o = s.option(form.DynamicList, 'internal_subnets', _('Internal subnets'),
_('Perform source NAT for these internal networks only.'));
o.datatype = 'cidr';
o.placeholder = '192.168.0.0/16';
o = s.option(form.Flag, 'hairpin_enabled', _('Enable hairpin'),
_('May conflict with other policy routing-based applications'));
o.default = o.disabled;
o.rmempty = false;
o = s.option(widgets.DeviceSelect, 'hairpinif', _('Hairpin internal interfaces'));
o.multiple = true;
o.noaliases = true;
o.nobridges = false;
o.nocreate = true;
o.depends('hairpin_enabled', '1');
o.rmempty = true;
o.retain = true;
return m.render()
.then(L.bind(function(m, nodes) {
poll.add(L.bind(function() {
return Promise.all([
getServiceStatus()
]).then(L.bind(this.poll_status, this, nodes));
}, this), 3);
return nodes;
}, this, m));
}
});