Allow per-subnet DNSNameServers for ctlplane network

Add a new option ``dns_nameservers`` in the subnet sections
for the undercloud ctlplane network. By default the option
is not set, and in that case the ``undercloud_nameservers``
are used, maintaining the current behaviour.

This decouples the nameservers used on the undercloud and
the ones used for the overcloud nodes. In a DCN setting
different DNS server may be preferred per-site.

Related-Bug: #1834306
Change-Id: I0dc03eddf9ea00ff33cd3ae0cdc8f42a4961e89c
This commit is contained in:
Harald Jensås 2019-06-25 14:41:02 +02:00
parent 6627c4c2e0
commit ee16c09447
6 changed files with 89 additions and 16 deletions

View File

@ -51,6 +51,10 @@ HOST_ROUTES_HELP_STR = _(
'Host routes for the Neutron-managed subnet for the Overcloud instances '
'on this network. The host routes on the local_subnet will also be '
'configured on the undercloud.')
DNS_NAMESERVERS_HELP_STR = _(
'DNS nameservers for the Neutron-managed subnet for the Overcloud '
'instances on this network. If no nameservers are defined for the subnet, '
'the nameservers defined for undercloud_nameservers will be used.')
# Deprecated options
_deprecated_opt_network_gateway = [cfg.DeprecatedOpt(
@ -385,6 +389,9 @@ class UndercloudConfig(StandaloneConfig):
sample_default=('[{destination: 10.10.10.0/24, '
'nexthop: 192.168.24.1}]'),
help=HOST_ROUTES_HELP_STR),
cfg.ListOpt('dns_nameservers',
default=constants.CTLPLANE_DNS_NAMESERVERS_DEFAULT,
help=DNS_NAMESERVERS_HELP_STR),
]
return self.sort_opts(_subnets_opts)
@ -413,6 +420,9 @@ class UndercloudConfig(StandaloneConfig):
bounds=True,
default=[],
help=HOST_ROUTES_HELP_STR),
cfg.ListOpt('dns_nameservers',
default=constants.CTLPLANE_DNS_NAMESERVERS_DEFAULT,
help=DNS_NAMESERVERS_HELP_STR),
]
return self.sort_opts(_subnets_opts)

View File

@ -100,6 +100,7 @@ CTLPLANE_DHCP_START_DEFAULT = ['192.168.24.5']
CTLPLANE_DHCP_END_DEFAULT = ['192.168.24.24']
CTLPLANE_INSPECTION_IPRANGE_DEFAULT = '192.168.24.100,192.168.24.120'
CTLPLANE_GATEWAY_DEFAULT = '192.168.24.1'
CTLPLANE_DNS_NAMESERVERS_DEFAULT = []
# Ansible parameters used for the actions being
# executed during tripleo deploy/upgrade.

View File

@ -148,6 +148,7 @@ class TestUndercloudConfig(base.TestCase):
'dhcp_end',
'dhcp_exclude',
'dhcp_start',
'dns_nameservers',
'gateway',
'host_routes',
'inspection_iprange',

View File

