Merge pull request #6386 from egc112/egc112-openvpn-advanced-lua
[project/luci.git] / modules / luci-mod-status / htdocs / luci-static / resources / view / status / include / 40_dhcp.js
1 'use strict';
2 'require baseclass';
3 'require rpc';
4 'require uci';
5 'require network';
6 'require validation';
7
8 var callLuciDHCPLeases = rpc.declare({
9 object: 'luci-rpc',
10 method: 'getDHCPLeases',
11 expect: { '': {} }
12 });
13
14 return baseclass.extend({
15 title: '',
16
17 isMACStatic: {},
18 isDUIDStatic: {},
19
20 load: function() {
21 return Promise.all([
22 callLuciDHCPLeases(),
23 network.getHostHints(),
24 L.resolveDefault(uci.load('dhcp'))
25 ]);
26 },
27
28 handleCreateStaticLease: function(lease, ev) {
29 ev.currentTarget.classList.add('spinning');
30 ev.currentTarget.disabled = true;
31 ev.currentTarget.blur();
32
33 var cfg = uci.add('dhcp', 'host');
34 uci.set('dhcp', cfg, 'name', lease.hostname);
35 uci.set('dhcp', cfg, 'ip', lease.ipaddr);
36 uci.set('dhcp', cfg, 'mac', lease.macaddr.toUpperCase());
37
38 return uci.save()
39 .then(L.bind(L.ui.changes.init, L.ui.changes))
40 .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
41 },
42
43 handleCreateStaticLease6: function(lease, ev) {
44 ev.currentTarget.classList.add('spinning');
45 ev.currentTarget.disabled = true;
46 ev.currentTarget.blur();
47
48 var cfg = uci.add('dhcp', 'host'),
49 ip6arr = lease.ip6addrs[0] ? validation.parseIPv6(lease.ip6addrs[0]) : null;
50
51 uci.set('dhcp', cfg, 'name', lease.hostname);
52 uci.set('dhcp', cfg, 'duid', lease.duid.toUpperCase());
53 uci.set('dhcp', cfg, 'mac', lease.macaddr);
54 if (ip6arr)
55 uci.set('dhcp', cfg, 'hostid', (ip6arr[6] * 0xFFFF + ip6arr[7]).toString(16));
56
57 return uci.save()
58 .then(L.bind(L.ui.changes.init, L.ui.changes))
59 .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
60 },
61
62 renderLeases: function(data) {
63 var leases = Array.isArray(data[0].dhcp_leases) ? data[0].dhcp_leases : [],
64 leases6 = Array.isArray(data[0].dhcp6_leases) ? data[0].dhcp6_leases : [],
65 machints = data[1].getMACHints(false),
66 hosts = uci.sections('dhcp', 'host'),
67 isReadonlyView = !L.hasViewPermission();
68
69 for (var i = 0; i < hosts.length; i++) {
70 var host = hosts[i];
71
72 if (host.mac) {
73 var macs = L.toArray(host.mac);
74 for (var j = 0; j < macs.length; j++) {
75 var mac = macs[j].toUpperCase();
76 this.isMACStatic[mac] = true;
77 }
78 }
79 if (host.duid) {
80 var duid = host.duid.toUpperCase();
81 this.isDUIDStatic[duid] = true;
82 }
83 };
84
85 var table = E('table', { 'id': 'status_leases', 'class': 'table lases' }, [
86 E('tr', { 'class': 'tr table-titles' }, [
87 E('th', { 'class': 'th' }, _('Hostname')),
88 E('th', { 'class': 'th' }, _('IPv4 address')),
89 E('th', { 'class': 'th' }, _('MAC address')),
90 E('th', { 'class': 'th' }, _('Lease time remaining')),
91 isReadonlyView ? E([]) : E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
92 ])
93 ]);
94
95 cbi_update_table(table, leases.map(L.bind(function(lease) {
96 var exp, rows;
97
98 if (lease.expires === false)
99 exp = E('em', _('unlimited'));
100 else if (lease.expires <= 0)
101 exp = E('em', _('expired'));
102 else
103 exp = '%t'.format(lease.expires);
104
105 var hint = lease.macaddr ? machints.filter(function(h) { return h[0] == lease.macaddr })[0] : null,
106 host = null;
107
108 if (hint && lease.hostname && lease.hostname != hint[1])
109 host = '%s (%s)'.format(lease.hostname, hint[1]);
110 else if (lease.hostname)
111 host = lease.hostname;
112
113 rows = [
114 host || '-',
115 lease.ipaddr,
116 lease.macaddr,
117 exp
118 ];
119
120 if (!isReadonlyView && lease.macaddr != null) {
121 var mac = lease.macaddr.toUpperCase();
122 rows.push(E('button', {
123 'class': 'cbi-button cbi-button-apply',
124 'click': L.bind(this.handleCreateStaticLease, this, lease),
125 'disabled': this.isMACStatic[mac]
126 }, [ _('Set Static') ]));
127 }
128
129 return rows;
130 }, this)), E('em', _('There are no active leases')));
131
132 var table6 = E('table', { 'id': 'status_leases6', 'class': 'table leases6' }, [
133 E('tr', { 'class': 'tr table-titles' }, [
134 E('th', { 'class': 'th' }, _('Host')),
135 E('th', { 'class': 'th' }, _('IPv6 address')),
136 E('th', { 'class': 'th' }, _('DUID')),
137 E('th', { 'class': 'th' }, _('Lease time remaining')),
138 isReadonlyView ? E([]) : E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
139 ])
140 ]);
141
142 cbi_update_table(table6, leases6.map(L.bind(function(lease) {
143 var exp, rows;
144
145 if (lease.expires === false)
146 exp = E('em', _('unlimited'));
147 else if (lease.expires <= 0)
148 exp = E('em', _('expired'));
149 else
150 exp = '%t'.format(lease.expires);
151
152 var hint = lease.macaddr ? machints.filter(function(h) { return h[0] == lease.macaddr })[0] : null,
153 host = null;
154
155 if (hint && lease.hostname && lease.hostname != hint[1] && lease.ip6addr != hint[1])
156 host = '%s (%s)'.format(lease.hostname, hint[1]);
157 else if (lease.hostname)
158 host = lease.hostname;
159 else if (hint)
160 host = hint[1];
161
162 rows = [
163 host || '-',
164 lease.ip6addrs ? lease.ip6addrs.join(' ') : lease.ip6addr,
165 lease.duid,
166 exp
167 ];
168
169 if (!isReadonlyView && lease.duid != null) {
170 var duid = lease.duid.toUpperCase();
171 rows.push(E('button', {
172 'class': 'cbi-button cbi-button-apply',
173 'click': L.bind(this.handleCreateStaticLease6, this, lease),
174 'disabled': this.isDUIDStatic[duid]
175 }, [ _('Set Static') ]));
176 }
177
178 return rows;
179 }, this)), E('em', _('There are no active leases')));
180
181 return E([
182 E('h3', _('Active DHCP Leases')),
183 table,
184 E('h3', _('Active DHCPv6 Leases')),
185 table6
186 ]);
187 },
188
189 render: function(data) {
190 if (L.hasSystemFeature('dnsmasq') || L.hasSystemFeature('odhcpd'))
191 return this.renderLeases(data);
192
193 return E([]);
194 }
195 });