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:
parent
27928c0ddf
commit
748faa0579
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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']]
|
||||
|
Loading…
Reference in New Issue
Block a user