Merge "Do not announce any DNS resolver if "0.0.0.0" or "::" provided"
This commit is contained in:
commit
5122b1c077
@ -1153,10 +1153,8 @@ class Dnsmasq(DhcpLocalProcess):
|
||||
addr_mode == constants.IPV6_SLAAC)):
|
||||
continue
|
||||
if subnet.dns_nameservers:
|
||||
if ((subnet.ip_version == 4 and
|
||||
subnet.dns_nameservers == ['0.0.0.0']) or
|
||||
(subnet.ip_version == 6 and
|
||||
subnet.dns_nameservers == ['::'])):
|
||||
if common_utils.is_dns_servers_any_address(
|
||||
subnet.dns_nameservers, subnet.ip_version):
|
||||
# Special case: Do not announce DNS servers
|
||||
options.append(
|
||||
self._format_option(
|
||||
|
@ -37,6 +37,8 @@ from ovsdbapp import constants as ovsdbapp_const
|
||||
from neutron._i18n import _
|
||||
from neutron.common.ovn import constants
|
||||
from neutron.common.ovn import exceptions as ovn_exc
|
||||
from neutron.common import utils as common_utils
|
||||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
|
||||
from neutron.db import models_v2
|
||||
from neutron.objects import ports as ports_obj
|
||||
|
||||
@ -414,6 +416,26 @@ def get_system_dns_resolvers(resolver_file=DNS_RESOLVER_FILE):
|
||||
return resolvers
|
||||
|
||||
|
||||
def get_dhcp_dns_servers(subnet, ip_version=const.IP_VERSION_4):
|
||||
"""Retrieve the DHCP option DNS servers
|
||||
|
||||
The DHCP should not announce any DNS resolver at all on the subnet if any
|
||||
configured DNS server is "0.0.0.0" (IPv4) or "::" (IPv6).
|
||||
https://docs.openstack.org/neutron/latest/admin/config-dns-res.html
|
||||
"""
|
||||
if ip_version == const.IP_VERSION_4:
|
||||
dns_servers = (subnet.get('dns_nameservers') or
|
||||
ovn_conf.get_dns_servers() or
|
||||
get_system_dns_resolvers())
|
||||
else:
|
||||
dns_servers = subnet['dns_nameservers']
|
||||
|
||||
if common_utils.is_dns_servers_any_address(dns_servers, ip_version):
|
||||
return []
|
||||
|
||||
return dns_servers
|
||||
|
||||
|
||||
def get_port_subnet_ids(port):
|
||||
fixed_ips = list(port['fixed_ips'])
|
||||
return [f['subnet_id'] for f in fixed_ips]
|
||||
|
@ -145,6 +145,13 @@ def get_dhcp_agent_device_id(network_id, host):
|
||||
return 'dhcp%s-%s' % (host_uuid, network_id)
|
||||
|
||||
|
||||
def is_dns_servers_any_address(dns_servers, ip_version):
|
||||
"""Checks if DNS server list matches the IP any address '0.0.0.0'/'::'"""
|
||||
ip_any = netaddr.IPNetwork(n_const.IP_ANY[ip_version]).ip
|
||||
return (len(dns_servers) == 1 and
|
||||
netaddr.IPNetwork(dns_servers[0]).ip == ip_any)
|
||||
|
||||
|
||||
class exception_logger(object):
|
||||
"""Wrap a function and log raised exception
|
||||
|
||||
|
@ -1925,9 +1925,7 @@ class OVNClient(object):
|
||||
options['server_mac'] = n_net.get_random_mac(
|
||||
cfg.CONF.base_mac.split(':'))
|
||||
|
||||
dns_servers = (subnet.get('dns_nameservers') or
|
||||
ovn_conf.get_dns_servers() or
|
||||
utils.get_system_dns_resolvers())
|
||||
dns_servers = utils.get_dhcp_dns_servers(subnet)
|
||||
if dns_servers:
|
||||
options['dns_server'] = '{%s}' % ', '.join(dns_servers)
|
||||
else:
|
||||
@ -1966,9 +1964,10 @@ class OVNClient(object):
|
||||
cfg.CONF.base_mac.split(':'))
|
||||
}
|
||||
|
||||
if subnet['dns_nameservers']:
|
||||
dns_servers = '{%s}' % ', '.join(subnet['dns_nameservers'])
|
||||
dhcpv6_opts['dns_server'] = dns_servers
|
||||
dns_servers = utils.get_dhcp_dns_servers(subnet,
|
||||
ip_version=const.IP_VERSION_6)
|
||||
if dns_servers:
|
||||
dhcpv6_opts['dns_server'] = '{%s}' % ', '.join(dns_servers)
|
||||
|
||||
if subnet.get('ipv6_address_mode') == const.DHCPV6_STATELESS:
|
||||
dhcpv6_opts[ovn_const.DHCPV6_STATELESS_OPT] = 'true'
|
||||
|
@ -14,10 +14,13 @@
|
||||
# under the License.
|
||||
|
||||
from collections import namedtuple
|
||||
from os import path
|
||||
from unittest import mock
|
||||
|
||||
import fixtures
|
||||
from neutron_lib.api.definitions import extra_dhcp_opt as edo_ext
|
||||
from neutron_lib import constants as n_const
|
||||
from oslo_config import cfg
|
||||
|
||||
from neutron.common.ovn import constants
|
||||
from neutron.common.ovn import utils
|
||||
@ -33,6 +36,7 @@ nameserver foo 10.0.0.4
|
||||
nameserver aef0::4
|
||||
foo 10.0.0.5
|
||||
"""
|
||||
RESOLV_DNS_SERVERS = ['10.0.0.1', '10.0.0.3']
|
||||
|
||||
|
||||
class TestUtils(base.BaseTestCase):
|
||||
@ -43,7 +47,7 @@ class TestUtils(base.BaseTestCase):
|
||||
tmp_resolv_file = open(resolver_file_name, 'w')
|
||||
tmp_resolv_file.writelines(RESOLV_CONF_TEMPLATE)
|
||||
tmp_resolv_file.close()
|
||||
expected_dns_resolvers = ['10.0.0.1', '10.0.0.3']
|
||||
expected_dns_resolvers = RESOLV_DNS_SERVERS
|
||||
observed_dns_resolvers = utils.get_system_dns_resolvers(
|
||||
resolver_file=resolver_file_name)
|
||||
self.assertEqual(expected_dns_resolvers, observed_dns_resolvers)
|
||||
@ -379,3 +383,53 @@ class TestConnectionConfigToTargetString(base.BaseTestCase):
|
||||
for config, target in config_target:
|
||||
output = utils.connection_config_to_target_string(config)
|
||||
self.assertEqual(target, output)
|
||||
|
||||
|
||||
class TestGetDhcpDnsServers(base.BaseTestCase):
|
||||
|
||||
def test_ipv4(self):
|
||||
# DNS servers from subnet.
|
||||
dns_servers = utils.get_dhcp_dns_servers(
|
||||
{'dns_nameservers': ['1.2.3.4', '5.6.7.8']})
|
||||
self.assertEqual(['1.2.3.4', '5.6.7.8'], dns_servers)
|
||||
|
||||
# DNS servers from config parameter.
|
||||
cfg.CONF.set_override('dns_servers',
|
||||
'1.1.2.2,3.3.4.4', group='ovn')
|
||||
dns_servers = utils.get_dhcp_dns_servers({})
|
||||
self.assertEqual(['1.1.2.2', '3.3.4.4'], dns_servers)
|
||||
|
||||
# DNS servers from local DNS resolver.
|
||||
cfg.CONF.set_override('dns_servers', '', group='ovn')
|
||||
with mock.patch('builtins.open',
|
||||
mock.mock_open(read_data=RESOLV_CONF_TEMPLATE)), \
|
||||
mock.patch.object(path, 'exists', return_value=True):
|
||||
dns_servers = utils.get_dhcp_dns_servers({})
|
||||
self.assertEqual(RESOLV_DNS_SERVERS, dns_servers)
|
||||
|
||||
# No DNS servers if only '0.0.0.0' configured.
|
||||
dns_servers = utils.get_dhcp_dns_servers(
|
||||
{'dns_nameservers': ['0.0.0.0', '5.6.7.8']})
|
||||
self.assertEqual(['0.0.0.0', '5.6.7.8'], dns_servers)
|
||||
dns_servers = utils.get_dhcp_dns_servers(
|
||||
{'dns_nameservers': ['0.0.0.0']})
|
||||
self.assertEqual([], dns_servers)
|
||||
|
||||
def test_ipv6(self):
|
||||
# DNS servers from subnet.
|
||||
dns_servers = utils.get_dhcp_dns_servers(
|
||||
{'dns_nameservers': ['2001:4860:4860::8888',
|
||||
'2001:4860:4860::8844']},
|
||||
ip_version=n_const.IP_VERSION_6)
|
||||
self.assertEqual(['2001:4860:4860::8888',
|
||||
'2001:4860:4860::8844'], dns_servers)
|
||||
|
||||
# No DNS servers if only '::' configured.
|
||||
dns_servers = utils.get_dhcp_dns_servers(
|
||||
{'dns_nameservers': ['2001:4860:4860::8888', '::']},
|
||||
ip_version=n_const.IP_VERSION_6)
|
||||
self.assertEqual(['2001:4860:4860::8888', '::'], dns_servers)
|
||||
dns_servers = utils.get_dhcp_dns_servers(
|
||||
{'dns_nameservers': ['::']},
|
||||
ip_version=n_const.IP_VERSION_6)
|
||||
self.assertEqual([], dns_servers)
|
||||
|
Loading…
Reference in New Issue
Block a user