b93f26875d8603064b21912f9542fce1d2abc5f6
[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', { '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 rows = [
106 lease.hostname || '-',
107 lease.ipaddr,
108 lease.macaddr,
109 exp
110 ];
111
112 if (!isReadonlyView && lease.macaddr != null) {
113 var mac = lease.macaddr.toUpperCase();
114 rows.push(E('button', {
115 'class': 'cbi-button cbi-button-apply',
116 'click': L.bind(this.handleCreateStaticLease, this, lease),
117 'disabled': this.isMACStatic[mac]
118 }, [ _('Set Static') ]));
119 }
120
121 return rows;
122 }, this)), E('em', _('There are no active leases')));
123
124 var table6 = E('table', { 'class': 'table leases6' }, [
125 E('tr', { 'class': 'tr table-titles' }, [
126 E('th', { 'class': 'th' }, _('Host')),
127 E('th', { 'class': 'th' }, _('IPv6 address')),
128 E('th', { 'class': 'th' }, _('DUID')),
129 E('th', { 'class': 'th' }, _('Lease time remaining')),
130 isReadonlyView ? E([]) : E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
131 ])
132 ]);
133
134 cbi_update_table(table6, leases6.map(L.bind(function(lease) {
135 var exp, rows;
136
137 if (lease.expires === false)
138 exp = E('em', _('unlimited'));
139 else if (lease.expires <= 0)
140 exp = E('em', _('expired'));
141 else
142 exp = '%t'.format(lease.expires);
143
144 var hint = lease.macaddr ? machints.filter(function(h) { return h[0] == lease.macaddr })[0] : null,
145 host = null;
146
147 if (hint && lease.hostname && lease.hostname != hint[1] && lease.ip6addr != hint[1])
148 host = '%s (%s)'.format(lease.hostname, hint[1]);
149 else if (lease.hostname)
150 host = lease.hostname;
151 else if (hint)
152 host = hint[1];
153
154 rows = [
155 host || '-',
156 lease.ip6addrs ? lease.ip6addrs.join(' ') : lease.ip6addr,
157 lease.duid,
158 exp
159 ];
160
161 if (!isReadonlyView && lease.duid != null) {
162 var duid = lease.duid.toUpperCase();
163 rows.push(E('button', {
164 'class': 'cbi-button cbi-button-apply',
165 'click': L.bind(this.handleCreateStaticLease6, this, lease),
166 'disabled': this.isDUIDStatic[duid]
167 }, [ _('Set Static') ]));
168 }
169
170 return rows;
171 }, this)), E('em', _('There are no active leases')));
172
173 return E([
174 E('h3', _('Active DHCP Leases')),
175 table,
176 E('h3', _('Active DHCPv6 Leases')),
177 table6
178 ]);
179 },
180
181 render: function(data) {
182 if (L.hasSystemFeature('dnsmasq') || L.hasSystemFeature('odhcpd'))
183 return this.renderLeases(data);
184
185 return E([]);
186 }
187 });