Update auto-addresses on MAC change
On MAC update add an entry for auto-addressed IPs so that they get removed and re-allocated. Also add a check to ensure the length of fixed_ips in the result is what was expected i.e. ensure we replaced the IP's(as is the current behaviour) and not just added to the list. Change-Id: Id1eadce7a18ba82d6c1a42f1afb0267f076f9308 Closes-Bug: #1671548
This commit is contained in:
parent
233a68d27c
commit
46d1a890e7
|
@ -335,6 +335,25 @@ class IpamPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||
def update_port_with_ips(self, context, host, db_port, new_port, new_mac):
|
||||
changes = self.Changes(add=[], original=[], remove=[])
|
||||
|
||||
auto_assign_subnets = []
|
||||
if new_mac:
|
||||
original = self._make_port_dict(db_port, process_extensions=False)
|
||||
if original.get('mac_address') != new_mac:
|
||||
original_ips = original.get('fixed_ips', [])
|
||||
new_ips = new_port.setdefault('fixed_ips', original_ips)
|
||||
new_ips_subnets = [new_ip['subnet_id'] for new_ip in new_ips]
|
||||
for orig_ip in original_ips:
|
||||
if ipv6_utils.is_eui64_address(orig_ip.get('ip_address')):
|
||||
subnet_to_delete = {}
|
||||
subnet_to_delete['subnet_id'] = orig_ip['subnet_id']
|
||||
subnet_to_delete['delete_subnet'] = True
|
||||
auto_assign_subnets.append(subnet_to_delete)
|
||||
try:
|
||||
i = new_ips_subnets.index(orig_ip['subnet_id'])
|
||||
new_ips[i] = subnet_to_delete
|
||||
except ValueError:
|
||||
new_ips.append(subnet_to_delete)
|
||||
|
||||
if 'fixed_ips' in new_port:
|
||||
original = self._make_port_dict(db_port,
|
||||
process_extensions=False)
|
||||
|
@ -362,6 +381,14 @@ class IpamPluggableBackend(ipam_backend_mixin.IpamBackendMixin):
|
|||
self._update_db_port(context, db_port, new_port, network_id,
|
||||
new_mac)
|
||||
getattr(db_port, 'fixed_ips') # refresh relationship before return
|
||||
|
||||
if auto_assign_subnets:
|
||||
port_copy = copy.deepcopy(original)
|
||||
port_copy.update(new_port)
|
||||
port_copy['fixed_ips'] = auto_assign_subnets
|
||||
self.allocate_ips_for_port_and_store(context,
|
||||
{'port': port_copy}, port_copy['id'])
|
||||
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
if 'fixed_ips' in new_port:
|
||||
|
|
|
@ -1381,8 +1381,6 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s
|
|||
subnet_cidr = subnet['subnet']['cidr']
|
||||
eui_addr = str(netutils.get_ipv6_addr_by_EUI64(subnet_cidr,
|
||||
port_mac))
|
||||
# TODO(kevinbenton): remove after bug 1671548 fix
|
||||
eui_addr = mock.ANY
|
||||
fip = {'ip_address': eui_addr,
|
||||
'subnet_id': subnet['subnet']['id']}
|
||||
self.assertIn(fip, new_port['port']['fixed_ips'])
|
||||
|
@ -1408,6 +1406,9 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s
|
|||
self.assertEqual(new_mac, result['port']['mac_address'])
|
||||
if updated_fixed_ips is None:
|
||||
self._verify_ips_after_mac_change(port, result)
|
||||
else:
|
||||
self.assertEqual(len(updated_fixed_ips),
|
||||
len(result['port']['fixed_ips']))
|
||||
else:
|
||||
error = self.deserialize(self.fmt, res)
|
||||
self.assertEqual(expected_error,
|
||||
|
|
Loading…
Reference in New Issue