Allow to disable DNS server announcement per subnet
Currently there is no way to have DHCP agents not announce DNS servers for a subnet. The current behaviour when the dns_nameservers option is set to '0.0.0.0' is that each agent will only announce itself instead of announcing the list of all dhcp agents for that subnet, which seems not too useful. So we redefine the meaning of this option to instruct the DHCP agent to not announce any DNS server in that case. Actually, going back to square one, it would be more natural to swap the meaning of "option unset" and "option 0.0.0.0", but that would change the default behaviour for all existing installation and thus does not seem feasible. Change-Id: I32d943360162c483ac1364100a21ab56b13517fb Closes-Bug: 1311040
This commit is contained in:
parent
f311b42d28
commit
584b7561c1
@ -882,12 +882,22 @@ class Dnsmasq(DhcpLocalProcess):
|
|||||||
addr_mode == constants.IPV6_SLAAC)):
|
addr_mode == constants.IPV6_SLAAC)):
|
||||||
continue
|
continue
|
||||||
if subnet.dns_nameservers:
|
if subnet.dns_nameservers:
|
||||||
options.append(
|
if ((subnet.ip_version == 4 and
|
||||||
self._format_option(
|
subnet.dns_nameservers == ['0.0.0.0']) or
|
||||||
subnet.ip_version, i, 'dns-server',
|
(subnet.ip_version == 6 and
|
||||||
','.join(
|
subnet.dns_nameservers == ['::'])):
|
||||||
Dnsmasq._convert_to_literal_addrs(
|
# Special case: Do not announce DNS servers
|
||||||
subnet.ip_version, subnet.dns_nameservers))))
|
options.append(
|
||||||
|
self._format_option(
|
||||||
|
subnet.ip_version, i, 'dns-server'))
|
||||||
|
else:
|
||||||
|
options.append(
|
||||||
|
self._format_option(
|
||||||
|
subnet.ip_version, i, 'dns-server',
|
||||||
|
','.join(
|
||||||
|
Dnsmasq._convert_to_literal_addrs(
|
||||||
|
subnet.ip_version,
|
||||||
|
subnet.dns_nameservers))))
|
||||||
else:
|
else:
|
||||||
# use the dnsmasq ip as nameservers only if there is no
|
# use the dnsmasq ip as nameservers only if there is no
|
||||||
# dns-server submitted by the server
|
# dns-server submitted by the server
|
||||||
|
@ -442,6 +442,13 @@ class FakeV4SubnetAgentWithManyDnsProvided(FakeV4Subnet):
|
|||||||
self.host_routes = []
|
self.host_routes = []
|
||||||
|
|
||||||
|
|
||||||
|
class FakeV4SubnetAgentWithNoDnsProvided(FakeV4Subnet):
|
||||||
|
def __init__(self):
|
||||||
|
super(FakeV4SubnetAgentWithNoDnsProvided, self).__init__()
|
||||||
|
self.dns_nameservers = ['0.0.0.0']
|
||||||
|
self.host_routes = []
|
||||||
|
|
||||||
|
|
||||||
class FakeV4MultipleAgentsWithoutDnsProvided(object):
|
class FakeV4MultipleAgentsWithoutDnsProvided(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
self.id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||||
@ -469,6 +476,15 @@ class FakeV4AgentWithManyDnsProvided(object):
|
|||||||
self.namespace = 'qdhcp-ns'
|
self.namespace = 'qdhcp-ns'
|
||||||
|
|
||||||
|
|
||||||
|
class FakeV4AgentWithNoDnsProvided(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||||
|
self.subnets = [FakeV4SubnetAgentWithNoDnsProvided()]
|
||||||
|
self.ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort(),
|
||||||
|
FakePortMultipleAgents1()]
|
||||||
|
self.namespace = 'qdhcp-ns'
|
||||||
|
|
||||||
|
|
||||||
class FakeV4SubnetMultipleAgentsWithDnsProvided(FakeV4Subnet):
|
class FakeV4SubnetMultipleAgentsWithDnsProvided(FakeV4Subnet):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(FakeV4SubnetMultipleAgentsWithDnsProvided, self).__init__()
|
super(FakeV4SubnetMultipleAgentsWithDnsProvided, self).__init__()
|
||||||
@ -546,6 +562,19 @@ class FakeV6SubnetStateless(object):
|
|||||||
self.ipv6_ra_mode = None
|
self.ipv6_ra_mode = None
|
||||||
|
|
||||||
|
|
||||||
|
class FakeV6SubnetStatelessNoDnsProvided(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
|
||||||
|
self.ip_version = 6
|
||||||
|
self.cidr = 'ffea:3ba5:a17a:4ba3::/64'
|
||||||
|
self.gateway_ip = 'ffea:3ba5:a17a:4ba3::1'
|
||||||
|
self.enable_dhcp = True
|
||||||
|
self.dns_nameservers = ['::']
|
||||||
|
self.host_routes = []
|
||||||
|
self.ipv6_address_mode = constants.DHCPV6_STATELESS
|
||||||
|
self.ipv6_ra_mode = None
|
||||||
|
|
||||||
|
|
||||||
class FakeV6SubnetStatelessBadPrefixLength(object):
|
class FakeV6SubnetStatelessBadPrefixLength(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
|
self.id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
|
||||||
@ -898,6 +927,14 @@ class FakeV6NetworkStatelessDHCP(object):
|
|||||||
self.namespace = 'qdhcp-ns'
|
self.namespace = 'qdhcp-ns'
|
||||||
|
|
||||||
|
|
||||||
|
class FakeV6NetworkStatelessDHCPNoDnsProvided(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'
|
||||||
|
self.subnets = [FakeV6SubnetStatelessNoDnsProvided()]
|
||||||
|
self.ports = [FakeV6Port()]
|
||||||
|
self.namespace = 'qdhcp-ns'
|
||||||
|
|
||||||
|
|
||||||
class FakeV6NetworkStatelessDHCPBadPrefixLength(object):
|
class FakeV6NetworkStatelessDHCPBadPrefixLength(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'
|
self.id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'
|
||||||
@ -1429,6 +1466,18 @@ class TestDnsmasq(TestBase):
|
|||||||
self._test_output_opts_file(expected,
|
self._test_output_opts_file(expected,
|
||||||
FakeV4AgentWithManyDnsProvided())
|
FakeV4AgentWithManyDnsProvided())
|
||||||
|
|
||||||
|
def test_output_opts_file_agent_with_no_dns_provided(self):
|
||||||
|
expected = ('tag:tag0,'
|
||||||
|
'option:dns-server\n'
|
||||||
|
'tag:tag0,option:classless-static-route,'
|
||||||
|
'169.254.169.254/32,192.168.0.1,0.0.0.0/0,192.168.0.1\n'
|
||||||
|
'tag:tag0,249,169.254.169.254/32,192.168.0.1,0.0.0.0/0,'
|
||||||
|
'192.168.0.1\n'
|
||||||
|
'tag:tag0,option:router,192.168.0.1').lstrip()
|
||||||
|
|
||||||
|
self._test_output_opts_file(expected,
|
||||||
|
FakeV4AgentWithNoDnsProvided())
|
||||||
|
|
||||||
def test_output_opts_file_multiple_agents_with_dns_provided(self):
|
def test_output_opts_file_multiple_agents_with_dns_provided(self):
|
||||||
expected = ('tag:tag0,option:dns-server,8.8.8.8\n'
|
expected = ('tag:tag0,option:dns-server,8.8.8.8\n'
|
||||||
'tag:tag0,option:classless-static-route,'
|
'tag:tag0,option:classless-static-route,'
|
||||||
@ -2239,6 +2288,18 @@ class TestDnsmasq(TestBase):
|
|||||||
self.safe.assert_has_calls([mock.call(exp_host_name, exp_host_data),
|
self.safe.assert_has_calls([mock.call(exp_host_name, exp_host_data),
|
||||||
mock.call(exp_opt_name, exp_opt_data)])
|
mock.call(exp_opt_name, exp_opt_data)])
|
||||||
|
|
||||||
|
def test_host_and_opts_file_on_stateless_dhcpv6_network_no_dns(self):
|
||||||
|
exp_host_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/host'
|
||||||
|
exp_opt_name = '/dhcp/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb/opts'
|
||||||
|
exp_opt_data = ('tag:tag0,option6:dns-server\n'
|
||||||
|
'tag:tag0,'
|
||||||
|
'option6:domain-search,openstacklocal').lstrip()
|
||||||
|
dm = self._get_dnsmasq(FakeV6NetworkStatelessDHCPNoDnsProvided())
|
||||||
|
dm._output_hosts_file()
|
||||||
|
dm._output_opts_file()
|
||||||
|
self.safe.assert_has_calls([mock.call(exp_host_name, ''),
|
||||||
|
mock.call(exp_opt_name, exp_opt_data)])
|
||||||
|
|
||||||
def test_host_file_on_net_with_v6_slaac_and_v4(self):
|
def test_host_file_on_net_with_v6_slaac_and_v4(self):
|
||||||
exp_host_name = '/dhcp/eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee/host'
|
exp_host_name = '/dhcp/eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee/host'
|
||||||
exp_host_data = (
|
exp_host_data = (
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
prelude: >
|
||||||
|
DNS server assignment can now be disabled in replies sent from the DHCP agent.
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
It is now possible to instruct the DHCP agent not to supply any DNS server
|
||||||
|
address to their clients by setting the ``dns_nameservers`` attribute for
|
||||||
|
the corresponding subnet to ``0.0.0.0`` or ``::``, for IPv4 or IPv6 subnets
|
||||||
|
(respectively).
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
The functionality when a subnet has its DNS server set to ``0.0.0.0`` or
|
||||||
|
``::`` has been changed with this release. The old behaviour was that each
|
||||||
|
DHCP agent would supply only its own IP address as the DNS server to its
|
||||||
|
clients. The new behaviour is that the DHCP agent will not supply any DNS
|
||||||
|
server IP address at all.
|
Loading…
Reference in New Issue
Block a user