Merge "Get rid of DVR override of remove_router_interface"

This commit is contained in:
Jenkins 2016-12-12 13:40:54 +00:00 committed by Gerrit Code Review
commit c3e0a5c4f8
4 changed files with 37 additions and 26 deletions

View File

@ -931,12 +931,12 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
port_type=owner
)
try:
port_db = qry.one().port
except exc.NoResultFound:
port = self._core_plugin.get_port(context, qry.one().port_id)
except (n_exc.PortNotFound, exc.NoResultFound):
raise l3.RouterInterfaceNotFound(router_id=router_id,
port_id=port_id)
port_subnet_ids = [fixed_ip['subnet_id']
for fixed_ip in port_db['fixed_ips']]
for fixed_ip in port['fixed_ips']]
if subnet_id and subnet_id not in port_subnet_ids:
raise n_exc.SubnetMismatchForPort(
port_id=port_id, subnet_id=subnet_id)
@ -945,9 +945,9 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
for port_subnet_id in port_subnet_ids:
self._confirm_router_interface_not_in_use(
context, router_id, port_subnet_id)
self._core_plugin.delete_port(context, port_db['id'],
self._core_plugin.delete_port(context, port['id'],
l3_port_check=False)
return (port_db, subnets)
return (port, subnets)
def _remove_interface_by_subnet(self, context,
router_id, subnet_id, owner):
@ -965,6 +965,10 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
)
for p in ports:
try:
p = self._core_plugin.get_port(context, p.id)
except n_exc.PortNotFound:
continue
port_subnets = [fip['subnet_id'] for fip in p['fixed_ips']]
if subnet_id in port_subnets and len(port_subnets) > 1:
# multiple prefix port - delete prefix from port
@ -1017,7 +1021,9 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
cidrs=[x['cidr'] for x in subnets],
network_id=gw_network_id,
gateway_ips=gw_ips,
port=port)
port=port,
router_id=router_id,
interface_info=interface_info)
return self._make_router_interface_info(router_id, port['tenant_id'],
port['id'], port['network_id'],
subnets[0]['id'],

View File

@ -87,6 +87,8 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
resources.ROUTER_INTERFACE, events.BEFORE_CREATE)
registry.subscribe(n._update_snat_v6_addrs_after_intf_update,
resources.ROUTER_INTERFACE, events.AFTER_CREATE)
registry.subscribe(n._cleanup_after_interface_removal,
resources.ROUTER_INTERFACE, events.AFTER_DELETE)
return n
def _set_distributed_flag(self, resource, event, trigger, context,
@ -412,24 +414,24 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
return False
@db_api.retry_if_session_inactive()
def remove_router_interface(self, context, router_id, interface_info):
def _cleanup_after_interface_removal(self, resource, event, trigger,
context, port, interface_info,
router_id, **kwargs):
"""Handler to cleanup distributed resources after intf removal."""
router = self._get_router(context, router_id)
if not router.extra_attributes.distributed:
return super(
L3_NAT_with_dvr_db_mixin, self).remove_router_interface(
context, router_id, interface_info)
return
plugin = directory.get_plugin(const.L3)
router_hosts_before = plugin._get_dvr_hosts_for_router(
context, router_id)
interface_info = super(
L3_NAT_with_dvr_db_mixin, self).remove_router_interface(
context, router_id, interface_info)
# we calculate which hosts to notify by checking the hosts for
# the removed port's subnets and then subtract out any hosts still
# hosting the router for the remaining interfaces
router_hosts_for_removed = plugin._get_dvr_hosts_for_subnets(
context, subnet_ids={ip['subnet_id'] for ip in port['fixed_ips']})
router_hosts_after = plugin._get_dvr_hosts_for_router(
context, router_id)
removed_hosts = set(router_hosts_before) - set(router_hosts_after)
removed_hosts = set(router_hosts_for_removed) - set(router_hosts_after)
if removed_hosts:
agents = plugin.get_l3_agents(context,
filters={'host': removed_hosts})
@ -442,18 +444,16 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
if not is_this_snat_agent:
self.l3_rpc_notifier.router_removed_from_agent(
context, router_id, agent['host'])
# if subnet_id not in interface_info, request was to remove by port
sub_id = (interface_info.get('subnet_id') or
port['fixed_ips'][0]['subnet_id'])
is_multiple_prefix_csport = (
self._check_for_multiprefix_csnat_port_and_update(
context, router, interface_info['network_id'],
interface_info['subnet_id']))
context, router, port['network_id'], sub_id))
if not is_multiple_prefix_csport:
# Single prefix port - go ahead and delete the port
self.delete_csnat_router_interface_ports(
context.elevated(), router,
subnet_id=interface_info['subnet_id'])
return interface_info
context.elevated(), router, subnet_id=sub_id)
def _get_snat_sync_interfaces(self, context, router_ids):
"""Query router interfaces that relate to list of router_ids."""

View File

@ -228,6 +228,12 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
are bound
"""
subnet_ids = self.get_subnet_ids_on_router(context, router_id)
hosts = self._get_dvr_hosts_for_subnets(context, subnet_ids)
LOG.debug('Hosts for router %s: %s', router_id, hosts)
return hosts
def _get_dvr_hosts_for_subnets(self, context, subnet_ids):
"""Get a list of hosts with DVR servicable ports on subnet_ids."""
Binding = ml2_models.PortBinding
Port = models_v2.Port
IPAllocation = models_v2.IPAllocation
@ -242,7 +248,6 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
n_utils.get_other_dvr_serviced_device_owners()))
query = query.filter(owner_filter)
hosts = [item[0] for item in query]
LOG.debug('Hosts for router %s: %s', router_id, hosts)
return hosts
def _get_dvr_subnet_ids_on_host_query(self, context, host):

View File

@ -1523,7 +1523,7 @@ class L3DvrTestCase(L3DvrTestCaseBase):
{'subnet_id': subnet['subnet']['id']})
l3_notifier.router_removed_from_agent.assert_called_once_with(
self.context, router['id'], HOST1)
mock.ANY, router['id'], HOST1)
def test_router_auto_scheduling(self):
router = self._create_router()