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 496ab8481f
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 break
LOG.debug('DVR: dvr_update_router_addvm %s ', router_id) 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.""" """Gets the dvr routers on vmport subnets."""
router_ids = set() router_ids = set()
port_dict = self._core_plugin.get_port(context, port_id) 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 True
return False return False
def dvr_deletens_if_no_vm(self, context, port_id): def dvr_deletens_if_no_port(self, context, port_id):
"""Delete the DVR namespace if no VM exists.""" """Delete the DVR namespace if no dvr serviced port exists."""
router_ids = self.get_dvr_routers_by_vmportid(context, port_id) router_ids = self.get_dvr_routers_by_portid(context, port_id)
port_host = ml2_db.get_port_binding_host(port_id) port_host = ml2_db.get_port_binding_host(port_id)
if not router_ids: if not router_ids:
LOG.debug('No namespaces available for this DVR port %(port)s ' 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 = [] removed_router_info = []
for router_id in router_ids: for router_id in router_ids:
subnet_ids = self.get_subnet_ids_on_router(context, router_id) 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: for subnet in subnet_ids:
if self.check_ports_active_on_host_and_subnet(context, if self.check_ports_active_on_host_and_subnet(context,
port_host, port_host,
port_id, port_id,
subnet): subnet):
vm_exists_on_subnet = True port_exists_on_subnet = True
break break
if vm_exists_on_subnet: if port_exists_on_subnet:
continue continue
filter_rtr = {'device_id': [router_id], filter_rtr = {'device_id': [router_id],
'device_owner': 'device_owner':

View File

@ -968,7 +968,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
network = self.get_network(context, port['network_id']) network = self.get_network(context, port['network_id'])
mech_context = None 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) bindings = db.get_dvr_port_bindings(context.session, id)
for bind in bindings: for bind in bindings:
mech_context = driver_context.DvrPortContext( mech_context = driver_context.DvrPortContext(
@ -977,8 +978,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
else: else:
mech_context = driver_context.PortContext(self, context, port, mech_context = driver_context.PortContext(self, context, port,
network, binding) network, binding)
if "compute:" in port['device_owner'] and is_dvr_enabled: if is_dvr_enabled and utils.is_dvr_serviced(device_owner):
router_info = l3plugin.dvr_deletens_if_no_vm(context, id) router_info = l3plugin.dvr_deletens_if_no_port(context, id)
removed_routers += router_info removed_routers += router_info
self.mechanism_manager.delete_port_precommit(mech_context) self.mechanism_manager.delete_port_precommit(mech_context)
self._delete_port_security_group_bindings(context, id) 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") l3plugin.dvr_vmarp_table_update(context, id, "del")
LOG.debug("Calling delete_port for %(port_id)s owned by %(owner)s" 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) super(Ml2Plugin, self).delete_port(context, id)
# now that we've left db transaction, we are safe to notify # 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( self.assertTrue(utils.is_dvr_serviced(
constants.DEVICE_OWNER_LOADBALANCER)) 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): def test_check_if_port_not_serviced_by_dvr(self):
self.assertFalse(utils.is_dvr_serviced( self.assertFalse(utils.is_dvr_serviced(
constants.DEVICE_OWNER_ROUTER_INTF)) constants.DEVICE_OWNER_ROUTER_INTF))
@ -205,61 +208,49 @@ class TestMl2DvrPortsV2(TestMl2PortsV2):
mock.PropertyMock(return_value=extensions)) mock.PropertyMock(return_value=extensions))
self.service_plugins = {'L3_ROUTER_NAT': self.l3plugin} self.service_plugins = {'L3_ROUTER_NAT': self.l3plugin}
def test_delete_last_vm_port(self): def _test_delete_dvr_serviced_port(self, device_owner, floating_ip=False):
fip_set = set() ns_to_delete = {'host': 'myhost', 'agent_id': 'vm_l3_agent',
ns_to_delete = {'host': 'vmhost', 'agent_id': 'vm_l3_agent',
'router_id': 'my_router'} 'router_id': 'my_router'}
fip_set = set()
if floating_ip:
fip_set.add(ns_to_delete['router_id'])
with contextlib.nested( with contextlib.nested(
mock.patch.object(manager.NeutronManager, mock.patch.object(manager.NeutronManager,
'get_service_plugins', 'get_service_plugins',
return_value=self.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, 'notify_routers_updated'),
mock.patch.object(self.l3plugin, 'disassociate_floatingips', mock.patch.object(self.l3plugin, 'disassociate_floatingips',
return_value=fip_set), 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]), return_value=[ns_to_delete]),
mock.patch.object(self.l3plugin, 'remove_router_from_l3_agent') mock.patch.object(self.l3plugin, 'remove_router_from_l3_agent')
) as (get_service_plugin, port, notify, disassociate_floatingips, ) 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'] port_id = port['port']['id']
self.plugin.delete_port(self.context, port_id) self.plugin.delete_port(self.context, port_id)
notify.assert_has_calls([mock.call(self.context, fip_set)]) 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([ remove_router_from_l3_agent.assert_has_calls([
mock.call(self.context, ns_to_delete['agent_id'], mock.call(self.context, ns_to_delete['agent_id'],
ns_to_delete['router_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): def test_delete_last_vm_port_with_floatingip(self):
ns_to_delete = {'host': 'vmhost', 'agent_id': 'vm_l3_agent', self._test_delete_dvr_serviced_port(device_owner='compute:None',
'router_id': 'my_router'} floating_ip=True)
fip_set = set([ns_to_delete['router_id']])
with contextlib.nested( def test_delete_lbaas_vip_port(self):
mock.patch.object(manager.NeutronManager, self._test_delete_dvr_serviced_port(
'get_service_plugins', device_owner=constants.DEVICE_OWNER_LOADBALANCER)
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'])
])
class TestMl2PortBinding(Ml2PluginV2TestCase, class TestMl2PortBinding(Ml2PluginV2TestCase,

View File

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