DVR to delete router namespaces for service ports
Earlier merge that enabled LBaaS in DVR with review #114141 had not covered the removal of DVR router namespace on VIP Port deletion in ml2 plugin. Here we fix the ml2 plugin to attempt namespace removal for all dvr serviced ports. Change-Id: Ie7930ebedb12212886d45294132fefff7296e104 Closes-Bug: #1364839
This commit is contained in:
parent
e6c81f1bd2
commit
a58ef4cc62
@ -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':
|
||||
|
@ -964,7 +964,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(
|
||||
@ -973,8 +974,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)
|
||||
@ -985,7 +986,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
|
||||
|
@ -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,
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user