Dnsmasq uses all agent IPs as nameservers
Add dhcp option which provides all agent IPs which will be used as nameserver entries when neutron uses multiple dhcp agent per network and when there is no dns nameserver provided by the neutron server. Change-Id: I639a844bba212a731616851ff479a5e735612cf8 Closes-bug: #1259482
This commit is contained in:
parent
b347f851df
commit
7e5e2ad4df
@ -16,6 +16,7 @@
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
@ -442,6 +443,9 @@ class Dnsmasq(DhcpLocalProcess):
|
||||
subnet_to_interface_ip = self._make_subnet_interface_ip_map()
|
||||
|
||||
options = []
|
||||
|
||||
dhcp_ips = collections.defaultdict(list)
|
||||
subnet_idx_map = {}
|
||||
for i, subnet in enumerate(self.network.subnets):
|
||||
if not subnet.enable_dhcp:
|
||||
continue
|
||||
@ -449,6 +453,10 @@ class Dnsmasq(DhcpLocalProcess):
|
||||
options.append(
|
||||
self._format_option(i, 'dns-server',
|
||||
','.join(subnet.dns_nameservers)))
|
||||
else:
|
||||
# use the dnsmasq ip as nameservers only if there is no
|
||||
# dns-server submitted by the server
|
||||
subnet_idx_map[subnet.id] = i
|
||||
|
||||
gateway = subnet.gateway_ip
|
||||
host_routes = []
|
||||
@ -486,6 +494,22 @@ class Dnsmasq(DhcpLocalProcess):
|
||||
self._format_option(port.id, opt.opt_name, opt.opt_value)
|
||||
for opt in port.extra_dhcp_opts)
|
||||
|
||||
# provides all dnsmasq ip as dns-server if there is more than
|
||||
# one dnsmasq for a subnet and there is no dns-server submitted
|
||||
# by the server
|
||||
if port.device_owner == 'network:dhcp':
|
||||
for ip in port.fixed_ips:
|
||||
i = subnet_idx_map.get(ip.subnet_id)
|
||||
if i is None:
|
||||
continue
|
||||
dhcp_ips[i].append(ip.ip_address)
|
||||
|
||||
for i, ips in dhcp_ips.items():
|
||||
if len(ips) > 1:
|
||||
options.append(self._format_option(i,
|
||||
'dns-server',
|
||||
','.join(ips)))
|
||||
|
||||
name = self.get_conf_file_name('opts')
|
||||
utils.replace_file(name, '\n'.join(options))
|
||||
return name
|
||||
|
@ -89,6 +89,30 @@ class FakeRouterPort:
|
||||
self.extra_dhcp_opts = []
|
||||
|
||||
|
||||
class FakePortMultipleAgents1:
|
||||
id = 'rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr'
|
||||
admin_state_up = True
|
||||
device_owner = 'network:dhcp'
|
||||
fixed_ips = [FakeIPAllocation('192.168.0.5',
|
||||
'dddddddd-dddd-dddd-dddd-dddddddddddd')]
|
||||
mac_address = '00:00:0f:dd:dd:dd'
|
||||
|
||||
def __init__(self):
|
||||
self.extra_dhcp_opts = []
|
||||
|
||||
|
||||
class FakePortMultipleAgents2:
|
||||
id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
||||
admin_state_up = True
|
||||
device_owner = 'network:dhcp'
|
||||
fixed_ips = [FakeIPAllocation('192.168.0.6',
|
||||
'dddddddd-dddd-dddd-dddd-dddddddddddd')]
|
||||
mac_address = '00:00:0f:ee:ee:ee'
|
||||
|
||||
def __init__(self):
|
||||
self.extra_dhcp_opts = []
|
||||
|
||||
|
||||
class FakeV4HostRoute:
|
||||
destination = '20.0.0.1/24'
|
||||
nexthop = '20.0.0.1'
|
||||
@ -124,6 +148,42 @@ class FakeV4SubnetGatewayRoute:
|
||||
dns_nameservers = ['8.8.8.8']
|
||||
|
||||
|
||||
class FakeV4SubnetMultipleAgentsWithoutDnsProvided:
|
||||
id = 'dddddddd-dddd-dddd-dddd-dddddddddddd'
|
||||
ip_version = 4
|
||||
cidr = '192.168.0.0/24'
|
||||
gateway_ip = '192.168.0.1'
|
||||
enable_dhcp = True
|
||||
dns_nameservers = []
|
||||
host_routes = []
|
||||
|
||||
|
||||
class FakeV4MultipleAgentsWithoutDnsProvided:
|
||||
id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||
subnets = [FakeV4SubnetMultipleAgentsWithoutDnsProvided()]
|
||||
ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort(),
|
||||
FakePortMultipleAgents1(), FakePortMultipleAgents2()]
|
||||
namespace = 'qdhcp-ns'
|
||||
|
||||
|
||||
class FakeV4SubnetMultipleAgentsWithDnsProvided:
|
||||
id = 'dddddddd-dddd-dddd-dddd-dddddddddddd'
|
||||
ip_version = 4
|
||||
cidr = '192.168.0.0/24'
|
||||
gateway_ip = '192.168.0.1'
|
||||
enable_dhcp = True
|
||||
dns_nameservers = ['8.8.8.8']
|
||||
host_routes = []
|
||||
|
||||
|
||||
class FakeV4MultipleAgentsWithDnsProvided:
|
||||
id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||
subnets = [FakeV4SubnetMultipleAgentsWithDnsProvided()]
|
||||
ports = [FakePort1(), FakePort2(), FakePort3(), FakeRouterPort(),
|
||||
FakePortMultipleAgents1(), FakePortMultipleAgents2()]
|
||||
namespace = 'qdhcp-ns'
|
||||
|
||||
|
||||
class FakeV6Subnet:
|
||||
id = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||
ip_version = 6
|
||||
@ -716,6 +776,30 @@ tag:tag1,249,%s,%s""".lstrip() % (fake_v6,
|
||||
|
||||
self.safe.assert_called_once_with('/foo/opts', expected)
|
||||
|
||||
def test_output_opts_file_multiple_agents_without_dns_provided(self):
|
||||
expected = """
|
||||
tag:tag0,option:router,192.168.0.1
|
||||
tag:tag0,option:dns-server,192.168.0.5,192.168.0.6""".lstrip()
|
||||
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
|
||||
conf_fn.return_value = '/foo/opts'
|
||||
dm = dhcp.Dnsmasq(self.conf,
|
||||
FakeV4MultipleAgentsWithoutDnsProvided(),
|
||||
version=float(2.59))
|
||||
dm._output_opts_file()
|
||||
self.safe.assert_called_once_with('/foo/opts', expected)
|
||||
|
||||
def test_output_opts_file_multiple_agents_with_dns_provided(self):
|
||||
expected = """
|
||||
tag:tag0,option:dns-server,8.8.8.8
|
||||
tag:tag0,option:router,192.168.0.1""".lstrip()
|
||||
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
|
||||
conf_fn.return_value = '/foo/opts'
|
||||
dm = dhcp.Dnsmasq(self.conf,
|
||||
FakeV4MultipleAgentsWithDnsProvided(),
|
||||
version=float(2.59))
|
||||
dm._output_opts_file()
|
||||
self.safe.assert_called_once_with('/foo/opts', expected)
|
||||
|
||||
def test_output_opts_file_single_dhcp(self):
|
||||
expected = """
|
||||
tag:tag0,option:dns-server,8.8.8.8
|
||||
|
Loading…
x
Reference in New Issue
Block a user