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:
parent
3a86761751
commit
d35f7e1716
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``.
|
Loading…
Reference in New Issue
Block a user