luci-app-pbr: update to 1.1.4-5
[project/luci.git] / applications / luci-app-pbr / htdocs / luci-static / resources / view / pbr / overview.js
1 // Copyright 2022 Stan Grishin <stangri@melmac.ca>
2 // This code wouldn't have been possible without help from [@vsviridov](https://github.com/vsviridov)
3
4 "use strict";
5 "require form";
6 "require rpc";
7 "require view";
8 "require pbr.status as pbr";
9
10 var pkg = {
11 get Name() {
12 return "pbr";
13 },
14
15 get URL() {
16 return "https://docs.openwrt.melmac.net/" + pkg.Name + "/";
17 },
18 };
19
20 return view.extend({
21 load: function () {
22 return Promise.all([
23 L.resolveDefault(pbr.getInterfaces(pkg.Name), {}),
24 L.resolveDefault(pbr.getPlatformSupport(pkg.Name), {}),
25 L.resolveDefault(L.uci.load(pkg.Name), {}),
26 ]);
27 },
28
29 render: function (data) {
30 var status, m, s, o;
31 var reply = {
32 interfaces: (data[0] &&
33 data[0][pkg.Name] &&
34 data[0][pkg.Name].interfaces) || ["wan"],
35 platform: (data[1] && data[1][pkg.Name]) || {
36 ipset_installed: null,
37 nft_installed: null,
38 adguardhome_installed: null,
39 dnsmasq_installed: null,
40 unbound_installed: null,
41 adguardhome_ipset_support: null,
42 dnsmasq_ipset_support: null,
43 dnsmasq_nftset_support: null,
44 },
45 };
46
47 status = new pbr.status();
48 m = new form.Map(pkg.Name, _("Policy Based Routing - Configuration"));
49
50 s = m.section(form.NamedSection, "config", pkg.Name);
51 s.tab("tab_basic", _("Basic Configuration"));
52 s.tab(
53 "tab_advanced",
54 _("Advanced Configuration"),
55 _(
56 "%sWARNING:%s Please make sure to check the %sREADME%s before changing anything in this section! " +
57 "Change any of the settings below with extreme caution!%s"
58 ).format(
59 "<br/>&#160;&#160;&#160;&#160;<b>",
60 "</b>",
61 '<a href="' +
62 pkg.URL +
63 '#ServiceConfigurationSettings" target="_blank">',
64 "</a>",
65 "<br/><br/>"
66 )
67 );
68
69 s.tab("tab_webui", _("Web UI Configuration"));
70
71 o = s.taboption(
72 "tab_basic",
73 form.ListValue,
74 "verbosity",
75 _("Output verbosity"),
76 _("Controls both system log and console output verbosity.")
77 );
78 o.value("0", _("Suppress/No output"));
79 o.value("1", _("Condensed output"));
80 o.value("2", _("Verbose output"));
81 o.default = "2";
82
83 o = s.taboption(
84 "tab_basic",
85 form.ListValue,
86 "strict_enforcement",
87 _("Strict enforcement"),
88 _("See the %sREADME%s for details.").format(
89 '<a href="' + pkg.URL + '#StrictEnforcement" target="_blank">',
90 "</a>"
91 )
92 );
93 o.value("0", _("Do not enforce policies when their gateway is down"));
94 o.value("1", _("Strictly enforce policies when their gateway is down"));
95 o.default = "1";
96
97 var text = "";
98 if (reply.platform.adguardhome_ipset_support === null) {
99 text +=
100 _("The %s support is unknown.").format("<i>adguardhome.ipset</i>") +
101 "<br />";
102 } else if (!reply.platform.adguardhome_ipset_support) {
103 text +=
104 _("The %s is not supported on this system.").format(
105 "<i>adguardhome.ipset</i>"
106 ) + "<br />";
107 }
108 if (reply.platform.dnsmasq_ipset_support === null) {
109 text +=
110 _("The %s support is unknown.").format("<i>dnsmasq.ipset</i>") +
111 "<br />";
112 } else if (!reply.platform.dnsmasq_ipset_support) {
113 text +=
114 _("The %s is not supported on this system.").format(
115 "<i>dnsmasq.ipset</i>"
116 ) + "<br />";
117 }
118 if (reply.platform.dnsmasq_nftset_support === null) {
119 text +=
120 _("The %s support is unknown.").format("<i>dnsmasq.nftset</i>") +
121 "<br />";
122 } else if (!reply.platform.dnsmasq_nftset_support) {
123 text +=
124 _("The %s is not supported on this system.").format(
125 "<i>dnsmasq.nftset</i>"
126 ) + "<br />";
127 }
128 text += _(
129 "Please check the %sREADME%s before changing this option."
130 ).format(
131 '<a href="' + pkg.URL + '#UseResolversSetSupport" target="_blank">',
132 "</a>"
133 );
134
135 o = s.taboption(
136 "tab_basic",
137 form.ListValue,
138 "resolver_set",
139 _("Use resolver set support for domains"),
140 text
141 );
142 o.value("none", _("Disabled"));
143 if (reply.platform.adguardhome_ipset_support) {
144 o.value("adguardhome.ipset", _("AdGuardHome ipset"));
145 o.default = "adguardhome.ipset";
146 }
147 if (reply.platform.dnsmasq_ipset_support) {
148 o.value("dnsmasq.ipset", _("Dnsmasq ipset"));
149 o.default = "dnsmasq.ipset";
150 }
151 if (reply.platform.dnsmasq_nftset_support) {
152 o.value("dnsmasq.nftset", _("Dnsmasq nft set"));
153 o.default = "dnsmasq.nftset";
154 }
155
156 o = s.taboption(
157 "tab_basic",
158 form.ListValue,
159 "ipv6_enabled",
160 _("IPv6 Support")
161 );
162 o.value("0", _("Disabled"));
163 o.value("1", _("Enabled"));
164
165 o = s.taboption(
166 "tab_advanced",
167 form.DynamicList,
168 "supported_interface",
169 _("Supported Interfaces"),
170 _(
171 "Allows to specify the list of interface names (in lower case) to be explicitly supported by the service. " +
172 "Can be useful if your OpenVPN tunnels have dev option other than tun* or tap*."
173 )
174 );
175 o.optional = false;
176
177 o = s.taboption(
178 "tab_advanced",
179 form.DynamicList,
180 "ignored_interface",
181 _("Ignored Interfaces"),
182 _(
183 "Allows to specify the list of interface names (in lower case) to be ignored by the service. " +
184 "Can be useful if running both VPN server and VPN client on the router."
185 )
186 );
187 o.optional = false;
188
189 o = s.taboption(
190 "tab_advanced",
191 form.ListValue,
192 "rule_create_option",
193 _("Rule Create option"),
194 _("Select Add for -A/add and Insert for -I/Insert.")
195 );
196 o.value("add", _("Add"));
197 o.value("insert", _("Insert"));
198 o.default = "add";
199
200 o = s.taboption(
201 "tab_advanced",
202 form.ListValue,
203 "icmp_interface",
204 _("Default ICMP Interface"),
205 _("Force the ICMP protocol interface.")
206 );
207 o.value("", _("No Change"));
208 reply.interfaces.forEach((element) => {
209 if (element.toLowerCase() !== "ignore") {
210 o.value(element);
211 }
212 });
213 o.rmempty = true;
214
215 o = s.taboption(
216 "tab_advanced",
217 form.Value,
218 "wan_mark",
219 _("WAN Table FW Mark"),
220 _(
221 "Starting (WAN) FW Mark for marks used by the service. High starting mark is " +
222 "used to avoid conflict with SQM/QoS. Change with caution together with"
223 ) +
224 " " +
225 _("Service FW Mask") +
226 "."
227 );
228 o.rmempty = true;
229 o.placeholder = "010000";
230 o.datatype = "hexstring";
231
232 o = s.taboption(
233 "tab_advanced",
234 form.Value,
235 "fw_mask",
236 _("Service FW Mask"),
237 _(
238 "FW Mask used by the service. High mask is used to avoid conflict with SQM/QoS. " +
239 "Change with caution together with"
240 ) +
241 " " +
242 _("WAN Table FW Mark") +
243 "."
244 );
245 o.rmempty = true;
246 o.placeholder = "ff0000";
247 o.datatype = "hexstring";
248
249 o = s.taboption(
250 "tab_webui",
251 form.ListValue,
252 "webui_show_ignore_target",
253 _("Add Ignore Target"),
254 _(
255 "Adds 'ignore' to the list of interfaces for policies. See the %sREADME%s for details."
256 ).format(
257 '<a href="' + pkg.URL + '#IgnoreTarget" target="_blank">',
258 "</a>"
259 )
260 );
261 o.value("0", _("Disabled"));
262 o.value("1", _("Enabled"));
263 o.default = "0";
264 o.optional = false;
265
266 o = s.taboption(
267 "tab_webui",
268 form.DynamicList,
269 "webui_supported_protocol",
270 _("Supported Protocols"),
271 _("Display these protocols in protocol column in Web UI.")
272 );
273 o.optional = false;
274
275 s = m.section(
276 form.GridSection,
277 "policy",
278 _("Policies"),
279 _(
280 "Name, interface and at least one other field are required. Multiple local and remote " +
281 "addresses/devices/domains and ports can be space separated. Placeholders below represent just " +
282 "the format/syntax and will not be used if fields are left blank."
283 )
284 );
285 s.rowcolors = true;
286 s.sortable = true;
287 s.anonymous = true;
288 s.addremove = true;
289
290 o = s.option(form.Flag, "enabled", _("Enabled"));
291 o.default = "1";
292 o.editable = true;
293
294 o = s.option(form.Value, "name", _("Name"));
295
296 o = s.option(form.Value, "src_addr", _("Local addresses / devices"));
297 o.datatype =
298 "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network,string)))";
299 o.rmempty = true;
300 o.default = "";
301
302 o = s.option(form.Value, "src_port", _("Local ports"));
303 o.datatype = "list(neg(or(portrange,port)))";
304 o.placeholder = "0-65535";
305 o.rmempty = true;
306 o.default = "";
307
308 o = s.option(form.Value, "dest_addr", _("Remote addresses / domains"));
309 o.datatype =
310 "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network,string)))";
311 o.rmempty = true;
312 o.default = "";
313
314 o = s.option(form.Value, "dest_port", _("Remote ports"));
315 o.datatype = "list(neg(or(portrange,port)))";
316 o.placeholder = "0-65535";
317 o.rmempty = true;
318 o.default = "";
319
320 o = s.option(form.ListValue, "proto", _("Protocol"));
321 var proto = L.toArray(
322 L.uci.get(pkg.Name, "config", "webui_supported_protocol")
323 );
324 if (!proto.length) {
325 proto = ["all", "tcp", "udp", "tcp udp", "icmp"];
326 }
327 proto.forEach((element) => {
328 if (element === "all") {
329 o.value("", _("all"));
330 o.default = "";
331 } else {
332 o.value(element.toLowerCase());
333 }
334 });
335 o.rmempty = true;
336
337 o = s.option(form.ListValue, "chain", _("Chain"));
338 o.value("", "prerouting");
339 o.value("forward", "forward");
340 o.value("input", "input");
341 o.value("output", "output");
342 o.value("postrouting", "postrouting");
343 o.default = "";
344 o.rmempty = true;
345
346 o = s.option(form.ListValue, "interface", _("Interface"));
347 reply.interfaces.forEach((element) => {
348 o.value(element);
349 });
350 o.datatype = "network";
351 o.rmempty = false;
352
353 s = m.section(
354 form.NamedSection,
355 "config",
356 pkg.Name,
357 _("DSCP Tagging"),
358 _(
359 "Set DSCP tags (in range between 1 and 63) for specific interfaces. See the %sREADME%s for details."
360 ).format(
361 '<a href="' + pkg.URL + "#DSCPTag-BasedPolicies" + '" target="_blank">',
362 "</a>"
363 )
364 );
365 reply.interfaces.forEach((element) => {
366 if (element.toLowerCase() !== "ignore") {
367 o = s.option(
368 form.Value,
369 element + "_dscp",
370 element.toUpperCase() + " " + _("DSCP Tag")
371 );
372 o.datatype = "and(uinteger, min(1), max(63))";
373 }
374 });
375
376 s = m.section(
377 form.GridSection,
378 "include",
379 _("Custom User File Includes"),
380 _(
381 "Run the following user files after setting up but before restarting DNSMASQ. " +
382 "See the %sREADME%s for details."
383 ).format(
384 '<a href="' + pkg.URL + '#CustomUserFiles" target="_blank">',
385 "</a>"
386 )
387 );
388 s.sortable = true;
389 s.anonymous = true;
390 s.addremove = true;
391
392 o = s.option(form.Flag, "enabled", _("Enabled"));
393 o.optional = false;
394 o.editable = true;
395 o.rmempty = false;
396
397 o = s.option(form.Value, "path", _("Path"));
398 o.optional = false;
399 o.editable = true;
400 o.rmempty = false;
401
402 return Promise.all([status.render(), m.render()]);
403 },
404 });