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…
x
Reference in New Issue
Block a user