Merge "DVR to delete router namespaces for service ports"

This commit is contained in:
Jenkins 2014-09-22 23:13:54 +00:00 committed by Gerrit Code Review
commit 94a7c1ee5c
4 changed files with 37 additions and 45 deletions

View File

@ -110,7 +110,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
break
LOG.debug('DVR: dvr_update_router_addvm %s ', router_id)
def get_dvr_routers_by_vmportid(self, context, port_id):
def get_dvr_routers_by_portid(self, context, port_id):
"""Gets the dvr routers on vmport subnets."""
router_ids = set()
port_dict = self._core_plugin.get_port(context, port_id)
@ -153,9 +153,9 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
return True
return False
def dvr_deletens_if_no_vm(self, context, port_id):
"""Delete the DVR namespace if no VM exists."""
router_ids = self.get_dvr_routers_by_vmportid(context, port_id)
def dvr_deletens_if_no_port(self, context, port_id):
"""Delete the DVR namespace if no dvr serviced port exists."""
router_ids = self.get_dvr_routers_by_portid(context, port_id)
port_host = ml2_db.get_port_binding_host(port_id)
if not router_ids:
LOG.debug('No namespaces available for this DVR port %(port)s '
@ -165,16 +165,16 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
removed_router_info = []
for router_id in router_ids:
subnet_ids = self.get_subnet_ids_on_router(context, router_id)
vm_exists_on_subnet = False
port_exists_on_subnet = False
for subnet in subnet_ids:
if self.check_ports_active_on_host_and_subnet(context,
port_host,
port_id,
subnet):
vm_exists_on_subnet = True
port_exists_on_subnet = True
break
if vm_exists_on_subnet:
if port_exists_on_subnet:
continue
filter_rtr = {'device_id': [router_id],
'device_owner':

View File

@ -968,7 +968,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
network = self.get_network(context, port['network_id'])
mech_context = None
if port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE:
device_owner = port['device_owner']
if device_owner == const.DEVICE_OWNER_DVR_INTERFACE:
bindings = db.get_dvr_port_bindings(context.session, id)
for bind in bindings:
mech_context = driver_context.DvrPortContext(
@ -977,8 +978,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
else:
mech_context = driver_context.PortContext(self, context, port,
network, binding)
if "compute:" in port['device_owner'] and is_dvr_enabled:
router_info = l3plugin.dvr_deletens_if_no_vm(context, id)
if is_dvr_enabled and utils.is_dvr_serviced(device_owner):
router_info = l3plugin.dvr_deletens_if_no_port(context, id)
removed_routers += router_info
self.mechanism_manager.delete_port_precommit(mech_context)
self._delete_port_security_group_bindings(context, id)
@ -989,7 +990,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
l3plugin.dvr_vmarp_table_update(context, id, "del")
LOG.debug("Calling delete_port for %(port_id)s owned by %(owner)s"
% {"port_id": id, "owner": port['device_owner']})
% {"port_id": id, "owner": device_owner})
super(Ml2Plugin, self).delete_port(context, id)
# now that we've left db transaction, we are safe to notify

View File

@ -177,6 +177,9 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
self.assertTrue(utils.is_dvr_serviced(
constants.DEVICE_OWNER_LOADBALANCER))
def test_check_if_dhcp_port_serviced_by_dvr(self):
self.assertTrue(utils.is_dvr_serviced(constants.DEVICE_OWNER_DHCP))
def test_check_if_port_not_serviced_by_dvr(self):
self.assertFalse(utils.is_dvr_serviced(
constants.DEVICE_OWNER_ROUTER_INTF))
@ -205,61 +208,49 @@ class TestMl2DvrPortsV2(TestMl2PortsV2):
mock.PropertyMock(return_value=extensions))
self.service_plugins = {'L3_ROUTER_NAT': self.l3plugin}
def test_delete_last_vm_port(self):
fip_set = set()
ns_to_delete = {'host': 'vmhost', 'agent_id': 'vm_l3_agent',
def _test_delete_dvr_serviced_port(self, device_owner, floating_ip=False):
ns_to_delete = {'host': 'myhost', 'agent_id': 'vm_l3_agent',
'router_id': 'my_router'}
fip_set = set()
if floating_ip:
fip_set.add(ns_to_delete['router_id'])
with contextlib.nested(
mock.patch.object(manager.NeutronManager,
'get_service_plugins',
return_value=self.service_plugins),
self.port(do_delete=False, device_owner='compute:None'),
self.port(do_delete=False,
device_owner=device_owner),
mock.patch.object(self.l3plugin, 'notify_routers_updated'),
mock.patch.object(self.l3plugin, 'disassociate_floatingips',
return_value=fip_set),
mock.patch.object(self.l3plugin, 'dvr_deletens_if_no_vm',
mock.patch.object(self.l3plugin, 'dvr_deletens_if_no_port',
return_value=[ns_to_delete]),
mock.patch.object(self.l3plugin, 'remove_router_from_l3_agent')
) as (get_service_plugin, port, notify, disassociate_floatingips,
ddinv, remove_router_from_l3_agent):
dvr_delns_ifno_port, remove_router_from_l3_agent):
port_id = port['port']['id']
self.plugin.delete_port(self.context, port_id)
notify.assert_has_calls([mock.call(self.context, fip_set)])
dvr_delns_ifno_port.assert_called_once_with(self.context,
port['port']['id'])
remove_router_from_l3_agent.assert_has_calls([
mock.call(self.context, ns_to_delete['agent_id'],
ns_to_delete['router_id'])
])
def test_delete_last_vm_port(self):
self._test_delete_dvr_serviced_port(device_owner='compute:None')
def test_delete_last_vm_port_with_floatingip(self):
ns_to_delete = {'host': 'vmhost', 'agent_id': 'vm_l3_agent',
'router_id': 'my_router'}
fip_set = set([ns_to_delete['router_id']])
self._test_delete_dvr_serviced_port(device_owner='compute:None',
floating_ip=True)
with contextlib.nested(
mock.patch.object(manager.NeutronManager,
'get_service_plugins',
return_value=self.service_plugins),
self.port(do_delete=False, device_owner='compute:None'),
mock.patch.object(self.l3plugin, 'notify_routers_updated'),
mock.patch.object(self.l3plugin, 'disassociate_floatingips',
return_value=fip_set),
mock.patch.object(self.l3plugin, 'dvr_deletens_if_no_vm',
return_value=[ns_to_delete]),
mock.patch.object(self.l3plugin, 'remove_router_from_l3_agent')
) as (get_service_plugins, port, notify, disassociate_floatingips,
ddinv, remove_router_from_l3_agent):
port_id = port['port']['id']
self.plugin.delete_port(self.context, port_id)
notify.assert_has_calls([mock.call(self.context, fip_set)])
remove_router_from_l3_agent.assert_has_calls([
mock.call(self.context, ns_to_delete['agent_id'],
ns_to_delete['router_id'])
])
def test_delete_lbaas_vip_port(self):
self._test_delete_dvr_serviced_port(
device_owner=constants.DEVICE_OWNER_LOADBALANCER)
class TestMl2PortBinding(Ml2PluginV2TestCase,

View File

@ -822,7 +822,7 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
'.L3AgentNotifyAPI')):
self.dut.dvr_update_router_addvm(self.adminContext, port)
def test_get_dvr_routers_by_vmportid(self):
def test_get_dvr_routers_by_portid(self):
dvr_port = {
'id': 'dvr_port1',
'device_id': 'r1',
@ -844,8 +844,8 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
'.get_port', return_value=dvr_port),
mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
'.get_ports', return_value=[dvr_port])):
router_id = self.dut.get_dvr_routers_by_vmportid(self.adminContext,
dvr_port['id'])
router_id = self.dut.get_dvr_routers_by_portid(self.adminContext,
dvr_port['id'])
self.assertEqual(router_id.pop(), r1['id'])
def test_get_subnet_ids_on_router(self):