Revert "Don't allocate IP on port update when existing subnet specified"

This reverts commit f07c07b16f.
This broke the ability to add fixed IPs to a port based on
subnet_id.

API test to prevent regression in child patch.

Change-Id: Ia13abea59431744ce7a0270f480f4bf61a7161e0
Closes-Bug: #1623800
This commit is contained in:
Kevin Benton 2016-09-14 20:37:56 -07:00
parent 27928c0ddf
commit 748faa0579
3 changed files with 32 additions and 60 deletions

View File

@ -433,27 +433,13 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
for ip in itertools.chain(new_ips, original_ips)
if 'ip_address' in ip}
original_subnets = {ip['subnet_id']: ip['ip_address']
for ip in original_ips}
new = set()
for ip in new_ips:
if ip.get('subnet_id') not in delete_subnet_ids:
if 'ip_address' in ip:
new.add(ip['ip_address'])
else:
# A subnet_id is specified without an address
orig_ip = original_subnets.pop(ip['subnet_id'], None)
if orig_ip and not ipv6_utils.is_eui64_address(orig_ip):
# Use the original address on this subnet
new.add(orig_ip)
else:
# In the case where there is no IP, we have to include
# it in add_ips directly. In case of EUI64 address, the
# prefix may have changed so we want to make sure IPAM
# gets a chance to re-allocate it. This is safe in
# general because EUI-64 addresses always come out the
# same given the prefix doesn't change.
add_ips.append(ip)
add_ips.append(ip)
# Convert original ip addresses to sets
orig = set(ip['ip_address'] for ip in original_ips)

View File

@ -167,51 +167,6 @@ class TestIpamBackendMixin(base.BaseTestCase):
self._mock_slaac_subnet_on()
self._test_get_changed_ips_for_port_no_ip_address()
def test__get_changed_ips_for_port_subnet_id_no_ip(self):
# If a subnet is specified without an IP address only allocate a new
# address if one doesn't exist
self._mock_slaac_subnet_off()
new_ips = [{'subnet_id': 'id-3'}]
original_ips = [{'subnet_id': 'id-3', 'ip_address': '4.3.2.1'}]
expected_change = self.mixin.Changes(
add=[],
original=[{'subnet_id': 'id-3', 'ip_address': '4.3.2.1'}],
remove=[])
self._test_get_changed_ips_for_port(expected_change, original_ips,
new_ips, self.owner_non_router)
def test__get_changed_ips_for_port_subnet_id_no_ip_ipv6(self):
# If a subnet is specified without an IP address only allocate a new
# address if one doesn't exist
self._mock_slaac_subnet_off()
new_ips = [{'subnet_id': 'id-3'}]
original_ips = [{'subnet_id': 'id-3', 'ip_address': '2001:db8::8'}]
expected_change = self.mixin.Changes(
add=[],
original=[{'subnet_id': 'id-3', 'ip_address': '2001:db8::8'}],
remove=[])
self._test_get_changed_ips_for_port(expected_change, original_ips,
new_ips, self.owner_non_router)
def test__get_changed_ips_for_port_subnet_id_no_ip_eui64(self):
# If a subnet is specified without an IP address allocate a new address
# if the address is eui-64. This supports changing prefix when prefix
# delegation is in use.
self._mock_slaac_subnet_off()
new_ips = [{'subnet_id': 'id-3'}]
original_ips = [{'subnet_id': 'id-3',
'ip_address': '2001::eeb1:d7ff:fe2c:9c5f'}]
expected_change = self.mixin.Changes(
add=[{'subnet_id': 'id-3'}],
original=[],
remove=[{'subnet_id': 'id-3',
'ip_address': '2001::eeb1:d7ff:fe2c:9c5f'}])
self._test_get_changed_ips_for_port(expected_change, original_ips,
new_ips, self.owner_non_router)
def test__is_ip_required_by_subnet_for_router_port(self):
# Owner -> router:
# _get_subnet should not be called,

View File

@ -369,6 +369,37 @@ class DNSIntegrationTestCase(test_plugin.Ml2PluginV2TestCase):
previous_dns_name=DNSNAME,
original_ips=original_ips)
def test_update_port_fixed_ips_with_subnet_ids(self, *mocks):
net, port, dns_data_db = self._create_port_for_test()
original_ips = [ip['ip_address'] for ip in port['fixed_ips']]
ctx = context.get_admin_context()
kwargs = {'fixed_ips': []}
for ip in port['fixed_ips']:
# Since this tests using an "any" IP allocation to update the port
# IP address, change the allocation pools so that IPAM won't ever
# give us back the IP address we originally had.
subnet = self.plugin.get_subnet(ctx, ip['subnet_id'])
ip_net = netaddr.IPNetwork(subnet['cidr'])
subnet_size = ip_net.last - ip_net.first
subnet_mid_point = int(ip_net.first + subnet_size / 2)
start, end = (netaddr.IPAddress(subnet_mid_point + 1),
netaddr.IPAddress(ip_net.last - 1))
allocation_pools = [{'start': str(start), 'end': str(end)}]
body = {'allocation_pools': allocation_pools}
req = self.new_update_request('subnets', {'subnet': body},
ip['subnet_id'])
req.get_response(self.api)
kwargs['fixed_ips'].append(
{'subnet_id': ip['subnet_id']})
port, dns_data_db = self._update_port_for_test(port,
new_dns_name=None,
**kwargs)
self._verify_port_dns(net, port, dns_data_db, delete_records=True,
current_dns_name=DNSNAME,
previous_dns_name=DNSNAME,
original_ips=original_ips)
def test_update_port_fixed_ips_with_new_dns_name(self, *mocks):
net, port, dns_data_db = self._create_port_for_test()
original_ips = [ip['ip_address'] for ip in port['fixed_ips']]