rehome qos service DriverBase class
The neutron.services.qos.drivers.base.DriverBase class is used by a number of consumers [1]. This patch rehomes it into neutron_lib along with the qos_consts that are also used by consumers [2]. UTs and a release note are also included. [1] http://codesearch.openstack.org/?q=from%20neutron%5C.services%5C.qos%5C.drivers%20import%20base [2] http://codesearch.openstack.org/?q=from%20neutron%5C.services%5C.qos%20import%20qos_consts Change-Id: Ifaf4657c37791e8e11907c66fb6cab7128c122a6
This commit is contained in:
		
							
								
								
									
										0
									
								
								neutron_lib/services/qos/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								neutron_lib/services/qos/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										162
									
								
								neutron_lib/services/qos/base.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								neutron_lib/services/qos/base.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					# Copyright 2016 Hewlett Packard Enterprise Development Company, LP
 | 
				
			||||||
 | 
					# Copyright 2016 Red Hat Inc.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# All Rights Reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					# not use this file except in compliance with the License. You may obtain
 | 
				
			||||||
 | 
					# a copy of the License at
 | 
				
			||||||
 | 
					# http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
				
			||||||
 | 
					# License for the specific language governing permissions and limitations
 | 
				
			||||||
 | 
					# under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from oslo_log import log as logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from neutron_lib.api import validators as lib_validators
 | 
				
			||||||
 | 
					from neutron_lib.callbacks import events
 | 
				
			||||||
 | 
					from neutron_lib.callbacks import registry
 | 
				
			||||||
 | 
					from neutron_lib.services.qos import constants
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOG = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@registry.has_registry_receivers
 | 
				
			||||||
 | 
					class DriverBase(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, name, vif_types, vnic_types,
 | 
				
			||||||
 | 
					                 supported_rules,
 | 
				
			||||||
 | 
					                 requires_rpc_notifications=False):
 | 
				
			||||||
 | 
					        """Instantiate a qos driver.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: driver name.
 | 
				
			||||||
 | 
					        :param vif_types: list of interfaces (VIFs) supported.
 | 
				
			||||||
 | 
					        :param vnic_types: list of vnic types supported.
 | 
				
			||||||
 | 
					        :param supported_rules: dict of supported rules.
 | 
				
			||||||
 | 
					        :param requires_rpc_notifications: indicates if this driver
 | 
				
			||||||
 | 
					               expects rpc push notifications to be sent from the driver.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        self.vif_types = vif_types
 | 
				
			||||||
 | 
					        self.vnic_types = vnic_types
 | 
				
			||||||
 | 
					        self.supported_rules = supported_rules
 | 
				
			||||||
 | 
					        self.requires_rpc_notifications = requires_rpc_notifications
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @registry.receives(constants.QOS_PLUGIN, [events.AFTER_INIT])
 | 
				
			||||||
 | 
					    def _register(self, resource, event, trigger, **kwargs):
 | 
				
			||||||
 | 
					        if self.is_loaded:
 | 
				
			||||||
 | 
					            # trigger is the QosServiceDriverManager
 | 
				
			||||||
 | 
					            trigger.register_driver(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_loaded(self):
 | 
				
			||||||
 | 
					        """True if the driver is active for the Neutron Server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Implement this property to determine if your driver is actively
 | 
				
			||||||
 | 
					        configured for this Neutron Server deployment.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_vif_type_compatible(self, vif_type):
 | 
				
			||||||
 | 
					        """True if the driver is compatible with the VIF type."""
 | 
				
			||||||
 | 
					        return vif_type in self.vif_types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_vnic_compatible(self, vnic_type):
 | 
				
			||||||
 | 
					        """True if the driver is compatible with the specific VNIC type."""
 | 
				
			||||||
 | 
					        return vnic_type in self.vnic_types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_rule_supported(self, rule):
 | 
				
			||||||
 | 
					        supported_parameters = self.supported_rules.get(rule.rule_type)
 | 
				
			||||||
 | 
					        if not supported_parameters:
 | 
				
			||||||
 | 
					            LOG.debug("Rule type %(rule_type)s is not supported by "
 | 
				
			||||||
 | 
					                      "%(driver_name)s",
 | 
				
			||||||
 | 
					                      {'rule_type': rule.rule_type,
 | 
				
			||||||
 | 
					                       'driver_name': self.name})
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        for parameter, validators in supported_parameters.items():
 | 
				
			||||||
 | 
					            parameter_value = rule.get(parameter)
 | 
				
			||||||
 | 
					            for validator_type, validator_data in validators.items():
 | 
				
			||||||
 | 
					                validator_function = lib_validators.get_validator(
 | 
				
			||||||
 | 
					                    validator_type)
 | 
				
			||||||
 | 
					                validate_result = validator_function(parameter_value,
 | 
				
			||||||
 | 
					                                                     validator_data)
 | 
				
			||||||
 | 
					                # NOTE(slaweq): validator functions returns None if data is
 | 
				
			||||||
 | 
					                # valid or string with reason why data is not valid
 | 
				
			||||||
 | 
					                if validate_result:
 | 
				
			||||||
 | 
					                    LOG.debug("Parameter %(parameter)s=%(value)s in "
 | 
				
			||||||
 | 
					                              "rule type %(rule_type)s is not "
 | 
				
			||||||
 | 
					                              "supported by %(driver_name)s. "
 | 
				
			||||||
 | 
					                              "Validate result: %(validate_result)s",
 | 
				
			||||||
 | 
					                              {'parameter': parameter,
 | 
				
			||||||
 | 
					                               'value': parameter_value,
 | 
				
			||||||
 | 
					                               'rule_type': rule.rule_type,
 | 
				
			||||||
 | 
					                               'driver_name': self.name,
 | 
				
			||||||
 | 
					                               'validate_result': validate_result})
 | 
				
			||||||
 | 
					                    return False
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def create_policy(self, context, policy):
 | 
				
			||||||
 | 
					        """Create policy invocation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This method can be implemented by the specific driver subclass
 | 
				
			||||||
 | 
					        to update the backend where necessary with the specific policy
 | 
				
			||||||
 | 
					        information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param context: current running context information
 | 
				
			||||||
 | 
					        :param policy: a QoSPolicy object being created, which will have no
 | 
				
			||||||
 | 
					                      rules.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def create_policy_precommit(self, context, policy):
 | 
				
			||||||
 | 
					        """Create policy precommit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This method can be implemented by the specific driver subclass
 | 
				
			||||||
 | 
					        to handle the precommit event of a policy that is being created.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param context: current running context information
 | 
				
			||||||
 | 
					        :param policy: a QoSPolicy object being created, which will have no
 | 
				
			||||||
 | 
					                      rules.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update_policy(self, context, policy):
 | 
				
			||||||
 | 
					        """Update policy invocation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This method can be implemented by the specific driver subclass
 | 
				
			||||||
 | 
					        to update the backend where necessary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param context: current running context information
 | 
				
			||||||
 | 
					        :param policy: a QoSPolicy object being updated.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update_policy_precommit(self, context, policy):
 | 
				
			||||||
 | 
					        """Update policy precommit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This method can be implemented by the specific driver subclass
 | 
				
			||||||
 | 
					        to handle update precommit event of a policy that is being updated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param context: current running context information
 | 
				
			||||||
 | 
					        :param policy: a QoSPolicy object being updated.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def delete_policy(self, context, policy):
 | 
				
			||||||
 | 
					        """Delete policy invocation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This method can be implemented by the specific driver subclass
 | 
				
			||||||
 | 
					        to delete the backend policy where necessary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param context: current running context information
 | 
				
			||||||
 | 
					        :param policy: a QoSPolicy object being deleted
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def delete_policy_precommit(self, context, policy):
 | 
				
			||||||
 | 
					        """Delete policy precommit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This method can be implemented by the specific driver subclass
 | 
				
			||||||
 | 
					        to handle delete precommit event of a policy that is being deleted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param context: current running context information
 | 
				
			||||||
 | 
					        :param policy: a QoSPolicy object being deleted
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
							
								
								
									
										56
									
								
								neutron_lib/services/qos/constants.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								neutron_lib/services/qos/constants.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					# Copyright (c) 2015 Red Hat Inc.
 | 
				
			||||||
 | 
					# All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					#    not use this file except in compliance with the License. You may obtain
 | 
				
			||||||
 | 
					#    a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
				
			||||||
 | 
					#    License for the specific language governing permissions and limitations
 | 
				
			||||||
 | 
					#    under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth_limit'
 | 
				
			||||||
 | 
					RULE_TYPE_DSCP_MARKING = 'dscp_marking'
 | 
				
			||||||
 | 
					RULE_TYPE_MINIMUM_BANDWIDTH = 'minimum_bandwidth'
 | 
				
			||||||
 | 
					VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT,
 | 
				
			||||||
 | 
					                    RULE_TYPE_DSCP_MARKING,
 | 
				
			||||||
 | 
					                    RULE_TYPE_MINIMUM_BANDWIDTH,
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Names of rules' attributes
 | 
				
			||||||
 | 
					MAX_KBPS = "max_kbps"
 | 
				
			||||||
 | 
					MAX_BURST = "max_burst_kbps"
 | 
				
			||||||
 | 
					MIN_KBPS = "min_kbps"
 | 
				
			||||||
 | 
					DIRECTION = "direction"
 | 
				
			||||||
 | 
					DSCP_MARK = "dscp_mark"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOS_POLICY_ID = 'qos_policy_id'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOS_PLUGIN = 'qos_plugin'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# NOTE(slaweq): Value used to calculate burst value for egress bandwidth limit
 | 
				
			||||||
 | 
					# if burst is not given by user. In such case burst value will be calculated
 | 
				
			||||||
 | 
					# as 80% of bw_limit to ensure that at least limits for TCP traffic will work
 | 
				
			||||||
 | 
					# fine.
 | 
				
			||||||
 | 
					DEFAULT_BURST_RATE = 0.8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Method names for QoSDriver
 | 
				
			||||||
 | 
					PRECOMMIT_POSTFIX = '_precommit'
 | 
				
			||||||
 | 
					CREATE_POLICY = 'create_policy'
 | 
				
			||||||
 | 
					CREATE_POLICY_PRECOMMIT = CREATE_POLICY + PRECOMMIT_POSTFIX
 | 
				
			||||||
 | 
					UPDATE_POLICY = 'update_policy'
 | 
				
			||||||
 | 
					UPDATE_POLICY_PRECOMMIT = UPDATE_POLICY + PRECOMMIT_POSTFIX
 | 
				
			||||||
 | 
					DELETE_POLICY = 'delete_policy'
 | 
				
			||||||
 | 
					DELETE_POLICY_PRECOMMIT = DELETE_POLICY + PRECOMMIT_POSTFIX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOS_CALL_METHODS = (
 | 
				
			||||||
 | 
					    CREATE_POLICY,
 | 
				
			||||||
 | 
					    CREATE_POLICY_PRECOMMIT,
 | 
				
			||||||
 | 
					    UPDATE_POLICY,
 | 
				
			||||||
 | 
					    UPDATE_POLICY_PRECOMMIT,
 | 
				
			||||||
 | 
					    DELETE_POLICY,
 | 
				
			||||||
 | 
					    DELETE_POLICY_PRECOMMIT, )
 | 
				
			||||||
							
								
								
									
										0
									
								
								neutron_lib/tests/unit/services/qos/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								neutron_lib/tests/unit/services/qos/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										81
									
								
								neutron_lib/tests/unit/services/qos/test_base.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								neutron_lib/tests/unit/services/qos/test_base.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					# All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					#    not use this file except in compliance with the License. You may obtain
 | 
				
			||||||
 | 
					#    a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
				
			||||||
 | 
					#    License for the specific language governing permissions and limitations
 | 
				
			||||||
 | 
					#    under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from neutron_lib.api.definitions import portbindings
 | 
				
			||||||
 | 
					from neutron_lib.services.qos import base as qos_base
 | 
				
			||||||
 | 
					from neutron_lib.services.qos import constants as qos_consts
 | 
				
			||||||
 | 
					from neutron_lib.tests import _base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SUPPORTED_RULES = {
 | 
				
			||||||
 | 
					    qos_consts.RULE_TYPE_MINIMUM_BANDWIDTH: {
 | 
				
			||||||
 | 
					        "min_kbps": {'type:values': None},
 | 
				
			||||||
 | 
					        'direction': {'type:values': ['egress']}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _make_rule(rule_type='fake-rule-type', params=None):
 | 
				
			||||||
 | 
					    mock_rule = mock.MagicMock()
 | 
				
			||||||
 | 
					    mock_rule.rule_type = rule_type
 | 
				
			||||||
 | 
					    params = params or {}
 | 
				
			||||||
 | 
					    mock_rule.get = params.get
 | 
				
			||||||
 | 
					    return mock_rule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _make_driver(name='fake-driver',
 | 
				
			||||||
 | 
					                 vif_types=[portbindings.VIF_TYPE_OVS],
 | 
				
			||||||
 | 
					                 vnic_types=[portbindings.VNIC_NORMAL],
 | 
				
			||||||
 | 
					                 supported_rules=SUPPORTED_RULES,
 | 
				
			||||||
 | 
					                 requires_rpc_notifications=False):
 | 
				
			||||||
 | 
					    return qos_base.DriverBase(
 | 
				
			||||||
 | 
					        name, vif_types, vnic_types, supported_rules,
 | 
				
			||||||
 | 
					        requires_rpc_notifications=requires_rpc_notifications)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestDriverBase(_base.BaseTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_loaded(self):
 | 
				
			||||||
 | 
					        self.assertTrue(_make_driver().is_loaded())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_vif_type_compatible(self):
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            _make_driver().is_vif_type_compatible(
 | 
				
			||||||
 | 
					                portbindings.VIF_TYPE_OVS))
 | 
				
			||||||
 | 
					        self.assertFalse(
 | 
				
			||||||
 | 
					            _make_driver().is_vif_type_compatible(
 | 
				
			||||||
 | 
					                portbindings.VIF_TYPE_BRIDGE))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_vnic_compatible(self):
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            _make_driver().is_vnic_compatible(portbindings.VNIC_NORMAL))
 | 
				
			||||||
 | 
					        self.assertFalse(
 | 
				
			||||||
 | 
					            _make_driver().is_vnic_compatible(portbindings.VNIC_BAREMETAL))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_rule_supported_with_unsupported_rule(self):
 | 
				
			||||||
 | 
					        self.assertFalse(_make_driver().is_rule_supported(_make_rule()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_is_rule_supported(self):
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            _make_driver().is_rule_supported(
 | 
				
			||||||
 | 
					                _make_rule(
 | 
				
			||||||
 | 
					                    rule_type=qos_consts.RULE_TYPE_MINIMUM_BANDWIDTH,
 | 
				
			||||||
 | 
					                    params={'min_kbps': None, 'direction': 'egress'})))
 | 
				
			||||||
 | 
					        self.assertFalse(
 | 
				
			||||||
 | 
					            _make_driver().is_rule_supported(
 | 
				
			||||||
 | 
					                _make_rule(
 | 
				
			||||||
 | 
					                    rule_type=qos_consts.RULE_TYPE_MINIMUM_BANDWIDTH,
 | 
				
			||||||
 | 
					                    params={'min_kbps': None, 'direction': 'ingress'})))
 | 
				
			||||||
@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					features:
 | 
				
			||||||
 | 
					  - The ``DriverBase`` class from ``neutron.services.qos.drivers.base`` is now
 | 
				
			||||||
 | 
					    available in the ``neutron_lib.services.qos.base`` module.
 | 
				
			||||||
 | 
					  - The constants defined in ``neutron.services.qos.qos_consts`` are now
 | 
				
			||||||
 | 
					    available in ``neutron_lib.services.qos.constants``.
 | 
				
			||||||
		Reference in New Issue
	
	Block a user