From 427c726d3a064baa7dacd143eb21cb31ca7f1290 Mon Sep 17 00:00:00 2001 From: linb Date: Thu, 13 Aug 2015 13:16:18 +0800 Subject: [PATCH] Nsxv: Fix db out of sync with backend When creating a router, sometimes db process succeed but edge failed at the backend. The patch add exception handle for creating router and delete the router db if failed at the backend. Change-Id: I81d683b201d44abeb6049b3b91139f2f898f1777 Fixes-bug: #1497869 --- .../neutron/plugins/vmware/plugins/nsx_v.py | 21 ++++++++------ .../nsx_v_drivers/exclusive_router_driver.py | 10 +++---- .../tests/unit/vmware/test_nsx_v_plugin.py | 28 +++++++++++++++++++ 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v.py b/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v.py index 88e5d135f1..d9a5431b2c 100644 --- a/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v.py +++ b/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v.py @@ -1344,13 +1344,18 @@ class NsxVPluginV2(agents_db.AgentDbMixin, with context.session.begin(subtransactions=True): router_db = self._get_router(context, lrouter['id']) self._process_nsx_router_create(context, router_db, r) - router_driver = self._get_router_driver(context, router_db) - router_driver.create_router( - context, lrouter, - allow_metadata=(allow_metadata and self.metadata_proxy_handler)) - if gw_info != attr.ATTR_NOT_SPECIFIED: - router_driver._update_router_gw_info( - context, lrouter['id'], gw_info) + try: + router_driver = self._get_router_driver(context, router_db) + router_driver.create_router( + context, lrouter, + allow_metadata=(allow_metadata and + self.metadata_proxy_handler)) + if gw_info != attr.ATTR_NOT_SPECIFIED: + router_driver._update_router_gw_info( + context, lrouter['id'], gw_info) + except Exception: + with excutils.save_and_reraise_exception(): + self.delete_router(context, lrouter['id']) return self.get_router(context, lrouter['id']) def update_router(self, context, router_id, router): @@ -1382,8 +1387,8 @@ class NsxVPluginV2(agents_db.AgentDbMixin, def delete_router(self, context, id): self._check_router_in_use(context, id) router_driver = self._find_router_driver(context, id) - router_driver.delete_router(context, id) super(NsxVPluginV2, self).delete_router(context, id) + router_driver.delete_router(context, id) def get_router(self, context, id, fields=None): router = super(NsxVPluginV2, self).get_router(context, id, fields) diff --git a/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v_drivers/exclusive_router_driver.py b/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v_drivers/exclusive_router_driver.py index 9b3fac9373..c0b9f43067 100644 --- a/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v_drivers/exclusive_router_driver.py +++ b/vmware_nsx/neutron/plugins/vmware/plugins/nsx_v_drivers/exclusive_router_driver.py @@ -62,12 +62,10 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver): return self.plugin.get_router(context, router_id) def delete_router(self, context, router_id): - with locking.LockManager.get_lock( - self._get_router_edge_id(context, router_id), external=True): - self.edge_manager.delete_lrouter(context, router_id, dist=False) - if self.plugin.metadata_proxy_handler: - self.plugin.metadata_proxy_handler.cleanup_router_edge( - router_id) + self.edge_manager.delete_lrouter(context, router_id, dist=False) + if self.plugin.metadata_proxy_handler: + self.plugin.metadata_proxy_handler.cleanup_router_edge( + router_id) def update_routes(self, context, router_id, nexthop): with locking.LockManager.get_lock( diff --git a/vmware_nsx/neutron/tests/unit/vmware/test_nsx_v_plugin.py b/vmware_nsx/neutron/tests/unit/vmware/test_nsx_v_plugin.py index 3a4ca8b32d..cbb07dec10 100644 --- a/vmware_nsx/neutron/tests/unit/vmware/test_nsx_v_plugin.py +++ b/vmware_nsx/neutron/tests/unit/vmware/test_nsx_v_plugin.py @@ -1527,6 +1527,20 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, for k, v in expected: self.assertEqual(net['network'][k], v) + def test_create_router_fail_at_the_backend(self): + p = manager.NeutronManager.get_plugin() + edge_manager = p.edge_manager + with mock.patch.object(edge_manager, 'create_lrouter', + side_effect=[n_exc.NeutronException]): + router = {'router': {'admin_state_up': True, + 'name': 'e161be1d-0d0d-4046-9823-5a593d94f72c', + 'router_type': 'exclusive'}} + self.assertRaises(n_exc.NeutronException, + p.create_router, + context.get_admin_context(), + router) + self._test_list_resources('router', ()) + def test_create_l3_ext_network_with_dhcp(self): with self._create_l3_ext_network() as net: with testlib_api.ExpectedException( @@ -1976,6 +1990,20 @@ class TestVdrTestCase(L3NatTest, L3NatTestCaseBase, test_l3_plugin.L3NatDBIntTestCase, NsxVPluginV2TestCase): + def test_create_router_fail_at_the_backend(self): + p = manager.NeutronManager.get_plugin() + edge_manager = p.edge_manager + with mock.patch.object(edge_manager, 'create_lrouter', + side_effect=[n_exc.NeutronException]): + router = {'router': {'admin_state_up': True, + 'name': 'e161be1d-0d0d-4046-9823-5a593d94f72c', + 'distributed': True}} + self.assertRaises(n_exc.NeutronException, + p.create_router, + context.get_admin_context(), + router) + self._test_list_resources('router', ()) + def test_update_port_device_id_to_different_tenants_router(self): self.skipTest('TBD')