Merge "Optimize get_ports_on_host_by_subnet() dvr rpc handler"

This commit is contained in:
Jenkins 2016-01-21 13:58:31 +00:00 committed by Gerrit Code Review
commit 424e6e4711
2 changed files with 50 additions and 17 deletions

View File

@ -18,12 +18,15 @@ from oslo_db import exception as db_exc
from oslo_log import helpers as log_helpers from oslo_log import helpers as log_helpers
from oslo_log import log as logging from oslo_log import log as logging
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy import or_
from sqlalchemy.orm import exc from sqlalchemy.orm import exc
from neutron._i18n import _, _LE from neutron._i18n import _, _LE
from neutron.common import constants
from neutron.common import exceptions as n_exc from neutron.common import exceptions as n_exc
from neutron.common import utils from neutron.common import utils
from neutron.db import model_base from neutron.db import model_base
from neutron.db import models_v2
from neutron.extensions import dvr as ext_dvr from neutron.extensions import dvr as ext_dvr
from neutron.extensions import portbindings from neutron.extensions import portbindings
from neutron import manager from neutron import manager
@ -134,26 +137,24 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
:param subnet: subnet id to match and extract ports of interest :param subnet: subnet id to match and extract ports of interest
:returns list -- Ports on the given subnet in the input host :returns list -- Ports on the given subnet in the input host
""" """
# FIXME(vivek, salv-orlando): improve this query by adding the filters = {'fixed_ips': {'subnet_id': [subnet]},
# capability of filtering by binding:host_id portbindings.HOST_ID: [host]}
ports_by_host = [] ports_query = self.plugin._get_ports_query(context, filters=filters)
filter = {'fixed_ips': {'subnet_id': [subnet]}} owner_filter = or_(
ports = self.plugin.get_ports(context, filters=filter) models_v2.Port.device_owner.startswith(
LOG.debug("List of Ports on subnet %(subnet)s at host %(host)s " constants.DEVICE_OWNER_COMPUTE_PREFIX),
"received as %(ports)s", models_v2.Port.device_owner.in_(
{'subnet': subnet, 'host': host, 'ports': ports}) utils.get_other_dvr_serviced_device_owners()))
for port in ports: ports_query = ports_query.filter(owner_filter)
device_owner = port['device_owner'] ports = [
if (utils.is_dvr_serviced(device_owner)): self.plugin._make_port_dict(port, process_extensions=False)
if port[portbindings.HOST_ID] == host: for port in ports_query.all()
port_dict = self.plugin._make_port_dict(port, ]
process_extensions=False)
ports_by_host.append(port_dict)
LOG.debug("Returning list of dvr serviced ports on host %(host)s" LOG.debug("Returning list of dvr serviced ports on host %(host)s"
" for subnet %(subnet)s ports %(ports)s", " for subnet %(subnet)s ports %(ports)s",
{'host': host, 'subnet': subnet, {'host': host, 'subnet': subnet,
'ports': ports_by_host}) 'ports': ports})
return ports_by_host return ports
@log_helpers.log_method_call @log_helpers.log_method_call
def get_subnet_for_dvr(self, context, subnet, fixed_ips=None): def get_subnet_for_dvr(self, context, subnet, fixed_ips=None):

View File

@ -16,9 +16,11 @@
import mock import mock
from oslo_config import cfg from oslo_config import cfg
from neutron.common import constants
from neutron import context from neutron import context
from neutron.db import dvr_mac_db from neutron.db import dvr_mac_db
from neutron.extensions import dvr from neutron.extensions import dvr
from neutron.extensions import portbindings
from neutron.tests.unit.plugins.ml2 import test_plugin from neutron.tests.unit.plugins.ml2 import test_plugin
@ -127,3 +129,33 @@ class DvrDbMixinTestCase(test_plugin.Ml2PluginV2TestCase):
self.ctx, subnet['subnet']['id'], fixed_ips) self.ctx, subnet['subnet']['id'], fixed_ips)
self.assertEqual(gw_port['port']['mac_address'], self.assertEqual(gw_port['port']['mac_address'],
dvr_subnet['gateway_mac']) dvr_subnet['gateway_mac'])
def test_get_ports_on_host_by_subnet(self):
HOST = 'host1'
host_arg = {portbindings.HOST_ID: HOST}
arg_list = (portbindings.HOST_ID,)
with self.subnet() as subnet,\
self.port(subnet=subnet,
device_owner=constants.DEVICE_OWNER_COMPUTE_PREFIX,
arg_list=arg_list, **host_arg) as compute_port,\
self.port(subnet=subnet,
device_owner=constants.DEVICE_OWNER_DHCP,
arg_list=arg_list, **host_arg) as dhcp_port,\
self.port(subnet=subnet,
device_owner=constants.DEVICE_OWNER_LOADBALANCER,
arg_list=arg_list, **host_arg) as lb_port,\
self.port(device_owner=constants.DEVICE_OWNER_COMPUTE_PREFIX,
arg_list=arg_list, **host_arg),\
self.port(subnet=subnet,
device_owner=constants.DEVICE_OWNER_COMPUTE_PREFIX,
arg_list=arg_list,
**{portbindings.HOST_ID: 'other'}),\
self.port(subnet=subnet,
device_owner=constants.DEVICE_OWNER_NETWORK_PREFIX,
arg_list=arg_list, **host_arg):
expected_ids = [port['port']['id'] for port in
[compute_port, dhcp_port, lb_port]]
dvr_ports = self.mixin.get_ports_on_host_by_subnet(
self.ctx, HOST, subnet['subnet']['id'])
self.assertEqual(len(expected_ids), len(dvr_ports))
self.assertEqual(expected_ids, [port['id'] for port in dvr_ports])