diff --git a/neutron/notifiers/nova.py b/neutron/notifiers/nova.py index 2b2bab63d1..e95100597a 100644 --- a/neutron/notifiers/nova.py +++ b/neutron/notifiers/nova.py @@ -132,6 +132,18 @@ class Notifier(object): if not cfg.CONF.notify_nova_on_port_data_changes: return + # When neutron re-assigns floating ip from an original instance + # port to a new instance port without disassociate it first, an + # event should be sent for original instance, that will make nova + # know original instance's info, and update database for it. + if (action == 'update_floatingip' + and returned_obj['floatingip'].get('port_id') + and original_obj.get('port_id')): + disassociate_returned_obj = {'floatingip': {'port_id': None}} + event = self.create_port_changed_event(action, original_obj, + disassociate_returned_obj) + self.queue_event(event) + event = self.create_port_changed_event(action, original_obj, returned_obj) self.queue_event(event) diff --git a/neutron/tests/unit/notifiers/test_notifiers_nova.py b/neutron/tests/unit/notifiers/test_notifiers_nova.py index 7972ebf55a..db9bc79c31 100644 --- a/neutron/tests/unit/notifiers/test_notifiers_nova.py +++ b/neutron/tests/unit/notifiers/test_notifiers_nova.py @@ -303,3 +303,20 @@ class TestNovaNotify(base.BaseTestCase): self.nova_notifier.queue_event(mock.Mock()) self.assertFalse(self.nova_notifier._waiting_to_send) send_events.assert_called_once_with() + + def test_reassociate_floatingip_without_disassociate_event(self): + returned_obj = {'floatingip': + {'port_id': 'f5348a16-609a-4971-b0f0-4b8def5235fb'}} + original_obj = {'port_id': '5a39def4-3d3f-473d-9ff4-8e90064b9cc1'} + self.nova_notifier._waiting_to_send = True + self.nova_notifier.send_network_change( + 'update_floatingip', original_obj, returned_obj) + self.assertEqual(2, len(self.nova_notifier.pending_events)) + + returned_obj_non = {'floatingip': {'port_id': None}} + event_dis = self.nova_notifier.create_port_changed_event( + 'update_floatingip', original_obj, returned_obj_non) + event_assoc = self.nova_notifier.create_port_changed_event( + 'update_floatingip', original_obj, returned_obj) + self.assertEqual(self.nova_notifier.pending_events[0], event_dis) + self.assertEqual(self.nova_notifier.pending_events[1], event_assoc)