Endpoint level qos changes.
Get_endpoint_details rpc is modified to return qos config
for an ep.
Change-Id: I7ac94ad0140203d92c8834c84f40d6b28e8c753f
(cherry picked from commit 8656bae4b4)
			
			
This commit is contained in:
		@@ -26,6 +26,7 @@ from neutron.db.models import securitygroup as sg_models
 | 
			
		||||
from neutron.db.models import segment as segment_models
 | 
			
		||||
from neutron.db import models_v2
 | 
			
		||||
from neutron.db.port_security import models as psec_models
 | 
			
		||||
from neutron.db.qos import models as qos_models
 | 
			
		||||
from neutron.plugins.ml2 import models as ml2_models
 | 
			
		||||
from neutron.services.trunk import models as trunk_models
 | 
			
		||||
from neutron_lib.api.definitions import portbindings
 | 
			
		||||
@@ -104,6 +105,11 @@ EndpointSecurityGroupInfo = namedtuple(
 | 
			
		||||
    ['sg_id',
 | 
			
		||||
     'project_id'])
 | 
			
		||||
 | 
			
		||||
EndpointQosInfo = namedtuple(
 | 
			
		||||
    'EndpointQosInfo',
 | 
			
		||||
    ['qos_id',
 | 
			
		||||
     'project_id'])
 | 
			
		||||
 | 
			
		||||
