Merge "DVR to delete router namespaces for service ports"
This commit is contained in:
commit
496ab8481f
|
@ -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':
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue