diff --git a/vmware_nsx/db/db.py b/vmware_nsx/db/db.py index f40a4a3394..dd6cb7e0a0 100644 --- a/vmware_nsx/db/db.py +++ b/vmware_nsx/db/db.py @@ -567,6 +567,15 @@ def get_nsx_lbaas_loadbalancer_binding_by_service(session, lb_service_id): lb_service_id=lb_service_id).all() +def has_nsx_lbaas_loadbalancer_binding_by_router(session, nsx_router_id): + try: + session.query(nsx_models.NsxLbaasLoadbalancer).filter_by( + lb_router_id=nsx_router_id).one() + return True + except exc.NoResultFound: + return False + + def delete_nsx_lbaas_loadbalancer_binding(session, loadbalancer_id): return (session.query(nsx_models.NsxLbaasLoadbalancer). filter_by(loadbalancer_id=loadbalancer_id).delete()) diff --git a/vmware_nsx/plugins/common_v3/plugin.py b/vmware_nsx/plugins/common_v3/plugin.py index 9c72d0d772..df0a9df124 100644 --- a/vmware_nsx/plugins/common_v3/plugin.py +++ b/vmware_nsx/plugins/common_v3/plugin.py @@ -829,7 +829,7 @@ class NsxPluginV3Base(plugin.NsxPluginBase, def _get_update_router_gw_actions( self, org_tier0_uuid, orgaddr, org_enable_snat, - new_tier0_uuid, newaddr, new_enable_snat): + new_tier0_uuid, newaddr, new_enable_snat, lb_exist, fw_exist): """Return a dictionary of flags indicating which actions should be performed on this router GW update. """ @@ -888,12 +888,20 @@ class NsxPluginV3Base(plugin.NsxPluginBase, actions['advertise_route_connected_flag'] = ( True if not new_enable_snat else False) - # TODO(asarfaty): calculate flags for add/remove service router - actions['remove_service_router'] = ( - actions['remove_router_link_port'] and - not actions['add_router_link_port']) - actions['add_service_router'] = ( - actions['add_router_link_port'] and - not actions['remove_router_link_port']) + # the purpose of the two vars is to be able to differ between + # adding a gateway w/o snat and adding snat (when adding/removing gw + # the snat option is on by default. + + real_new_enable_snat = new_enable_snat and newaddr + real_org_enable_snat = org_enable_snat and orgaddr + + actions['add_service_router'] = ((real_new_enable_snat and + not real_org_enable_snat) or + (real_new_enable_snat and not + orgaddr and newaddr) + ) and not (fw_exist or lb_exist) + actions['remove_service_router'] = ((not real_new_enable_snat and + real_org_enable_snat) or ( + orgaddr and not newaddr)) and not (fw_exist or lb_exist) return actions diff --git a/vmware_nsx/plugins/nsx_p/plugin.py b/vmware_nsx/plugins/nsx_p/plugin.py index 05ca1fde02..d1c045de43 100644 --- a/vmware_nsx/plugins/nsx_p/plugin.py +++ b/vmware_nsx/plugins/nsx_p/plugin.py @@ -950,7 +950,8 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, context.elevated(), router_id) actions = self._get_update_router_gw_actions( org_tier0_uuid, orgaddr, org_enable_snat, - new_tier0_uuid, newaddr, new_enable_snat) + new_tier0_uuid, newaddr, new_enable_snat, fw_exist=False, + lb_exist=False) if actions['add_service_router']: edge_cluster = self.nsxpolicy.tier0.get_edge_cluster_path( diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 795db1feb8..dbacd0f3cb 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -881,7 +881,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, return self.conn.consume_in_threads() def _get_edge_cluster(self, tier0_uuid): - self.nsxlib.router.validate_tier0(self.tier0_groups_dict, tier0_uuid) + if (not self.tier0_groups_dict.get(tier0_uuid) or not self. + tier0_groups_dict[tier0_uuid].get('edge_cluster_uuid')): + self.nsxlib.router.validate_tier0(self.tier0_groups_dict, + tier0_uuid) tier0_info = self.tier0_groups_dict[tier0_uuid] return tier0_info['edge_cluster_uuid'] @@ -3189,6 +3192,44 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, 'net': sub['network_id']}) raise n_exc.InvalidInput(error_message=msg) + def state_firewall_rules(self, context, router_id): + if self.fwaas_callbacks and self.fwaas_callbacks.fwaas_enabled: + ports = self._get_router_interfaces(context, router_id) + return self.fwaas_callbacks.router_with_fwg(context, ports) + + def verify_sr_at_backend(self, context, router_id): + nsx_router_id = nsx_db.get_nsx_router_id(context.session, + router_id) + return self.nsxlib.router.has_service_router(nsx_router_id) + + def service_router_has_services(self, context, router_id): + nsx_router_id = nsx_db.get_nsx_router_id(context.session, + router_id) + router = self._get_router(context, router_id) + snat_exist = router.enable_snat + lb_exist = nsx_db.has_nsx_lbaas_loadbalancer_binding_by_router( + context.session, nsx_router_id) + fw_exist = self.state_firewall_rules(context, router_id) + if snat_exist or lb_exist or fw_exist: + return True + return snat_exist or lb_exist or fw_exist + + def create_service_router(self, context, router_id): + router = self._get_router(context, router_id) + tier0_uuid = self._get_tier0_uuid_by_router(context, router) + edge_cluster_uuid = self._get_edge_cluster(tier0_uuid) + nsx_router_id = nsx_db.get_nsx_router_id(context.session, + router_id) + self.nsxlib.router.update_router_edge_cluster(nsx_router_id, + edge_cluster_uuid) + + def delete_service_router(self, context, router_id): + nsx_router_id = nsx_db.get_nsx_router_id(context.session, + router_id) + self.nsxlib.router.change_edge_firewall_status( + nsx_router_id, nsxlib_consts.FW_DISABLE) + self.nsxlib.router.update_router_edge_cluster(nsx_router_id, None) + def _update_router_gw_info(self, context, router_id, info): router = self._get_router(context, router_id) org_tier0_uuid = self._get_tier0_uuid_by_router(context, router) @@ -3196,6 +3237,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, orgaddr, orgmask, _orgnexthop = ( self._get_external_attachment_info( context, router)) + self._validate_router_gw(context, router_id, info, org_enable_snat) router_subnets = self._find_router_subnets( @@ -3221,15 +3263,24 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, context, router)) nsx_router_id = nsx_db.get_nsx_router_id(context.session, router_id) + lb_exist = nsx_db.has_nsx_lbaas_loadbalancer_binding_by_router( + context.session, nsx_router_id) + fw_exist = self.state_firewall_rules(context, router_id) + actions = self._get_update_router_gw_actions( org_tier0_uuid, orgaddr, org_enable_snat, - new_tier0_uuid, newaddr, new_enable_snat) + new_tier0_uuid, newaddr, new_enable_snat, lb_exist, fw_exist) + + if actions['add_service_router']: + self.create_service_router(context, router_id) if actions['revocate_bgp_announce']: + # TODO(berlin): revocate bgp announce on org tier0 router pass if actions['remove_snat_rules']: self.nsxlib.router.delete_gw_snat_rules(nsx_router_id, orgaddr) + if actions['remove_no_dnat_rules']: for subnet in router_subnets: self._del_subnet_no_dnat_rule(context, nsx_router_id, subnet) @@ -3241,21 +3292,17 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, self.nsxlib.router.update_router_transport_zone( nsx_router_id, None) if actions['add_router_link_port']: - # First update edge cluster info for router - edge_cluster_uuid = self._get_edge_cluster(new_tier0_uuid) - self.nsxlib.router.update_router_edge_cluster( - nsx_router_id, edge_cluster_uuid) # Add the overlay transport zone to the router config if self.nsxlib.feature_supported( - nsxlib_consts.FEATURE_ROUTER_TRANSPORT_ZONE): + nsxlib_consts.FEATURE_ROUTER_TRANSPORT_ZONE): tz_uuid = self.nsxlib.router.get_tier0_router_overlay_tz( new_tier0_uuid) if tz_uuid: self.nsxlib.router.update_router_transport_zone( nsx_router_id, tz_uuid) tags = self.nsxlib.build_v3_tags_payload( - router, resource_type='os-neutron-rport', - project_name=context.tenant_name) + router, resource_type='os-neutron-rport', + project_name=context.tenant_name) self.nsxlib.router.add_router_link_port(nsx_router_id, new_tier0_uuid, tags=tags) @@ -3280,6 +3327,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, actions['advertise_route_nat_flag'], actions['advertise_route_connected_flag']) + if actions['remove_service_router']: + self.delete_service_router(context, router_id) + def _add_subnet_snat_rule(self, context, router_id, nsx_router_id, subnet, gw_address_scope, gw_ip): # if the subnets address scope is the same as the gateways: @@ -3610,7 +3660,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, return nsx_router_id, section_id - def update_router_firewall(self, context, router_id): + def update_router_firewall(self, context, router_id, from_fw=False): """Rewrite all the rules in the router edge firewall This method should be called on FWaaS v1/v2 updates, and on router @@ -3629,7 +3679,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # let the fwaas callbacks update the router FW return self.fwaas_callbacks.update_router_firewall( context, self.nsxlib, router_id, ports, - nsx_router_id, section_id) + nsx_router_id, section_id, from_fw=from_fw) def _get_port_relay_servers(self, context, port_id, network_id=None): if not network_id: diff --git a/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v2.py b/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v2.py index 7984c5f533..2bec6cde63 100644 --- a/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v2.py +++ b/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver_v2.py @@ -83,7 +83,8 @@ class EdgeFwaasV3DriverV2(base_driver.CommonEdgeFwaasV3Driver): # update each router once for router_id in routers: - self.core_plugin.update_router_firewall(context, router_id) + self.core_plugin.update_router_firewall(context, router_id, + from_fw=True) def get_port_translated_rules(self, nsx_ls_id, firewall_group, plugin_rules): diff --git a/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py b/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py index 3c091b599c..1f2451cc9a 100644 --- a/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py +++ b/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v1.py @@ -60,7 +60,8 @@ class Nsxv3FwaasCallbacksV1(com_clbcks.NsxFwaasCallbacks): return True def update_router_firewall(self, context, nsxlib, router_id, - router_interfaces, nsx_router_id, section_id): + router_interfaces, nsx_router_id, section_id, + from_fw=False): """Rewrite all the FWaaS v1 rules in the router edge firewall This method should be called on FWaaS updates, and on router diff --git a/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v2.py b/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v2.py index 361daefeb7..3d0f78d6a5 100644 --- a/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v2.py +++ b/vmware_nsx/services/fwaas/nsx_v3/fwaas_callbacks_v2.py @@ -68,14 +68,25 @@ class Nsxv3FwaasCallbacksV2(com_callbacks.NsxFwaasCallbacksV2): return self.internal_driver.get_port_translated_rules( nsx_ls_id, fwg, plugin_rules) + def router_with_fwg(self, context, router_interfaces): + for port in router_interfaces: + fwg = self.get_port_fwg(context, port['id']) + if fwg and fwg.get('status') == nl_constants.ACTIVE: + return True + return False + def update_router_firewall(self, context, nsxlib, router_id, - router_interfaces, nsx_router_id, section_id): + router_interfaces, nsx_router_id, section_id, + from_fw=False): """Rewrite all the FWaaS v2 rules in the router edge firewall This method should be called on FWaaS updates, and on router interfaces changes. + The purpose of from_fw is to differ between fw calls and other router + calls, and if it is True - add the service router accordingly. """ fw_rules = [] + with_fw = False # Add firewall rules per port attached to a firewall group for port in router_interfaces: nsx_ls_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id( @@ -84,6 +95,7 @@ class Nsxv3FwaasCallbacksV2(com_callbacks.NsxFwaasCallbacksV2): # Check if this port has a firewall fwg = self.get_port_fwg(context, port['id']) if fwg: + with_fw = True # Add plugin additional allow rules plugin_rules = self.core_plugin.get_extra_fw_rules( context, router_id, port['id']) @@ -99,7 +111,25 @@ class Nsxv3FwaasCallbacksV2(com_callbacks.NsxFwaasCallbacksV2): section_id, allow_all=True)) # update the backend router firewall - nsxlib.firewall_section.update(section_id, rules=fw_rules) + exists_on_backend = self.core_plugin.verify_sr_at_backend(context, + router_id) + if from_fw: + # fw action required + if with_fw: + # firewall exists in Neutron and not on backend - create + if not exists_on_backend: + self.core_plugin.create_service_router(context, router_id) + exists_on_backend = True + else: + # First, check if other services exist and use the sr + sr_exists = self.core_plugin.service_router_has_services( + context, router_id) + if not sr_exists and exists_on_backend: + # No other services that require service router - delete + self.core_plugin.delete_service_router(context, router_id) + exists_on_backend = False + if exists_on_backend: + nsxlib.firewall_section.update(section_id, rules=fw_rules) def delete_port(self, context, port_id): # Mark the FW group as inactive if this is the last port diff --git a/vmware_nsx/services/lbaas/nsx_v3/implementation/loadbalancer_mgr.py b/vmware_nsx/services/lbaas/nsx_v3/implementation/loadbalancer_mgr.py index 0ac4a2d7e3..7ce95dd4f9 100644 --- a/vmware_nsx/services/lbaas/nsx_v3/implementation/loadbalancer_mgr.py +++ b/vmware_nsx/services/lbaas/nsx_v3/implementation/loadbalancer_mgr.py @@ -105,6 +105,15 @@ class EdgeLoadBalancerManagerFromDict(base_mgr.Nsxv3LoadbalancerBaseManager): raise n_exc.BadRequest(resource='lbaas-lb', msg=msg) nsx_db.delete_nsx_lbaas_loadbalancer_binding( context.session, lb['id']) + router_id = nsx_db.get_neutron_from_nsx_router_id( + context.session, nsx_router_id) + # Service router is needed only when the LB exist, and + # no other services are using it. + if not self.core_plugin.service_router_has_services( + context, + router_id): + self.core_plugin.delete_service_router(context, + router_id) completor(success=True) def refresh(self, context, lb): diff --git a/vmware_nsx/services/lbaas/nsx_v3/implementation/member_mgr.py b/vmware_nsx/services/lbaas/nsx_v3/implementation/member_mgr.py index c9739b6ccb..684cec55ed 100644 --- a/vmware_nsx/services/lbaas/nsx_v3/implementation/member_mgr.py +++ b/vmware_nsx/services/lbaas/nsx_v3/implementation/member_mgr.py @@ -166,6 +166,11 @@ class EdgeMemberManagerFromDict(base_mgr.Nsxv3LoadbalancerBaseManager): lb_size = lb_utils.get_lb_flavor_size( self.flavor_plugin, context, loadbalancer.get('flavor_id')) + if not self.core_plugin.service_router_has_services( + context, + router_id): + self.core_plugin.create_service_router(context, + router_id) lb_service = self._create_lb_service( context, service_client, member['tenant_id'], router_id, nsx_router_id, loadbalancer['id'], lb_size) diff --git a/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v2_driver.py b/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v2_driver.py index 28bf200351..265b8186f2 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v2_driver.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_fwaas_v2_driver.py @@ -211,6 +211,8 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): return_value=port),\ mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg', return_value=firewall),\ + mock.patch.object(self.plugin, 'service_router_has_services', + return_value=True),\ mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id", return_value=(FAKE_NSX_LS_ID, 0)),\ mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." @@ -245,7 +247,9 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): mock.patch.object(self.plugin, 'get_port', return_value=port),\ mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg', - return_value=firewall),\ + return_value=firewall), \ + mock.patch.object(self.plugin, 'service_router_has_services', + return_value=True), \ mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id", return_value=(FAKE_NSX_LS_ID, 0)),\ mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." @@ -300,7 +304,9 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): with mock.patch.object(self.plugin, '_get_router_interfaces', return_value=[port]),\ mock.patch.object(self.plugin, 'get_port', - return_value=port),\ + return_value=port), \ + mock.patch.object(self.plugin, 'service_router_has_services', + return_value=True), \ mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg', return_value=firewall),\ mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id", @@ -333,7 +339,9 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): with mock.patch.object(self.plugin, '_get_router_interfaces', return_value=[port]),\ mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg', - return_value=None),\ + return_value=None), \ + mock.patch.object(self.plugin, 'service_router_has_services', + return_value=True), \ mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id", return_value=(FAKE_NSX_LS_ID, 0)),\ mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." @@ -347,8 +355,10 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): apply_list = self._fake_apply_list() rule_list = self._fake_rules_v4() firewall = self._fake_firewall_group_with_admin_down(rule_list) - with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw: + with mock.patch.object(self.plugin, 'service_router_has_services', + return_value=True), \ + mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection" + ".update") as update_fw: self.firewall.create_firewall_group('nsx', apply_list, firewall) update_fw.assert_called_once_with( MOCK_SECTION_ID, @@ -366,7 +376,9 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): mock.patch.object(self.plugin, '_get_port_relay_servers', return_value=[relay_server]),\ mock.patch.object(self.plugin.fwaas_callbacks, 'get_port_fwg', - return_value=firewall),\ + return_value=firewall), \ + mock.patch.object(self.plugin, 'service_router_has_services', + return_value=True), \ mock.patch("vmware_nsx.db.db.get_nsx_switch_and_port_id", return_value=(FAKE_NSX_LS_ID, 0)),\ mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index 02e38fe05f..3966de211e 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -2594,6 +2594,10 @@ class TestL3NatTestCase(L3NatTest, return mock.patch("vmware_nsxlib.v3.router.RouterLib." "add_gw_snat_rule") + def _mock_add_remove_service_router(self): + return mock.patch("vmware_nsxlib.v3.router.RouterLib." + "update_router_edge_cluster") + def _mock_del_snat_rule(self): return mock.patch("vmware_nsxlib.v3.router.RouterLib." "delete_gw_snat_rule_by_source") @@ -2651,6 +2655,43 @@ class TestL3NatTestCase(L3NatTest, else: add_nat.assert_not_called() + def test_add_service_router_enable_snat(self): + with self.address_scope(name='as1') as addr_scope, \ + self._create_l3_ext_network() as ext_net: + ext_subnet = self._prepare_external_subnet_on_address_scope( + ext_net, addr_scope) + + # create a router with this gateway + with self.router() as r, \ + self._mock_add_remove_service_router() as change_sr: + router_id = r['router']['id'] + self._add_external_gateway_to_router( + router_id, ext_subnet['network_id']) + # Checking that update_edge_cluster is being called with + # edge_cluster_uuid, for creating a service router + self.assertIsNotNone(change_sr.call_args_list[0][0][1]) + + def test_remove_service_router_disable_snat(self): + with self.address_scope(name='as1') as addr_scope, \ + self._create_l3_ext_network() as ext_net: + ext_subnet = self._prepare_external_subnet_on_address_scope( + ext_net, addr_scope) + + # create a router with this gateway, disable snat + with self.router() as r: + self._add_external_gateway_to_router( + r['router']['id'], + ext_subnet['network_id']) + with self._mock_add_remove_service_router() as change_sr: + self._update_router_enable_snat( + r['router']['id'], + ext_subnet['network_id'], + False) + # Checking that update_edge_cluster is being called + # and setting edge_cluster_uuid to None, for service + # router removal. + self.assertIsNone(change_sr.call_args_list[0][0][1]) + def test_router_address_scope_snat_rules(self): """Test that if the router interface had the same address scope as the gateway - snat rule is not added. diff --git a/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py b/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py index c40c0b930a..17f95d0988 100644 --- a/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py +++ b/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py @@ -27,6 +27,7 @@ from vmware_nsx.services.lbaas.nsx_v3.v2 import lb_driver_v2 LB_VIP = '10.0.0.10' LB_ROUTER_ID = 'router-x' +ROUTER_ID = 'neutron-router-x' LB_ID = 'xxx-xxx' LB_TENANT_ID = 'yyy-yyy' LB_SERVICE_ID = 'service-1' @@ -277,6 +278,8 @@ class TestEdgeLbaasV2Loadbalancer(BaseTestEdgeLbaasV2): ) as mock_get_lb_service, \ mock.patch.object(self.service_client, 'delete' ) as mock_delete_lb_service, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(nsx_db, 'delete_nsx_lbaas_loadbalancer_binding' ) as mock_delete_lb_binding: mock_get_lb_binding.return_value = LB_BINDING @@ -285,6 +288,7 @@ class TestEdgeLbaasV2Loadbalancer(BaseTestEdgeLbaasV2): self.edge_driver.loadbalancer.delete(self.context, self.lb) mock_delete_lb_service.assert_called_with(LB_SERVICE_ID) + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID mock_delete_lb_binding.assert_called_with( self.context.session, LB_ID) mock_successful_completion = ( @@ -447,11 +451,14 @@ class TestEdgeLbaasV2Listener(BaseTestEdgeLbaasV2): ) as mock_remove_virtual_server, \ mock.patch.object(self.app_client, 'delete' ) as mock_delete_app_profile, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(self.vs_client, 'delete' ) as mock_delete_virtual_server, \ mock.patch.object(nsx_db, 'delete_nsx_lbaas_listener_binding', ) as mock_delete_listener_binding: mock_get_listener_binding.return_value = LISTENER_BINDING + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID mock_get_lb_binding.return_value = LB_BINDING mock_get_lb_service.return_value = { 'id': LB_SERVICE_ID, @@ -686,9 +693,12 @@ class TestEdgeLbaasV2Pool(BaseTestEdgeLbaasV2): ) as mock_delete_pool, \ mock.patch.object(nsx_db, 'delete_nsx_lbaas_pool_binding' ) as mock_delete_pool_binding, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(nsx_db, 'get_nsx_lbaas_loadbalancer_binding' ) as mock_get_lb_binding: mock_get_pool_binding.return_value = POOL_BINDING + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID mock_get_lb_binding.return_value = None self.edge_driver.pool.delete(self.context, self.pool) @@ -1090,11 +1100,14 @@ class TestEdgeLbaasV2Member(BaseTestEdgeLbaasV2): ) as mock_get_pool, \ mock.patch.object(lb_utils, 'get_network_from_subnet' ) as mock_get_network_from_subnet, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(self.pool_client, 'update_pool_with_members' ) as mock_update_pool_with_members: mock_get_pool_binding.return_value = POOL_BINDING mock_get_pool.return_value = LB_POOL_WITH_MEMBER mock_get_network_from_subnet.return_value = LB_NETWORK + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID self.edge_driver.member.delete(self.context, self.member) @@ -1199,6 +1212,8 @@ class TestEdgeLbaasV2HealthMonitor(BaseTestEdgeLbaasV2): ) as mock_get_monitor_binding, \ mock.patch.object(self.pool_client, 'remove_monitor_from_pool' ) as mock_remove_monitor_from_pool, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(self.monitor_client, 'delete' ) as mock_delete_monitor, \ mock.patch.object(nsx_db, 'delete_nsx_lbaas_monitor_binding' @@ -1209,6 +1224,7 @@ class TestEdgeLbaasV2HealthMonitor(BaseTestEdgeLbaasV2): mock_remove_monitor_from_pool.assert_called_with(LB_POOL_ID, LB_MONITOR_ID) + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID mock_delete_monitor.assert_called_with(LB_MONITOR_ID) mock_delete_monitor_binding.assert_called_with( self.context.session, LB_ID, POOL_ID, HM_ID) @@ -1311,14 +1327,18 @@ class TestEdgeLbaasV2L7Policy(BaseTestEdgeLbaasV2): ) as mock_vs_remove_rule, \ mock.patch.object(self.rule_client, 'delete' ) as mock_delete_rule, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(nsx_db, 'delete_nsx_lbaas_l7policy_binding' ) as mock_delete_l7policy_binding: mock_get_l7policy_binding.return_value = L7POLICY_BINDING + mock_get_neutron_from_nsx_router_id.return_value = LB_ROUTER_ID self.edge_driver.l7policy.delete(self.context, self.l7policy) mock_vs_remove_rule.assert_called_with(LB_VS_ID, LB_RULE_ID) mock_delete_rule.assert_called_with(LB_RULE_ID) + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID mock_delete_l7policy_binding.assert_called_with( self.context.session, L7POLICY_ID) mock_successful_completion = ( @@ -1429,6 +1449,8 @@ class TestEdgeLbaasV2L7Rule(BaseTestEdgeLbaasV2): ) as mock_get_l7policy_binding, \ mock.patch.object(nsx_db, 'get_nsx_lbaas_pool_binding' ) as mock_get_pool_binding, \ + mock.patch.object(nsx_db, 'get_neutron_from_nsx_router_id' + ) as mock_get_neutron_from_nsx_router_id, \ mock.patch.object(self.rule_client, 'update' ) as mock_update_rule: mock_get_l7policy_binding.return_value = L7POLICY_BINDING @@ -1438,6 +1460,7 @@ class TestEdgeLbaasV2L7Rule(BaseTestEdgeLbaasV2): mock_update_rule.assert_called_with(LB_RULE_ID, **delete_rule_body) + mock_get_neutron_from_nsx_router_id.router_id = ROUTER_ID mock_successful_completion = ( self.lbv2_driver.l7rule.successful_completion)