From: John Davidge Date: Thu, 13 Aug 2015 22:08:47 +0000 (+0100) Subject: Fix DBDuplicateEntry when creating port with fixed_ips on PD subnet X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=81b266f2f7c16ae39eaa53381a35f02784216458;p=openstack-build%2Fneutron-build.git Fix DBDuplicateEntry when creating port with fixed_ips on PD subnet Creating a port on a prefix delegation enabled subnet with a fixed ip list containing only the subnet id will cause a DBDuplicateEntry error. This is because the subnet is not treated as an ipv6 auto address subnet as it should be by _test_fixed_ips_for_port in ipam_non_pluggable_backend.py All IPV6 PD subnets are auto address subnets, so the additional check was unnecessary and incorrect in this case. This patch changes the condition for appending the subnet id to the fixed_ip_set so that PD subnets are treated the same as auto address subnets. Also includes a unit test to catch this failure. Change-Id: I8ad499467a09133258b1e9e40db736d4e1ae62f3 Closes-Bug: 1484379 --- diff --git a/neutron/db/ipam_non_pluggable_backend.py b/neutron/db/ipam_non_pluggable_backend.py index e935ca26c..4c77835a2 100644 --- a/neutron/db/ipam_non_pluggable_backend.py +++ b/neutron/db/ipam_non_pluggable_backend.py @@ -270,7 +270,6 @@ class IpamNonPluggableBackend(ipam_backend_mixin.IpamBackendMixin): # listed explicitly here by subnet ID) are associated # with the port. if (device_owner in constants.ROUTER_INTERFACE_OWNERS_SNAT or - ipv6_utils.is_ipv6_pd_enabled(subnet) or not is_auto_addr_subnet): fixed_ip_set.append({'subnet_id': subnet['id']}) diff --git a/neutron/tests/unit/db/test_db_base_plugin_v2.py b/neutron/tests/unit/db/test_db_base_plugin_v2.py index bb505acb4..25340e87c 100644 --- a/neutron/tests/unit/db/test_db_base_plugin_v2.py +++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py @@ -1703,9 +1703,16 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s self.assertEqual(1, len(fixed_ips)) self.assertEqual('10.0.0.2', fixed_ips[0]['ip_address']) - def _make_v6_subnet(self, network, ra_addr_mode): - return (self._make_subnet(self.fmt, network, gateway='fe80::1', - cidr='fe80::/64', ip_version=6, + def _make_v6_subnet(self, network, ra_addr_mode, ipv6_pd=False): + cidr = 'fe80::/64' + gateway = 'fe80::1' + if ipv6_pd: + cidr = None + gateway = None + cfg.CONF.set_override('default_ipv6_subnet_pool', + constants.IPV6_PD_POOL_ID) + return (self._make_subnet(self.fmt, network, gateway=gateway, + cidr=cidr, ip_version=6, ipv6_ra_mode=ra_addr_mode, ipv6_address_mode=ra_addr_mode)) @@ -1725,10 +1732,11 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s self.assertEqual(self._calc_ipv6_addr_by_EUI64(port, subnet), port['port']['fixed_ips'][0]['ip_address']) - def _test_create_port_with_ipv6_subnet_in_fixed_ips(self, addr_mode): + def _test_create_port_with_ipv6_subnet_in_fixed_ips(self, addr_mode, + ipv6_pd=False): """Test port create with an IPv6 subnet incl in fixed IPs.""" with self.network(name='net') as network: - subnet = self._make_v6_subnet(network, addr_mode) + subnet = self._make_v6_subnet(network, addr_mode, ipv6_pd) subnet_id = subnet['subnet']['id'] fixed_ips = [{'subnet_id': subnet_id}] with self.port(subnet=subnet, fixed_ips=fixed_ips) as port: @@ -1745,6 +1753,10 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s self._test_create_port_with_ipv6_subnet_in_fixed_ips( addr_mode=constants.IPV6_SLAAC) + def test_create_port_with_ipv6_pd_subnet_in_fixed_ips(self): + self._test_create_port_with_ipv6_subnet_in_fixed_ips( + addr_mode=constants.IPV6_SLAAC, ipv6_pd=True) + def test_create_port_with_ipv6_dhcp_stateful_subnet_in_fixed_ips(self): self._test_create_port_with_ipv6_subnet_in_fixed_ips( addr_mode=constants.DHCPV6_STATEFUL)