luci-app-pbr: initial commit
[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 uci';
8 'require view';
9 'require pbr.status as pbr';
10
11 var pkg = {
12 get Name() { return 'pbr'; },
13 get URL() { return 'https://docs.openwrt.melmac.net/' + pkg.Name + '/'; }
14 };
15
16 return view.extend({
17 load: function () {
18 return Promise.all([
19 uci.load(pkg.Name)
20 ]);
21 },
22
23 render: function () {
24 return Promise.all([
25 L.resolveDefault(pbr.getInterfaces(), {}),
26 L.resolveDefault(pbr.getPlatformSupport(), {}),
27 ]).then(function (data) {
28 var arrInterfaces = data[0][pkg.Name].interfaces;
29 var replyPlatform = data[1][pkg.Name];
30 var status, m, s, o;
31
32 status = new pbr.status();
33 m = new form.Map(pkg.Name, _("Policy Based Routing - Configuration"));
34
35 s = m.section(form.NamedSection, 'config', pkg.Name);
36 s.tab("tab_basic", _("Basic Configuration"));
37 s.tab("tab_advanced", _("Advanced Configuration"),
38 _("%sWARNING:%s Please make sure to check the %sREADME%s before changing anything in this section! " +
39 "Change any of the settings below with extreme caution!%s").format(
40 "<br/>&#160;&#160;&#160;&#160;<b>", "</b>",
41 "<a href=\"" + pkg.URL + "#service-configuration-settings \" target=\"_blank\">", "</a>", "<br/><br/>"));
42 s.tab("tab_webui", _("Web UI Configuration"))
43
44 o = s.taboption("tab_basic", form.ListValue, "verbosity", _("Output verbosity"),
45 _("Controls both system log and console output verbosity."));
46 o.value("0", _("Suppress/No output"));
47 o.value("1", _("Condensed output"));
48 o.value("2", _("Verbose output"));
49 o.default = "2";
50
51 o = s.taboption("tab_basic", form.ListValue, "strict_enforcement", _("Strict enforcement"),
52 _("See the %sREADME%s for details.").format(
53 "<a href=\"" + pkg.URL + "#strict-enforcement\" target=\"_blank\">", "</a>"));
54 o.value("0", _("Do not enforce policies when their gateway is down"));
55 o.value("1", _("Strictly enforce policies when their gateway is down"));
56 o.default = "1";
57
58 var text = "";
59 if (!(replyPlatform.adguardhome_ipset_support)) {
60 text += _("The %s is not supported on this system.").format("<i>adguardhome.ipset</i>") + "<br />"
61 }
62 if (!(replyPlatform.dnsmasq_ipset_support)) {
63 text += _("The %s is not supported on this system.").format("<i>dnsmasq.ipset</i>") + "<br />"
64 }
65 if (!(replyPlatform.dnsmasq_nftset_support)) {
66 text += _("The %s is not supported on this system.").format("<i>dnsmasq.nftset</i>") + "<br />"
67 }
68 text += _("Please check the %sREADME%s before changing this option.").format(
69 "<a href=\"" + pkg.URL + "#use-resolvers-set-support\" target=\"_blank\">", "</a>");
70 o = s.taboption("tab_basic", form.ListValue, "resolver_set", _("Use resolver set support for domains"), text);
71 o.value("none", _("Disabled"));
72 if (replyPlatform.adguardhome_ipset_support) {
73 o.value("adguardhome.ipset", _("AdGuardHome ipset"));
74 o.default = ("adguardhome.ipset", _("AdGuardHome ipset"));
75 }
76 if (replyPlatform.dnsmasq_ipset_support) {
77 o.value("dnsmasq.ipset", _("Dnsmasq ipset"));
78 o.default = ("dnsmasq.ipset", _("Dnsmasq ipset"));
79 }
80 if (replyPlatform.dnsmasq_nftset_support) {
81 o.value("dnsmasq.nftset", _("Dnsmasq nft set"));
82 o.default = ("dnsmasq.nftset", _("Dnsmasq nft set"));
83 }
84
85 o = s.taboption("tab_basic", form.ListValue, "ipv6_enabled", _("IPv6 Support"));
86 o.value("0", _("Disabled"));
87 o.value("1", _("Enabled"));
88
89 o = s.taboption("tab_advanced", form.DynamicList, "supported_interface", _("Supported Interfaces"),
90 _("Allows to specify the list of interface names (in lower case) to be explicitly supported by the service. " +
91 "Can be useful if your OpenVPN tunnels have dev option other than tun* or tap*."));
92 o.optional = false;
93
94 o = s.taboption("tab_advanced", form.DynamicList, "ignored_interface", _("Ignored Interfaces"),
95 _("Allows to specify the list of interface names (in lower case) to be ignored by the service. " +
96 "Can be useful if running both VPN server and VPN client on the router."));
97 o.optional = false;
98
99 o = s.taboption("tab_advanced", form.ListValue, "rule_create_option", _("Rule Create option"),
100 _("Select Add for -A/add and Insert for -I/Insert."));
101 o.value("add", _("Add"));
102 o.value("insert", _("Insert"));
103 o.default = "add";
104
105 o = s.taboption("tab_advanced", form.ListValue, "icmp_interface", _("Default ICMP Interface"),
106 _("Force the ICMP protocol interface."));
107 o.value("", _("No Change"));
108 arrInterfaces.forEach(element => {
109 if (element.toLowerCase() !== "ignore") {
110 o.value(element);
111 }
112 });
113 o.rmempty = true;
114
115 o = s.taboption("tab_advanced", form.Value, "wan_tid", _("WAN Table ID"),
116 _("Starting (WAN) Table ID number for tables created by the service."));
117 o.rmempty = true;
118 o.placeholder = "201";
119 o.datatype = "and(uinteger, min(201))";
120
121 o = s.taboption("tab_advanced", form.Value, "wan_mark", _("WAN Table FW Mark"),
122 _("Starting (WAN) FW Mark for marks used by the service. High starting mark is " +
123 "used to avoid conflict with SQM/QoS. Change with caution together with") +
124 " " + _("Service FW Mask") + ".");
125 o.rmempty = true;
126 o.placeholder = "010000";
127 o.datatype = "hexstring";
128
129 o = s.taboption("tab_advanced", form.Value, "fw_mask", _("Service FW Mask"),
130 _("FW Mask used by the service. High mask is used to avoid conflict with SQM/QoS. " +
131 "Change with caution together with") + " " + _("WAN Table FW Mark") + ".");
132 o.rmempty = true;
133 o.placeholder = "ff0000";
134 o.datatype = "hexstring";
135
136 o = s.taboption("tab_webui", form.ListValue, "webui_show_ignore_target", _("Add Ignore Target"),
137 _("Adds 'ignore' to the list of interfaces for policies. See the %sREADME%s for details.").format(
138 "<a href=\"" + pkg.URL + "#ignore-target\" target=\"_blank\">", "</a>"));
139 o.value("0", _("Disabled"))
140 o.value("1", _("Enabled"))
141 o.default = "0";
142 o.optional = false;
143
144 o = s.taboption("tab_webui", form.DynamicList, "webui_supported_protocol", _("Supported Protocols"),
145 _("Display these protocols in protocol column in Web UI."));
146 o.optional = false;
147
148 s = m.section(form.GridSection, 'policy', _('Policies'),
149 _("Name, interface and at least one other field are required. Multiple local and remote " +
150 "addresses/devices/domains and ports can be space separated. Placeholders below represent just " +
151 "the format/syntax and will not be used if fields are left blank."));
152 s.rowcolors = true;
153 s.sortable = true;
154 s.anonymous = true;
155 s.addremove = true;
156
157 o = s.option(form.Flag, "enabled", _("Enabled"));
158 o.default = "1";
159 o.editable = true;
160
161 o = s.option(form.Value, "name", _("Name"));
162
163 o = s.option(form.Value, "src_addr", _("Local addresses / devices"));
164 o.datatype = "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network)))";
165 o.rmempty = true;
166 o.default = "";
167
168 o = s.option(form.Value, "src_port", _("Local ports"));
169 o.datatype = "list(neg(or(portrange,port)))";
170 o.placeholder = "0-65535";
171 o.rmempty = true;
172 o.default = "";
173
174 o = s.option(form.Value, "dest_addr", _("Remote addresses / domains"));
175 o.datatype = "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network)))";
176 o.rmempty = true;
177 o.default = "";
178
179 o = s.option(form.Value, "dest_port", _("Remote ports"));
180 o.datatype = "list(neg(or(portrange,port)))";
181 o.placeholder = "0-65535";
182 o.rmempty = true;
183 o.default = "";
184
185 o = s.option(form.ListValue, "proto", _("Protocol"));
186 var proto = L.toArray(uci.get(pkg.Name, "config", "webui_supported_protocol"));
187 if (!proto.length) {
188 proto = ["all", "tcp", "udp", "tcp udp", "icmp"]
189 }
190 proto.forEach(element => {
191 if (element === "all") {
192 o.value("", _("all"));
193 o.default = ("", _("all"));
194 }
195 else {
196 o.value(element.toLowerCase());
197 }
198 });
199 o.rmempty = true;
200
201 o = s.option(form.ListValue, "chain", _("Chain"));
202 o.value("", "prerouting");
203 o.value("forward", "forward");
204 o.value("input", "input");
205 o.value("output", "output");
206 o.value("postrouting", "postrouting");
207 o.default = ("", "prerouting");
208 o.rmempty = true;
209
210 o = s.option(form.ListValue, "interface", _("Interface"));
211 arrInterfaces.forEach(element => {
212 o.value(element);
213 });
214 o.datatype = "network";
215 o.rmempty = false;
216
217 s = m.section(form.NamedSection, 'config', pkg.Name, _("DSCP Tagging"),
218 _("Set DSCP tags (in range between 1 and 63) for specific interfaces. See the %sREADME%s for details.").format(
219 "<a href=\"" + pkg.URL + "#dscp-tag-based-policies" + "\" target=\"_blank\">", "</a>"));
220 arrInterfaces.forEach(element => {
221 if (element.toLowerCase() !== "ignore") {
222 o = s.option(form.Value, element + "_dscp", element.toUpperCase() + " " + _("DSCP Tag"));
223 o.datatype = "and(uinteger, min(1), max(63))";
224 }
225 });
226
227 s = m.section(form.GridSection, 'include', _("Custom User File Includes"),
228 _("Run the following user files after setting up but before restarting DNSMASQ. " +
229 "See the %sREADME%s for details.").format(
230 "<a href=\"" + pkg.URL + "#custom-user-files\" target=\"_blank\">", "</a>"));
231 s.sortable = true;
232 s.anonymous = true;
233 s.addremove = true;
234
235 o = s.option(form.Flag, "enabled", _("Enabled"));
236 o.optional = false;
237 o.editable = true;
238
239 o = s.option(form.Value, "path", _("Path"));
240 o.optional = false;
241 o.editable = true;
242
243 return Promise.all([status.render(), m.render()]);
244 })
245 }
246 });