Improve content of FloatingIP AFTER callbacks

Use same FIP field names for all notifications.
Move association_event field into Payload metadata.

Closes-Bug: #1933502
Change-Id: Ia462ca4b340cd3d9a27341632b24926c3290a4b2
This commit is contained in:
Szymon Wroblewski 2021-06-24 21:12:53 +02:00
parent b488fb8e22
commit a177249731
3 changed files with 126 additions and 109 deletions

View File

@ -1323,16 +1323,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
floatingip_obj.last_known_router_id = previous_router_id
if 'description' in fip:
floatingip_obj.description = fip['description']
floating_ip_address = (str(floatingip_obj.floating_ip_address)
if floatingip_obj.floating_ip_address else None)
return {'fixed_ip_address': internal_ip_address,
'fixed_port_id': port_id,
'router_id': router_id,
'last_known_router_id': previous_router_id,
'floating_ip_address': floating_ip_address,
'floating_network_id': floatingip_obj.floating_network_id,
'floating_ip_id': floatingip_obj.id,
'association_event': association_event}
return association_event
def _is_ipv4_network(self, context, net_db):
return any(s.ip_version == 4 for s in net_db.subnets)
@ -1437,15 +1428,14 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
registry.publish(
resources.FLOATING_IP, events.AFTER_CREATE, self,
payload=events.DBEventPayload(
context, states=(assoc_result,),
context, states=(floatingip_dict,),
resource_id=floatingip_obj.id,
metadata={
'association_event': assoc_result['association_event']}))
if assoc_result['association_event']:
metadata={'association_event': assoc_result}))
if assoc_result:
LOG.info(FIP_ASSOC_MSG,
{'fip_id': assoc_result['floating_ip_id'],
'ext_ip': assoc_result['floating_ip_address'],
'port_id': assoc_result['fixed_port_id'],
{'fip_id': floatingip_obj.id,
'ext_ip': str(floatingip_obj.floating_ip_address),
'port_id': floatingip_obj.fixed_port_id,
'assoc': 'associated'})
if self._is_dns_integration_supported:
@ -1505,17 +1495,15 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
registry.publish(
resources.FLOATING_IP, events.AFTER_UPDATE, self,
payload=events.DBEventPayload(
context, states=(assoc_result,),
context, states=(old_floatingip, floatingip_dict),
resource_id=floatingip_obj.id,
metadata={
'association_event': assoc_result['association_event']}))
if assoc_result['association_event'] is not None:
port_id = old_fixed_port_id or assoc_result['fixed_port_id']
assoc = ('associated' if assoc_result['association_event']
else 'disassociated')
metadata={'association_event': assoc_result}))
if assoc_result is not None:
port_id = old_fixed_port_id or floatingip_obj.fixed_port_id
assoc = 'associated' if assoc_result else 'disassociated'
LOG.info(FIP_ASSOC_MSG,
{'fip_id': assoc_result['floating_ip_id'],
'ext_ip': assoc_result['floating_ip_address'],
{'fip_id': floatingip_obj.id,
'ext_ip': str(floatingip_obj.floating_ip_address),
'port_id': port_id, 'assoc': assoc})
if self._is_dns_integration_supported:
@ -1684,12 +1672,21 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
floating_ip_objs = l3_obj.FloatingIP.get_objects(
context, fixed_port_id=port_id)
router_ids = {fip.router_id for fip in floating_ip_objs}
old_fips = {fip.id: fip.to_dict() for fip in floating_ip_objs}
old_fips = {fip.id: self._make_floatingip_dict(fip)
for fip in floating_ip_objs}
values = {'fixed_port_id': None,
'fixed_ip_address': None,
'router_id': None}
l3_obj.FloatingIP.update_objects(
context, values, fixed_port_id=port_id)
# NOTE(swroblew): to avoid querying DB for new FIPs state,
# update state of local FIP objects for _make_floatingip_dict call
for fip in floating_ip_objs:
fip.fixed_port_id = None
fip.fixed_ip_address = None
fip.router_id = None
new_fips = {fip.id: self._make_floatingip_dict(fip)
for fip in floating_ip_objs}
for fip in floating_ip_objs:
registry.publish(
resources.FLOATING_IP,
@ -1702,33 +1699,21 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
states=(old_fips[fip.id],
{l3_apidef.FLOATINGIP: values})))
for fip in floating_ip_objs:
assoc_result = {
'fixed_ip_address': None,
'fixed_port_id': None,
'router_id': None,
'floating_ip_address': (
str(fip.floating_ip_address)
if fip.floating_ip_address else None),
'floating_network_id': fip.floating_network_id,
'floating_ip_id': fip.id,
'router_ids': router_ids,
'association_event': False,
}
for fip_id, fip in new_fips.items():
# Process DNS record removal after committing the transaction
if self._is_dns_integration_supported:
self._process_dns_floatingip_delete(context, fip.to_dict())
self._process_dns_floatingip_delete(context, fip)
registry.publish(
resources.FLOATING_IP, events.AFTER_UPDATE, self,
payload=events.DBEventPayload(
context, states=(assoc_result,),
resource_id=fip.id,
context, states=(old_fips[fip_id], fip),
resource_id=fip_id,
metadata={'association_event': False}))
for fip in old_fips.values():
LOG.info(FIP_ASSOC_MSG,
{'fip_id': fip['id'],
'ext_ip': fip['floating_ip_address'],
'port_id': fip['fixed_port_id'],
'ext_ip': str(fip['floating_ip_address']),
'port_id': fip['port_id'],
'assoc': 'disassociated'})
return router_ids

