From 69eec5ce08a4adbeb315dda00dd2990657930506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Jens=C3=A5s?= Date: Wed, 20 Nov 2019 20:13:34 +0100 Subject: [PATCH] Fix inspector ip range for dhcpv6-stateless When using dhcpv6-stateless a range should not be used. According to dnsmasq manual page: A static-only subnet with address all zeros may be used as a "catch-all" address to enable replies to all Information-request packets on a subnet which is provided with stateless DHCPv6, ie --dhcp-range=::,static Closes-Bug: #1853334 Change-Id: I6627da48bc170f7ecccaf84c0fccda9e2edd5af3 --- ...pector-dnsmasq-range-9d0f4635ecce3d2f.yaml | 8 +++ .../tests/v1/undercloud/test_config.py | 53 ++++++++++++++++++- tripleoclient/v1/undercloud_config.py | 13 ++++- 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/fix-dhcpv6-stateless-inspector-dnsmasq-range-9d0f4635ecce3d2f.yaml diff --git a/releasenotes/notes/fix-dhcpv6-stateless-inspector-dnsmasq-range-9d0f4635ecce3d2f.yaml b/releasenotes/notes/fix-dhcpv6-stateless-inspector-dnsmasq-range-9d0f4635ecce3d2f.yaml new file mode 100644 index 000000000..7b3a83a96 --- /dev/null +++ b/releasenotes/notes/fix-dhcpv6-stateless-inspector-dnsmasq-range-9d0f4635ecce3d2f.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixed an issue where the DHCP server for ironic-inspector was configured to + operate in DHCPv6-stateful mode when the undercloud configuration specified + DHCPv6-stateless mode. (See bug: `1853334 + `_) + diff --git a/tripleoclient/tests/v1/undercloud/test_config.py b/tripleoclient/tests/v1/undercloud/test_config.py index 871163b69..624b43792 100644 --- a/tripleoclient/tests/v1/undercloud/test_config.py +++ b/tripleoclient/tests/v1/undercloud/test_config.py @@ -185,7 +185,7 @@ class TestNetworkSettings(base.TestCase): } self.assertEqual(expected, env) - def test_ipv6_control_plane(self): + def test_ipv6_control_plane_stateless_default(self): env = {} self.conf.config(local_ip='fd12:3456:789a:1::2/64', undercloud_admin_host='fd12:3456:789a:1::3', @@ -203,6 +203,55 @@ class TestNetworkSettings(base.TestCase): host_routes=[], group='ctlplane-subnet') undercloud_config._process_network_args(env) + expected = { + 'NovaIPv6': True, + 'RabbitIPv6': True, + 'MemcachedIPv6': True, + 'RedisIPv6': True, + 'MysqlIPv6': True, + 'IronicIpVersion': '6', + 'ControlPlaneStaticRoutes': [], + 'IronicInspectorSubnets': [ + {'gateway': 'fd12:3456:789a:1::1', + 'host_routes': [], + 'ip_range': 'fd12:3456:789a:1::,static', + 'netmask': 'ffff:ffff:ffff:ffff::', + 'tag': 'ctlplane-subnet', + 'mtu': 1500}], + 'MasqueradeNetworks': {}, + 'UndercloudCtlplaneSubnets': { + 'ctlplane-subnet': { + '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'}}, + 'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless', + } + self.assertEqual(expected, env) + + def test_ipv6_control_plane_stateful(self): + env = {} + self.conf.config(local_ip='fd12:3456:789a:1::2/64', + undercloud_admin_host='fd12:3456:789a:1::3', + undercloud_public_host='fd12:3456:789a:1::4', + ipv6_address_mode='dhcpv6-stateful') + self.conf.config(cidr='fd12:3456:789a:1::/64', + 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', + masquerade=False, + host_routes=[], + group='ctlplane-subnet') + undercloud_config._process_network_args(env) expected = { 'NovaIPv6': True, 'RabbitIPv6': True, @@ -229,7 +278,7 @@ class TestNetworkSettings(base.TestCase): 'HostRoutes': [], 'NetworkCidr': 'fd12:3456:789a:1::/64', 'NetworkGateway': 'fd12:3456:789a:1::1'}}, - 'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless', + 'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateful', } self.assertEqual(expected, env) diff --git a/tripleoclient/v1/undercloud_config.py b/tripleoclient/v1/undercloud_config.py index e3a5aca2c..60d9656f2 100644 --- a/tripleoclient/v1/undercloud_config.py +++ b/tripleoclient/v1/undercloud_config.py @@ -224,7 +224,18 @@ def _generate_inspection_subnets(): env_dict = {} s = CONF.get(subnet) env_dict['tag'] = subnet - env_dict['ip_range'] = s.inspection_iprange + if netaddr.IPNetwork(s.cidr).version == 4: + env_dict['ip_range'] = s.inspection_iprange + if netaddr.IPNetwork(s.cidr).version == 6: + if CONF['ipv6_address_mode'] == 'dhcpv6-stateful': + env_dict['ip_range'] = s.inspection_iprange + if CONF['ipv6_address_mode'] == 'dhcpv6-stateless': + # dnsmasq(8): A static-only subnet with address all zeros may + # be used as a "catch-all" address to enable replies to all + # Information-request packets on a subnet which is provided + # with stateless DHCPv6, ie --dhcp-range=::,static + env_dict['ip_range'] = ','.join( + [str(netaddr.IPNetwork(s.cidr).ip), 'static']) env_dict['netmask'] = str(netaddr.IPNetwork(s.cidr).netmask) env_dict['gateway'] = s.gateway env_dict['host_routes'] = s.host_routes