From 4f9a6a8b7661c3792101580d14d401e8426bf72a Mon Sep 17 00:00:00 2001 From: venkata anil Date: Mon, 16 Oct 2017 06:03:35 +0000 Subject: [PATCH] Notify port_update to agent for status change Notify agents about port update when "port_update" is called to update port's status change. L3 agent will spawn keepalived only when HA network port status is ACTIVE. When L3 agent is restarted, it sets HA network port status to DOWN (through "port_update"), with the assumption that L2 agent will again rewire the port (set status to ACTIVE) allowing L3 agent to spawn keepalived. As server is not notifying L2 agent, port is remaining in DOWN status and L3 agent was never spawning keepalived on L3 agent restart(if keepalived is killed). Closes-Bug: 1723848 Change-Id: I629eeff905bf02ec5f7ee68cccc7c19f1b47d5aa --- neutron/plugins/ml2/plugin.py | 2 ++ neutron/tests/unit/plugins/ml2/test_plugin.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 3ca68771c14..e9a88e0bc39 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -1409,6 +1409,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, if original_port['admin_state_up'] != updated_port['admin_state_up']: need_port_update_notify = True + if original_port['status'] != updated_port['status']: + need_port_update_notify = True # NOTE: In the case of DVR ports, the port-binding is done after # router scheduling when sync_routers is called and so this call # below may not be required for DVR routed interfaces. But still diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index bef14186922..40ea374c1ed 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -807,6 +807,16 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase): self.assertEqual('DOWN', port['port']['status']) self.assertEqual('DOWN', self.port_create_status) + def test_notify_port_updated_for_status_change(self): + ctx = context.get_admin_context() + plugin = directory.get_plugin() + with self.port() as port: + with mock.patch.object(self.plugin, + '_notify_port_updated') as notify_mock: + port['port']['status'] = constants.PORT_STATUS_ACTIVE + plugin.update_port(ctx, port['port']['id'], port) + self.assertTrue(notify_mock.called) + def test_update_port_status_short_id(self): ctx = context.get_admin_context() plugin = directory.get_plugin()