@ -131,7 +131,8 @@ class TestNetworkSettings(base.TestCase):
fixtures.MockPatch('tripleoclient.utils.load_config'))
self.conf.config(local_ip='192.168.24.1/24',
undercloud_admin_host='192.168.24.3',
undercloud_public_host='192.168.24.2')
undercloud_public_host='192.168.24.2',
undercloud_nameservers=['10.10.10.10', '10.10.10.11'])
# ctlplane network - config group options
self.grp0 = cfg.OptGroup(name='ctlplane-subnet',
title='ctlplane-subnet')
@ -144,7 +145,8 @@ class TestNetworkSettings(base.TestCase):
cfg.BoolOpt('masquerade'),
cfg.ListOpt('host_routes',
item_type=cfg.types.Dict(bounds=True),
bounds=True,)]
bounds=True,),
cfg.ListOpt('dns_nameservers')]
self.conf.register_opts(self.opts, group=self.grp0)
self.grp1 = cfg.OptGroup(name='subnet1', title='subnet1')
self.grp2 = cfg.OptGroup(name='subnet2', title='subnet2')
@ -156,14 +158,15 @@ class TestNetworkSettings(base.TestCase):
gateway='192.168.24.1',
masquerade=False,
host_routes=[],
dns_nameservers=[],
group='ctlplane-subnet')
def test_default(self):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -175,6 +178,7 @@ class TestNetworkSettings(base.TestCase):
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}}
@ -189,6 +193,8 @@ class TestNetworkSettings(base.TestCase):
dhcp_start='fd12:3456:789a:1::10',
dhcp_end='fd12:3456:789a:1::20',
dhcp_exclude=[],
dns_nameservers=['fd12:3456:789a:1::5',
'fd12:3456:789a:1::6'],
inspection_iprange=('fd12:3456:789a:1::30,'
'fd12:3456:789a:1::40'),
gateway='fd12:3456:789a:1::1',
@ -203,7 +209,7 @@ class TestNetworkSettings(base.TestCase):
'RedisIPv6': True,
'MysqlIPv6': True,
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'DnsServers': '10.10.10.10,10.10.10.11',
'IronicInspectorSubnets': [
{'gateway': 'fd12:3456:789a:1::1',
'host_routes': [],
@ -216,6 +222,8 @@ class TestNetworkSettings(base.TestCase):
'AllocationPools': [
{'start': 'fd12:3456:789a:1::10',
'end': 'fd12:3456:789a:1::20'}],
'DnsNameServers': ['fd12:3456:789a:1::5',
'fd12:3456:789a:1::6'],
'HostRoutes': [],
'NetworkCidr': 'fd12:3456:789a:1::/64',
'NetworkGateway': 'fd12:3456:789a:1::1'}}}
@ -237,8 +245,8 @@ class TestNetworkSettings(base.TestCase):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -251,6 +259,7 @@ class TestNetworkSettings(base.TestCase):
'AllocationPools': [
{'start': '192.168.24.4', 'end': '192.168.24.99'},
{'start': '192.168.24.121', 'end': '192.168.24.254'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}}
@ -264,8 +273,8 @@ class TestNetworkSettings(base.TestCase):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.10.1',
'host_routes': [],
@ -278,6 +287,7 @@ class TestNetworkSettings(base.TestCase):
'AllocationPools': [
{'start': '192.168.10.2', 'end': '192.168.10.99'},
{'start': '192.168.10.121', 'end': '192.168.10.254'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.1'}}}
@ -293,8 +303,8 @@ class TestNetworkSettings(base.TestCase):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.10.1',
'host_routes': [],
@ -309,6 +319,7 @@ class TestNetworkSettings(base.TestCase):
{'start': '192.168.10.51', 'end': '192.168.10.79'},
{'start': '192.168.10.90', 'end': '192.168.10.99'},
{'start': '192.168.10.121', 'end': '192.168.10.254'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.1'}}}
@ -321,8 +332,8 @@ class TestNetworkSettings(base.TestCase):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -335,6 +346,7 @@ class TestNetworkSettings(base.TestCase):
'AllocationPools': [
{'start': '192.168.24.4', 'end': '192.168.24.99'},
{'start': '192.168.24.121', 'end': '192.168.24.254'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}}
@ -347,8 +359,8 @@ class TestNetworkSettings(base.TestCase):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -361,6 +373,7 @@ class TestNetworkSettings(base.TestCase):
'AllocationPools': [
{'start': '192.168.24.10', 'end': '192.168.24.99'},
{'start': '192.168.24.121', 'end': '192.168.24.254'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}
@ -374,8 +387,8 @@ class TestNetworkSettings(base.TestCase):
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -388,6 +401,7 @@ class TestNetworkSettings(base.TestCase):
'AllocationPools': [
{'start': '192.168.24.4', 'end': '192.168.24.99'},
{'start': '192.168.24.121', 'end': '192.168.24.220'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}
@ -399,6 +413,7 @@ class TestNetworkSettings(base.TestCase):
self.conf.register_opts(self.opts, group=self.grp1)
self.conf.register_opts(self.opts, group=self.grp2)
self.conf.config(masquerade=True,
dns_nameservers=['10.1.1.100', '10.1.1.101'],
group='ctlplane-subnet')
self.conf.config(cidr='192.168.10.0/24',
dhcp_start='192.168.10.10',
@ -406,6 +421,7 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.10.100,192.168.10.189',
gateway='192.168.10.254',
dns_nameservers=['10.2.2.100', '10.2.2.101'],
host_routes=[],
masquerade=True,
group='subnet1')
@ -415,16 +431,17 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.20.100,192.168.20.189',
gateway='192.168.20.254',
dns_nameservers=['10.3.3.100', '10.3.3.101'],
host_routes=[],
masquerade=True,
group='subnet2')
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'},
{'ip_netmask': '192.168.20.0/24', 'next_hop': '192.168.24.1'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -457,18 +474,21 @@ class TestNetworkSettings(base.TestCase):
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DnsNameServers': ['10.1.1.100', '10.1.1.101'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
'DnsNameServers': ['10.2.2.100', '10.2.2.101'],
'HostRoutes': [],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.254'},
'subnet2': {
'AllocationPools': [
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
'DnsNameServers': ['10.3.3.100', '10.3.3.101'],
'HostRoutes': [],
'NetworkCidr': '192.168.20.0/24',
'NetworkGateway': '192.168.20.254'}
@ -486,6 +506,7 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.10.100,192.168.10.189',
gateway='192.168.10.254',
dns_nameservers=[],
host_routes=[],
group='subnet1')
self.conf.config(cidr='192.168.20.0/24',
@ -494,15 +515,16 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.20.100,192.168.20.189',
gateway='192.168.20.254',
dns_nameservers=[],
host_routes=[],
group='subnet2')
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'},
{'ip_netmask': '192.168.20.0/24', 'next_hop': '192.168.24.1'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -526,18 +548,21 @@ class TestNetworkSettings(base.TestCase):
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.254'},
'subnet2': {
'AllocationPools': [
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.20.0/24',
'NetworkGateway': '192.168.20.254'}
@ -552,15 +577,16 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.10.200,192.168.10.254',
gateway='192.168.10.254',
dns_nameservers=[],
host_routes=[],
masquerade=False,
group='subnet1')
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -579,12 +605,14 @@ class TestNetworkSettings(base.TestCase):
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.1', 'end': '192.168.10.199'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.254'}
@ -599,15 +627,16 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.10.100,192.168.10.199',
gateway='192.168.10.222',
dns_nameservers=[],
host_routes=[],
masquerade=False,
group='subnet1')
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [],
@ -626,6 +655,7 @@ class TestNetworkSettings(base.TestCase):
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
@ -634,6 +664,7 @@ class TestNetworkSettings(base.TestCase):
{'start': '192.168.10.1', 'end': '192.168.10.99'},
{'start': '192.168.10.200', 'end': '192.168.10.221'},
{'start': '192.168.10.223', 'end': '192.168.10.254'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.222'}
@ -654,6 +685,7 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.10.100,192.168.10.189',
gateway='192.168.10.254',
dns_nameservers=[],
host_routes=[{'destination': '10.10.10.254/32',
'nexthop': '192.168.10.254'}],
group='subnet1')
@ -663,17 +695,18 @@ class TestNetworkSettings(base.TestCase):
dhcp_exclude=[],
inspection_iprange='192.168.20.100,192.168.20.189',
gateway='192.168.20.254',
dns_nameservers=[],
host_routes=[{'destination': '10.10.10.254/32',
'nexthop': '192.168.20.254'}],
group='subnet2')
env = {}
undercloud_config._process_network_args(env)
expected = {
'DnsServers': '10.10.10.10,10.10.10.11',
'ControlPlaneStaticRoutes': [
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'},
{'ip_netmask': '192.168.20.0/24', 'next_hop': '192.168.24.1'},
{'ip_netmask': '10.10.10.254/32', 'next_hop': '192.168.24.1'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'host_routes': [{'destination': '10.10.10.254/32',
@ -700,6 +733,7 @@ class TestNetworkSettings(base.TestCase):
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [{'destination': '10.10.10.254/32',
'nexthop': '192.168.24.1'}],
'NetworkCidr': '192.168.24.0/24',
@ -707,6 +741,7 @@ class TestNetworkSettings(base.TestCase):
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [{'destination': '10.10.10.254/32',
'nexthop': '192.168.10.254'}],
'NetworkCidr': '192.168.10.0/24',
@ -714,6 +749,7 @@ class TestNetworkSettings(base.TestCase):
'subnet2': {
'AllocationPools': [
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
'HostRoutes': [{'destination': '10.10.10.254/32',
'nexthop': '192.168.20.254'}],
'NetworkCidr': '192.168.20.0/24',

View File

@ -78,7 +78,7 @@ PARAMETER_MAPPING = {
SUBNET_PARAMETER_MAPPING = {
'cidr': 'NetworkCidr',
'gateway': 'NetworkGateway',
'host_routes': 'HostRoutes'
'host_routes': 'HostRoutes',
}
THT_HOME = os.environ.get('THT_HOME',
@ -310,6 +310,9 @@ def _calculate_allocation_pools(subnet):
CONF.undercloud_admin_host)))
ip_set.remove(netaddr.IPNetwork(utils.get_single_ip(
CONF.undercloud_public_host)))
# Remove dns nameservers
for addr in subnet.get('dns_nameservers', []):
ip_set.remove(netaddr.IPAddress(addr))
# Remove addresses in the inspection_iprange
inspect_start, inspect_end = subnet.get('inspection_iprange').split(',')
ip_set.remove(netaddr.IPRange(inspect_start, inspect_end))
@ -337,6 +340,12 @@ def _process_network_args(env):
env['UndercloudCtlplaneSubnets'][subnet] = {
'AllocationPools': _calculate_allocation_pools(s)
}
if s.get('dns_nameservers'):
env['UndercloudCtlplaneSubnets'][subnet].update(
{'DnsNameServers': s['dns_nameservers']})
else:
env['UndercloudCtlplaneSubnets'][subnet].update(
{'DnsNameServers': CONF['undercloud_nameservers']})
for param_key, param_value in SUBNET_PARAMETER_MAPPING.items():
if param_value:
env['UndercloudCtlplaneSubnets'][subnet].update(

View File

@ -447,6 +447,21 @@ def _validate_deprecetad_now_invalid_parameters():
del deprecate_conf
def _validate_dnsnameservers(s):
ip_version = netaddr.IPNetwork(s['cidr']).version
if s['dns_nameservers']:
nameservers = s['dns_nameservers']
else:
nameservers = CONF.undercloud_nameservers
for nameserver in nameservers:
if not netaddr.IPAddress(nameserver).version == ip_version:
message = (_('IP version missmatch. Nameserver {0} is not valid '
'for subnet {1}').format(nameserver, s['cidr']))
LOG.error(message)
raise FailedValidation(message)
def check(verbose_level, upgrade=False):
# Fetch configuration and use its log file param to add logging to a file
utils.load_config(CONF, constants.UNDERCLOUD_CONF_PATH)
@ -483,6 +498,7 @@ def check(verbose_level, upgrade=False):
_validate_dhcp_range(s, subnet)
_checking_status('Inspection range for subnet "%s"' % subnet)
_validate_inspection_range(s)
_validate_dnsnameservers(s)
_checking_status('IP addresses')
_validate_ips()
_checking_status('Network interfaces')