View File

@ -634,9 +634,8 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
payload=events.DBEventPayload(
context=mock.Mock(), states=(dict(
router_id=router_db['id'], fixed_port_id=port['id'],
floating_ip_id=fip['id'],
floating_network_id=fip['floating_network_id'],
fixed_ip_address='1.2.3.4'),),
fixed_ip_address='1.2.3.4', id=fip['id'],
floating_network_id=fip['floating_network_id']),),
resource_id=fip['id'],
metadata=dict(association_event=True)))
return c_fip

View File

@ -2714,16 +2714,13 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
with self.port() as p:
private_sub = {'subnet': {'id':
p['port']['fixed_ips'][0]['subnet_id']}}
with self.floatingip_no_assoc(private_sub) as fip:
with self.floatingip_no_assoc(private_sub) as f:
port_id = p['port']['id']
ip_address = p['port']['fixed_ips'][0]['ip_address']
fip = f['floatingip']
with mock.patch.object(registry, 'publish') as publish:
body = self._update('floatingips',
fip['floatingip']['id'],
body = self._update('floatingips', fip['id'],
{'floatingip': {'port_id': port_id}})
fip_addr = fip['floatingip']['floating_ip_address']
fip_network_id = fip['floatingip']['floating_network_id']
fip_id = fip['floatingip']['id']
router_id = body['floatingip']['router_id']
body = self._show('routers', router_id)
publish.assert_any_call(
@ -2734,34 +2731,44 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
if event == events.AFTER_UPDATE:
break
payload = call_kwargs['payload']
fip_dict = dict(
previous = dict(
fixed_ip_address=None,
floating_ip_address=fip['floating_ip_address'],
floating_network_id=fip['floating_network_id'],
id=fip['id'],
port_id=None,
project_id=fip['project_id'],
router_id=None,
tenant_id=fip['tenant_id'])
current = previous.copy()
current.update(
fixed_ip_address=ip_address,
fixed_port_id=port_id,
floating_ip_address=fip_addr,
floating_network_id=fip_network_id,
last_known_router_id=None,
floating_ip_id=fip_id,
router_id=router_id,
association_event=True)
self.assertDictEqual(fip_dict, payload.latest_state)
port_id=port_id,
router_id=router_id)
skip = ('description', 'dns_domain', 'dns_name',
'port_details', 'qos_policy_id', 'revision_number',
'status', 'standard_attr_id')
for k in skip:
payload.states[0].pop(k, None)
payload.states[1].pop(k, None)
self.assertDictEqual(previous, payload.states[0])
self.assertDictEqual(current, payload.states[1])
self.assertEqual(fip['id'], payload.resource_id)
self.assertTrue(payload.metadata['association_event'])
def test_floatingip_disassociate_notification(self):
with self.port() as p:
private_sub = {'subnet': {'id':
p['port']['fixed_ips'][0]['subnet_id']}}
with self.floatingip_no_assoc(private_sub) as fip:
with self.floatingip_no_assoc(private_sub) as f:
port_id = p['port']['id']
body = self._update('floatingips',
fip['floatingip']['id'],
ip_address = p['port']['fixed_ips'][0]['ip_address']
fip = f['floatingip']
body = self._update('floatingips', fip['id'],
{'floatingip': {'port_id': port_id}})
with mock.patch.object(registry, 'publish') as publish:
fip_addr = fip['floatingip']['floating_ip_address']
fip_network_id = fip['floatingip']['floating_network_id']
fip_id = fip['floatingip']['id']
router_id = body['floatingip']['router_id']
self._update('floatingips',
fip['floatingip']['id'],
self._update('floatingips', fip['id'],
{'floatingip': {'port_id': None}})
publish.assert_any_call(
resources.FLOATING_IP, events.AFTER_UPDATE, mock.ANY,
@ -2771,31 +2778,42 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
if event == events.AFTER_UPDATE:
break
payload = call_kwargs['payload']
fip_dict = dict(
previous = dict(
fixed_ip_address=ip_address,
floating_ip_address=fip['floating_ip_address'],
floating_network_id=fip['floating_network_id'],
id=fip['id'],
port_id=port_id,
project_id=fip['project_id'],
router_id=router_id,
tenant_id=fip['tenant_id'])
current = previous.copy()
current.update(
fixed_ip_address=None,
fixed_port_id=None,
floating_ip_address=fip_addr,
floating_network_id=fip_network_id,
last_known_router_id=router_id,
floating_ip_id=fip_id,
router_id=None,
association_event=False)
self.assertDictEqual(fip_dict, payload.latest_state)
port_id=None,
router_id=None)
skip = ('description', 'dns_domain', 'dns_name',
'port_details', 'qos_policy_id', 'revision_number',
'status', 'standard_attr_id')
for k in skip:
payload.states[0].pop(k, None)
payload.states[1].pop(k, None)
self.assertDictEqual(previous, payload.states[0])
self.assertDictEqual(current, payload.states[1])
self.assertEqual(fip['id'], payload.resource_id)
self.assertFalse(payload.metadata['association_event'])
def test_floatingip_disassociate_notification_port_delete(self):
with self.port() as p:
private_sub = {'subnet': {'id':
p['port']['fixed_ips'][0]['subnet_id']}}
with self.floatingip_no_assoc(private_sub) as fip:
with self.floatingip_no_assoc(private_sub) as f:
port_id = p['port']['id']
body = self._update('floatingips',
fip['floatingip']['id'],
ip_address = p['port']['fixed_ips'][0]['ip_address']
fip = f['floatingip']
body = self._update('floatingips', fip['id'],
{'floatingip': {'port_id': port_id}})
with mock.patch.object(registry, 'publish') as publish:
fip_id = fip['floatingip']['id']
fip_address = fip['floatingip']['floating_ip_address']
f_network_id = fip['floatingip']['floating_network_id']
router_id = body['floatingip']['router_id']
self._delete('ports', p['port']['id'])
publish.assert_any_call(
@ -2806,16 +2824,29 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
if event == events.AFTER_UPDATE:
break
payload = call_kwargs['payload']
fip_dict = dict(
previous = dict(
fixed_ip_address=ip_address,
floating_ip_address=fip['floating_ip_address'],
floating_network_id=fip['floating_network_id'],
id=fip['id'],
port_id=port_id,
project_id=fip['project_id'],
router_id=router_id,
tenant_id=fip['tenant_id'])
current = previous.copy()
current.update(
fixed_ip_address=None,
fixed_port_id=None,
router_id=None,
floating_ip_address=fip_address,
floating_network_id=f_network_id,
floating_ip_id=fip_id,
router_ids={router_id, },
association_event=False)
self.assertDictEqual(fip_dict, payload.latest_state)
port_id=None,
router_id=None)
skip = ('description', 'dns_domain', 'dns_name',
'port_details', 'qos_policy_id', 'revision_number',
'status', 'standard_attr_id')
for k in skip:
payload.states[0].pop(k, None)
payload.states[1].pop(k, None)
self.assertDictEqual(previous, payload.states[0])
self.assertDictEqual(current, payload.states[1])
self.assertEqual(fip['id'], payload.resource_id)
self.assertFalse(payload.metadata['association_event'])
def test_floatingip_association_on_unowned_router(self):
@ -4082,20 +4113,22 @@ class L3AgentDbTestCaseBase(L3NatTestCaseMixin):
if event == events.AFTER_DELETE:
break
payload = call_kwargs['payload']
fip_dict = dict(
description=mock.ANY,
dns_domain=mock.ANY, dns_name=mock.ANY,
fixed_ip_address=f['floatingip']['fixed_ip_address'],
floating_ip_address=f['floatingip']['floating_ip_address'],
floating_network_id=f['floatingip']['floating_network_id'],
id=f['floatingip']['id'],
port_id=f['floatingip']['port_id'],
project_id=f['floatingip']['project_id'],
router_id=f['floatingip']['router_id'],
status=f['floatingip']['status'],
tenant_id=f['floatingip']['tenant_id'],
standard_attr_id=mock.ANY)
self.assertDictEqual(fip_dict, payload.latest_state)
fip = f['floatingip']
previous = dict(
fixed_ip_address=fip['fixed_ip_address'],
floating_ip_address=fip['floating_ip_address'],
floating_network_id=fip['floating_network_id'],
id=fip['id'],
port_id=fip['port_id'],
project_id=fip['project_id'],
router_id=fip['router_id'],
tenant_id=fip['tenant_id'])
skip = ('description', 'dns_domain', 'dns_name',
'port_details', 'qos_policy_id', 'revision_number',
'status', 'standard_attr_id')
for k in skip:
payload.states[0].pop(k, None)
self.assertDictEqual(previous, payload.states[0])
finally:
registry.unsubscribe(fake_method, resources.FLOATING_IP,
events.AFTER_DELETE)