mirror of
https://github.com/openwrt/luci.git
synced 2025-12-21 21:24:35 +04:00
luci-mod-network: move dnsmasq cfg to own function in dhcp.js
This makes it a bit clearer what is specific to dnsmasq and also prepares for the following patches. No actual code changes. Signed-off-by: David Härdeman <david@hardeman.nu>
This commit is contained in:
committed by
Paul Donald
parent
40642e453e
commit
2e8aebcbdb
@@ -237,210 +237,11 @@ return view.extend({
|
|||||||
|
|
||||||
m = new form.Map('dhcp', _('DHCP'));
|
m = new form.Map('dhcp', _('DHCP'));
|
||||||
|
|
||||||
s = m.section(form.TypedSection, 'dnsmasq');
|
s = this.add_dnsmasq_cfg(m, networks);
|
||||||
s.anonymous = false;
|
|
||||||
s.addremove = true;
|
|
||||||
s.addbtntitle = _('Add server instance', 'Dnsmasq instance');
|
|
||||||
|
|
||||||
s.renderContents = function(/* ... */) {
|
|
||||||
var renderTask = form.TypedSection.prototype.renderContents.apply(this, arguments),
|
|
||||||
sections = this.cfgsections();
|
|
||||||
|
|
||||||
return Promise.resolve(renderTask).then(function(nodes) {
|
|
||||||
if (sections.length < 2) {
|
|
||||||
nodes.querySelector('#cbi-dhcp-dnsmasq > h3').remove();
|
|
||||||
nodes.querySelector('#cbi-dhcp-dnsmasq > .cbi-section-remove').remove();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodes.querySelectorAll('#cbi-dhcp-dnsmasq > .cbi-section-remove').forEach(function(div, i) {
|
|
||||||
var section = uci.get('dhcp', sections[i]),
|
|
||||||
hline = div.nextElementSibling,
|
|
||||||
btn = div.firstElementChild;
|
|
||||||
|
|
||||||
if (!section || section['.anonymous']) {
|
|
||||||
hline.innerText = i ? _('Unnamed instance #%d', 'Dnsmasq instance').format(i+1) : _('Default instance', 'Dnsmasq instance');
|
|
||||||
btn.innerText = i ? _('Remove instance #%d', 'Dnsmasq instance').format(i+1) : _('Remove default instance', 'Dnsmasq instance');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hline.innerText = _('Instance "%q"', 'Dnsmasq instance').format(section['.name']);
|
|
||||||
btn.innerText = _('Remove instance "%q"', 'Dnsmasq instance').format(section['.name']);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
nodes.querySelector('#cbi-dhcp-dnsmasq > .cbi-section-create input').placeholder = _('New instance name…', 'Dnsmasq instance');
|
|
||||||
|
|
||||||
return nodes;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
s.tab('general', _('General'));
|
|
||||||
s.tab('devices', _('Devices & Ports'));
|
|
||||||
s.tab('logging', _('Log'));
|
|
||||||
s.tab('files', _('Files'));
|
|
||||||
s.tab('relay', _('Relay'));
|
|
||||||
s.tab('leases', _('Static Leases'));
|
s.tab('leases', _('Static Leases'));
|
||||||
s.tab('pxe_tftp', _('PXE/TFTP'));
|
s.tab('pxe_tftp', _('PXE/TFTP'));
|
||||||
|
|
||||||
// Begin general
|
|
||||||
s.taboption('general', form.Flag, 'authoritative',
|
|
||||||
_('Authoritative'),
|
|
||||||
_('This is the only DHCP server in the local network.'));
|
|
||||||
|
|
||||||
s.taboption('general', form.Value, 'domain',
|
|
||||||
_('Local domain'),
|
|
||||||
_('Local domain suffix appended to DHCP names and hosts file entries.'));
|
|
||||||
|
|
||||||
o = s.taboption('general', form.Flag, 'sequential_ip',
|
|
||||||
_('Allocate IPs sequentially'),
|
|
||||||
_('Allocate IP addresses sequentially, starting from the lowest available address.'));
|
|
||||||
o.optional = true;
|
|
||||||
|
|
||||||
o = s.taboption('general', form.Value, 'dhcpleasemax',
|
|
||||||
_('Max. DHCP leases'),
|
|
||||||
_('Maximum allowed number of active DHCP leases.'));
|
|
||||||
o.optional = true;
|
|
||||||
o.datatype = 'uinteger';
|
|
||||||
o.placeholder = 150;
|
|
||||||
// End general
|
|
||||||
|
|
||||||
// Begin devices
|
|
||||||
o = s.taboption('devices', form.Flag, 'nonwildcard',
|
|
||||||
_('Non-wildcard'),
|
|
||||||
_('Bind only to configured interface addresses, instead of the wildcard address.'));
|
|
||||||
o.default = o.enabled;
|
|
||||||
o.optional = false;
|
|
||||||
o.rmempty = true;
|
|
||||||
|
|
||||||
o = s.taboption('devices', widgets.NetworkSelect, 'interface',
|
|
||||||
_('Listen interfaces'),
|
|
||||||
_('Listen only on the specified interfaces, and loopback if not excluded explicitly.'));
|
|
||||||
o.multiple = true;
|
|
||||||
o.nocreate = true;
|
|
||||||
|
|
||||||
o = s.taboption('devices', widgets.NetworkSelect, 'notinterface',
|
|
||||||
_('Exclude interfaces'),
|
|
||||||
_('Do not listen on the specified interfaces.'));
|
|
||||||
o.loopback = true;
|
|
||||||
o.multiple = true;
|
|
||||||
o.nocreate = true;
|
|
||||||
// End devices
|
|
||||||
|
|
||||||
// Begin logging
|
|
||||||
o = s.taboption('logging', form.Flag, 'logdhcp',
|
|
||||||
_('Extra DHCP logging'),
|
|
||||||
_('Log all options sent to DHCP clients and the tags used to determine them.'));
|
|
||||||
o.optional = true;
|
|
||||||
|
|
||||||
o = s.taboption('logging', form.Value, 'logfacility',
|
|
||||||
_('Log facility'),
|
|
||||||
_('Set log class/facility for syslog entries.'));
|
|
||||||
o.optional = true;
|
|
||||||
o.value('KERN');
|
|
||||||
o.value('USER');
|
|
||||||
o.value('MAIL');
|
|
||||||
o.value('DAEMON');
|
|
||||||
o.value('AUTH');
|
|
||||||
o.value('LPR');
|
|
||||||
o.value('NEWS');
|
|
||||||
o.value('UUCP');
|
|
||||||
o.value('CRON');
|
|
||||||
o.value('LOCAL0');
|
|
||||||
o.value('LOCAL1');
|
|
||||||
o.value('LOCAL2');
|
|
||||||
o.value('LOCAL3');
|
|
||||||
o.value('LOCAL4');
|
|
||||||
o.value('LOCAL5');
|
|
||||||
o.value('LOCAL6');
|
|
||||||
o.value('LOCAL7');
|
|
||||||
o.value('-', _('stderr'));
|
|
||||||
|
|
||||||
o = s.taboption('logging', form.Flag, 'quietdhcp',
|
|
||||||
_('Suppress logging'),
|
|
||||||
_('Suppress logging of the routine operation for the DHCP protocol.'));
|
|
||||||
o.optional = true;
|
|
||||||
o.depends('logdhcp', '0');
|
|
||||||
// End logging
|
|
||||||
|
|
||||||
// Begin files
|
|
||||||
s.taboption('files', form.Flag, 'readethers',
|
|
||||||
_('Use %s').format('<code>/etc/ethers</code>'),
|
|
||||||
_('Read %s to configure the DHCP server.').format('<code>/etc/ethers</code>'));
|
|
||||||
|
|
||||||
s.taboption('files', form.Value, 'leasefile',
|
|
||||||
_('Lease file'),
|
|
||||||
_('File to store DHCP lease information.'));
|
|
||||||
// End files
|
|
||||||
|
|
||||||
// Begin relay
|
|
||||||
o = s.taboption('relay', form.SectionValue, '__relays__', form.TableSection, 'relay', null,
|
|
||||||
_('Relay DHCP requests elsewhere. OK: v4↔v4, v6↔v6. Not OK: v4↔v6, v6↔v4.')
|
|
||||||
+ '<br />' + _('Note: you may also need a DHCP Proxy (currently unavailable) when specifying a non-standard Relay To port(<code>addr#port</code>).')
|
|
||||||
+ '<br />' + _('You may add multiple unique Relay To on the same Listen addr.'));
|
|
||||||
|
|
||||||
ss = o.subsection;
|
|
||||||
|
|
||||||
ss.addremove = true;
|
|
||||||
ss.anonymous = true;
|
|
||||||
ss.sortable = true;
|
|
||||||
ss.rowcolors = true;
|
|
||||||
ss.nodescriptions = true;
|
|
||||||
|
|
||||||
so = ss.option(form.Value, 'local_addr', _('Relay from'));
|
|
||||||
so.rmempty = false;
|
|
||||||
so.datatype = 'ipaddr';
|
|
||||||
|
|
||||||
for (var family = 4; family <= 6; family += 2) {
|
|
||||||
for (var i = 0; i < networks.length; i++) {
|
|
||||||
if (networks[i].getName() != 'loopback') {
|
|
||||||
var addrs = (family == 6) ? networks[i].getIP6Addrs() : networks[i].getIPAddrs();
|
|
||||||
for (var j = 0; j < addrs.length; j++) {
|
|
||||||
var addr = addrs[j].split('/')[0];
|
|
||||||
so.value(addr, E([], [
|
|
||||||
addr, ' (',
|
|
||||||
widgets.NetworkSelect.prototype.renderIfaceBadge(networks[i]),
|
|
||||||
')'
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
so = ss.option(form.Value, 'server_addr', _('Relay to address'));
|
|
||||||
so.rmempty = false;
|
|
||||||
so.optional = false;
|
|
||||||
so.placeholder = '192.168.10.1#535';
|
|
||||||
so.validate = function(section, value) {
|
|
||||||
var m = this.section.formvalue(section, 'local_addr'),
|
|
||||||
n = this.section.formvalue(section, 'server_addr'),
|
|
||||||
p;
|
|
||||||
|
|
||||||
if (!m || !n) {
|
|
||||||
return _('Both "Relay from" and "Relay to address" must be specified.');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p = n.split('#');
|
|
||||||
if (p.length > 1 && !/^[0-9]+$/.test(p[1]))
|
|
||||||
return _('Expected port number.');
|
|
||||||
else
|
|
||||||
n = p[0];
|
|
||||||
|
|
||||||
if ((validation.parseIPv6(m) && validation.parseIPv6(n)) ||
|
|
||||||
validation.parseIPv4(m) && validation.parseIPv4(n))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return _('Address families of "Relay from" and "Relay to address" must match.')
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
so = ss.option(widgets.NetworkSelect, 'interface', _('Only accept replies via'));
|
|
||||||
so.optional = true;
|
|
||||||
so.rmempty = false;
|
|
||||||
so.placeholder = 'lan';
|
|
||||||
// End relay
|
|
||||||
|
|
||||||
// Begin leases
|
// Begin leases
|
||||||
o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null,
|
o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null,
|
||||||
_('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br /><br />' +
|
_('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br /><br />' +
|
||||||
@@ -836,5 +637,211 @@ return view.extend({
|
|||||||
|
|
||||||
return mapEl;
|
return mapEl;
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
add_dnsmasq_cfg: function(m, networks) {
|
||||||
|
var s, o, ss, so;
|
||||||
|
|
||||||
|
s = m.section(form.TypedSection, 'dnsmasq');
|
||||||
|
s.anonymous = false;
|
||||||
|
s.addremove = true;
|
||||||
|
s.addbtntitle = _('Add server instance', 'Dnsmasq instance');
|
||||||
|
s.renderContents = function(/* ... */) {
|
||||||
|
var renderTask = form.TypedSection.prototype.renderContents.apply(this, arguments),
|
||||||
|
sections = this.cfgsections();
|
||||||
|
|
||||||
|
return Promise.resolve(renderTask).then(function(nodes) {
|
||||||
|
if (sections.length < 2) {
|
||||||
|
nodes.querySelector('#cbi-dhcp-dnsmasq > h3').remove();
|
||||||
|
nodes.querySelector('#cbi-dhcp-dnsmasq > .cbi-section-remove').remove();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nodes.querySelectorAll('#cbi-dhcp-dnsmasq > .cbi-section-remove').forEach(function(div, i) {
|
||||||
|
var section = uci.get('dhcp', sections[i]),
|
||||||
|
hline = div.nextElementSibling,
|
||||||
|
btn = div.firstElementChild;
|
||||||
|
|
||||||
|
if (!section || section['.anonymous']) {
|
||||||
|
hline.innerText = i ? _('Unnamed instance #%d', 'Dnsmasq instance').format(i+1) : _('Default instance', 'Dnsmasq instance');
|
||||||
|
btn.innerText = i ? _('Remove instance #%d', 'Dnsmasq instance').format(i+1) : _('Remove default instance', 'Dnsmasq instance');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hline.innerText = _('Instance "%q"', 'Dnsmasq instance').format(section['.name']);
|
||||||
|
btn.innerText = _('Remove instance "%q"', 'Dnsmasq instance').format(section['.name']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes.querySelector('#cbi-dhcp-dnsmasq > .cbi-section-create input').placeholder = _('New instance name…', 'Dnsmasq instance');
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
s.tab('general', _('General'));
|
||||||
|
s.tab('devices', _('Devices & Ports'));
|
||||||
|
s.tab('logging', _('Log'));
|
||||||
|
s.tab('files', _('Files'));
|
||||||
|
s.tab('relay', _('Relay'));
|
||||||
|
|
||||||
|
// Begin general
|
||||||
|
s.taboption('general', form.Flag, 'authoritative',
|
||||||
|
_('Authoritative'),
|
||||||
|
_('This is the only DHCP server in the local network.'));
|
||||||
|
|
||||||
|
s.taboption('general', form.Value, 'domain',
|
||||||
|
_('Local domain'),
|
||||||
|
_('Local domain suffix appended to DHCP names and hosts file entries.'));
|
||||||
|
|
||||||
|
o = s.taboption('general', form.Flag, 'sequential_ip',
|
||||||
|
_('Allocate IPs sequentially'),
|
||||||
|
_('Allocate IP addresses sequentially, starting from the lowest available address.'));
|
||||||
|
o.optional = true;
|
||||||
|
|
||||||
|
o = s.taboption('general', form.Value, 'dhcpleasemax',
|
||||||
|
_('Max. DHCP leases'),
|
||||||
|
_('Maximum allowed number of active DHCP leases.'));
|
||||||
|
o.optional = true;
|
||||||
|
o.datatype = 'uinteger';
|
||||||
|
o.placeholder = 150;
|
||||||
|
// End general
|
||||||
|
|
||||||
|
// Begin devices
|
||||||
|
o = s.taboption('devices', form.Flag, 'nonwildcard',
|
||||||
|
_('Non-wildcard'),
|
||||||
|
_('Bind only to configured interface addresses, instead of the wildcard address.'));
|
||||||
|
o.default = o.enabled;
|
||||||
|
o.optional = false;
|
||||||
|
o.rmempty = true;
|
||||||
|
|
||||||
|
o = s.taboption('devices', widgets.NetworkSelect, 'interface',
|
||||||
|
_('Listen interfaces'),
|
||||||
|
_('Listen only on the specified interfaces, and loopback if not excluded explicitly.'));
|
||||||
|
o.multiple = true;
|
||||||
|
o.nocreate = true;
|
||||||
|
|
||||||
|
o = s.taboption('devices', widgets.NetworkSelect, 'notinterface',
|
||||||
|
_('Exclude interfaces'),
|
||||||
|
_('Do not listen on the specified interfaces.'));
|
||||||
|
o.loopback = true;
|
||||||
|
o.multiple = true;
|
||||||
|
o.nocreate = true;
|
||||||
|
// End devices
|
||||||
|
|
||||||
|
// Begin logging
|
||||||
|
o = s.taboption('logging', form.Flag, 'logdhcp',
|
||||||
|
_('Extra DHCP logging'),
|
||||||
|
_('Log all options sent to DHCP clients and the tags used to determine them.'));
|
||||||
|
o.optional = true;
|
||||||
|
|
||||||
|
o = s.taboption('logging', form.Value, 'logfacility',
|
||||||
|
_('Log facility'),
|
||||||
|
_('Set log class/facility for syslog entries.'));
|
||||||
|
o.optional = true;
|
||||||
|
o.value('KERN');
|
||||||
|
o.value('USER');
|
||||||
|
o.value('MAIL');
|
||||||
|
o.value('DAEMON');
|
||||||
|
o.value('AUTH');
|
||||||
|
o.value('LPR');
|
||||||
|
o.value('NEWS');
|
||||||
|
o.value('UUCP');
|
||||||
|
o.value('CRON');
|
||||||
|
o.value('LOCAL0');
|
||||||
|
o.value('LOCAL1');
|
||||||
|
o.value('LOCAL2');
|
||||||
|
o.value('LOCAL3');
|
||||||
|
o.value('LOCAL4');
|
||||||
|
o.value('LOCAL5');
|
||||||
|
o.value('LOCAL6');
|
||||||
|
o.value('LOCAL7');
|
||||||
|
o.value('-', _('stderr'));
|
||||||
|
|
||||||
|
o = s.taboption('logging', form.Flag, 'quietdhcp',
|
||||||
|
_('Suppress logging'),
|
||||||
|
_('Suppress logging of the routine operation for the DHCP protocol.'));
|
||||||
|
o.optional = true;
|
||||||
|
o.depends('logdhcp', '0');
|
||||||
|
// End logging
|
||||||
|
|
||||||
|
// Begin files
|
||||||
|
s.taboption('files', form.Flag, 'readethers',
|
||||||
|
_('Use %s').format('<code>/etc/ethers</code>'),
|
||||||
|
_('Read %s to configure the DHCP server.').format('<code>/etc/ethers</code>'));
|
||||||
|
|
||||||
|
s.taboption('files', form.Value, 'leasefile',
|
||||||
|
_('Lease file'),
|
||||||
|
_('File to store DHCP lease information.'));
|
||||||
|
// End files
|
||||||
|
|
||||||
|
// Begin relay
|
||||||
|
o = s.taboption('relay', form.SectionValue, '__relays__', form.TableSection, 'relay', null,
|
||||||
|
_('Relay DHCP requests elsewhere. OK: v4↔v4, v6↔v6. Not OK: v4↔v6, v6↔v4.')
|
||||||
|
+ '<br />' + _('Note: you may also need a DHCP Proxy (currently unavailable) when specifying a non-standard Relay To port(<code>addr#port</code>).')
|
||||||
|
+ '<br />' + _('You may add multiple unique Relay To on the same Listen addr.'));
|
||||||
|
|
||||||
|
ss = o.subsection;
|
||||||
|
|
||||||
|
ss.addremove = true;
|
||||||
|
ss.anonymous = true;
|
||||||
|
ss.sortable = true;
|
||||||
|
ss.rowcolors = true;
|
||||||
|
ss.nodescriptions = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Value, 'local_addr', _('Relay from'));
|
||||||
|
so.rmempty = false;
|
||||||
|
so.datatype = 'ipaddr';
|
||||||
|
|
||||||
|
for (var family = 4; family <= 6; family += 2) {
|
||||||
|
for (var i = 0; i < networks.length; i++) {
|
||||||
|
if (networks[i].getName() != 'loopback') {
|
||||||
|
var addrs = (family == 6) ? networks[i].getIP6Addrs() : networks[i].getIPAddrs();
|
||||||
|
for (var j = 0; j < addrs.length; j++) {
|
||||||
|
var addr = addrs[j].split('/')[0];
|
||||||
|
so.value(addr, E([], [
|
||||||
|
addr, ' (',
|
||||||
|
widgets.NetworkSelect.prototype.renderIfaceBadge(networks[i]),
|
||||||
|
')'
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
so = ss.option(form.Value, 'server_addr', _('Relay to address'));
|
||||||
|
so.rmempty = false;
|
||||||
|
so.optional = false;
|
||||||
|
so.placeholder = '192.168.10.1#535';
|
||||||
|
so.validate = function(section, value) {
|
||||||
|
var m = this.section.formvalue(section, 'local_addr'),
|
||||||
|
n = this.section.formvalue(section, 'server_addr'),
|
||||||
|
p;
|
||||||
|
|
||||||
|
if (!m || !n) {
|
||||||
|
return _('Both "Relay from" and "Relay to address" must be specified.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = n.split('#');
|
||||||
|
if (p.length > 1 && !/^[0-9]+$/.test(p[1]))
|
||||||
|
return _('Expected port number.');
|
||||||
|
else
|
||||||
|
n = p[0];
|
||||||
|
|
||||||
|
if ((validation.parseIPv6(m) && validation.parseIPv6(n)) ||
|
||||||
|
validation.parseIPv4(m) && validation.parseIPv4(n))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return _('Address families of "Relay from" and "Relay to address" must match.')
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
so = ss.option(widgets.NetworkSelect, 'interface', _('Only accept replies via'));
|
||||||
|
so.optional = true;
|
||||||
|
so.rmempty = false;
|
||||||
|
so.placeholder = 'lan';
|
||||||
|
// End relay
|
||||||
|
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user