EndpointDhcpIpInfo = namedtuple(
 | 
			
		||||
    'EndpointDhcpIpInfo',
 | 
			
		||||
    ['mac_address',
 | 
			
		||||
@@ -151,6 +157,10 @@ EndpointTrunkInfo = namedtuple(
 | 
			
		||||
     'segmentation_type',
 | 
			
		||||
     'segmentation_id'])
 | 
			
		||||
 | 
			
		||||
NEUTRON_INTERNAL_PORTS = (n_constants.DEVICE_OWNER_DHCP,
 | 
			
		||||
     n_constants.DEVICE_OWNER_ROUTER_INTF,
 | 
			
		||||
     n_constants.DEVICE_OWNER_ROUTER_GW)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TopologyRpcEndpoint(object):
 | 
			
		||||
 | 
			
		||||
@@ -365,6 +375,12 @@ class ApicRpcHandlerMixin(object):
 | 
			
		||||
                    info['sg_info'] = self._query_endpoint_sg_info(
 | 
			
		||||
                        session, port_info.port_id)
 | 
			
		||||
 | 
			
		||||
                    # Query for port's qos policy
 | 
			
		||||
                    info['qos_info'] = []
 | 
			
		||||
                    if port_info.device_owner not in NEUTRON_INTERNAL_PORTS:
 | 
			
		||||
                        info['qos_info'] = self._query_endpoint_qos_info(
 | 
			
		||||
                            session, port_info.port_id)
 | 
			
		||||
 | 
			
		||||
                    # Query for list of state associated with each
 | 
			
		||||
                    # DHCP IP on the port's network.
 | 
			
		||||
                    info['dhcp_ip_info'] = self._query_endpoint_dhcp_ip_info(
 | 
			
		||||
@@ -608,6 +624,22 @@ class ApicRpcHandlerMixin(object):
 | 
			
		||||
                query(session).params(
 | 
			
		||||
                    port_id=port_id)]
 | 
			
		||||
 | 
			
		||||
    def _query_endpoint_qos_info(self, session, port_id):
 | 
			
		||||
        query = BAKERY(lambda s: s.query(
 | 
			
		||||
            qos_models.QosPolicy.id,
 | 
			
		||||
            qos_models.QosPolicy.project_id,
 | 
			
		||||
        ))
 | 
			
		||||
        query += lambda q: q.join(
 | 
			
		||||
            qos_models.QosPortPolicyBinding,
 | 
			
		||||
            qos_models.QosPortPolicyBinding.policy_id ==
 | 
			
		||||
            qos_models.QosPolicy.id)
 | 
			
		||||
        query += lambda q: q.filter(
 | 
			
		||||
            qos_models.QosPortPolicyBinding.port_id ==
 | 
			
		||||
            sa.bindparam('port_id'))
 | 
			
		||||
        return [EndpointQosInfo._make(row) for row in
 | 
			
		||||
                query(session).params(
 | 
			
		||||
                    port_id=port_id)]
 | 
			
		||||
 | 
			
		||||
    def _query_endpoint_dhcp_ip_info(self, session, network_id):
 | 
			
		||||
        query = BAKERY(lambda s: s.query(
 | 
			
		||||
            models_v2.Port.mac_address,
 | 
			
		||||
@@ -938,6 +970,8 @@ class ApicRpcHandlerMixin(object):
 | 
			
		||||
            if not (vif_details and vif_details.get('port_filter') and
 | 
			
		||||
                    vif_details.get('ovs_hybrid_plug')):
 | 
			
		||||
                details['security_group'] = self._build_sg_details(info)
 | 
			
		||||
        if info['qos_info']:
 | 
			
		||||
            details['qos_policy'] = self._build_qos_details(info)
 | 
			
		||||
        details['subnets'] = self._build_subnet_details(info)
 | 
			
		||||
        details['vm-name'] = (port_info.vm_name if
 | 
			
		||||
                              port_info.device_owner.startswith('compute:') and
 | 
			
		||||
@@ -1077,6 +1111,11 @@ class ApicRpcHandlerMixin(object):
 | 
			
		||||
              'name': sg.sg_id} for sg in info['sg_info']] +
 | 
			
		||||
            [{'policy-space': 'common', 'name': self._default_sg_name}])
 | 
			
		||||
 | 
			
		||||
    def _build_qos_details(self, info):
 | 
			
		||||
        return (
 | 
			
		||||
            [{'policy-space': self.name_mapper.project(None, qos.project_id),
 | 
			
		||||
              'name': qos.qos_id} for qos in info['qos_info']][0])
 | 
			
		||||
 | 
			
		||||
    def _build_subnet_details(self, info):
 | 
			
		||||
        ip_info = info['ip_info']
 | 
			
		||||
        dhcp_ip_info = info['dhcp_ip_info']
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,10 @@ import mock
 | 
			
		||||
 | 
			
		||||
# from aim.api import infra as aim_infra
 | 
			
		||||
from aim.api import resource as aim_res
 | 
			
		||||
from gbpservice.neutron.tests.unit.plugins.ml2plus import (
 | 
			
		||||
    test_apic_aim as test_aim_md)
 | 
			
		||||
from gbpservice.neutron.tests.unit.services.grouppolicy import (
 | 
			
		||||
    test_aim_mapping_driver as test_aim_base)
 | 
			
		||||
 | 
			
		||||
from neutron.objects.qos import policy as policy_object
 | 
			
		||||
from neutron.objects.qos import rule as rule_object
 | 
			
		||||
from neutron_lib import context
 | 
			
		||||
@@ -46,6 +47,7 @@ class TestAIMQosBase(test_aim_base.AIMBaseTestCase):
 | 
			
		||||
        super(TestAIMQosBase, self).setUp(
 | 
			
		||||
            *args, ml2_options=ml2_options, qos_plugin='qos', **kwargs)
 | 
			
		||||
        self._plugin = directory.get_plugin()
 | 
			
		||||
        self.plugin = self._plugin
 | 
			
		||||
        self._plugin.remove_networks_from_down_agents = mock.Mock()
 | 
			
		||||
        self._plugin.is_agent_down = mock.Mock(return_value=False)
 | 
			
		||||
        self._ctx = context.get_admin_context()
 | 
			
		||||
@@ -185,6 +187,23 @@ class TestQosPolicy(TestAIMQosBase):
 | 
			
		||||
        epg = self.aim_mgr.get(self._aim_context, epg)
 | 
			
		||||
        self.assertIsNone(epg.qos_name)
 | 
			
		||||
 | 
			
		||||
    def test_port_qos_gbpDetailsForML2(self):
 | 
			
		||||
        self._register_agent('host1', test_aim_md.AGENT_CONF_OPFLEX)
 | 
			
		||||
        net = self._make_network(self.fmt, 'net1', True)
 | 
			
		||||
        self._make_subnet(self.fmt, net, '10.0.1.1', '10.0.1.0/24')
 | 
			
		||||
        qosPolicy = self._make_qos_policy()
 | 
			
		||||
        qosPort = self._make_port(self.fmt,
 | 
			
		||||
                                  net['network']['id'],
 | 
			
		||||
                                  None, arg_list=('qos_policy_id',),
 | 
			
		||||
                                  qos_policy_id=qosPolicy.id)
 | 
			
		||||
        self._bind_port_to_host(qosPort['port']['id'], 'host1')
 | 
			
		||||
 | 
			
		||||
        mapping = self.aim_mech.get_gbp_details(
 | 
			
		||||
            self._neutron_admin_context,
 | 
			
		||||
            device='tap%s' % qosPort['port']['id'],
 | 
			
		||||
            host='host1')
 | 
			
		||||
        self.assertEqual(qosPolicy.id, mapping['qos_policy']['name'])
 | 
			
		||||
 | 
			
		||||
    def _test_invalid_network_exception(self, kwargs):
 | 
			
		||||
        # Verify creating network with QoS fails
 | 
			
		||||
        net_qos_obj = self._make_qos_policy()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user