diff --git a/neutron/extensions/qos.py b/neutron/extensions/qos.py index 980718f0aaf..acbd4689848 100644 --- a/neutron/extensions/qos.py +++ b/neutron/extensions/qos.py @@ -17,14 +17,11 @@ import abc import itertools import re -from neutron_lib.api import converters +from neutron_lib.api.definitions import qos as apidef from neutron_lib.api import extensions as api_extensions -from neutron_lib import constants as common_constants -from neutron_lib.db import constants as db_const from neutron_lib.plugins import constants from neutron_lib.plugins import directory from neutron_lib.services import base as service_base -from neutron_lib.services.qos import constants as qos_consts import six from neutron.api import extensions @@ -33,126 +30,10 @@ from neutron.api.v2 import resource_helper from neutron.objects.qos import rule as rule_object -ALIAS = "qos" -QOS_PREFIX = "/qos" -COLLECTION_NAME = 'policies' - -# Attribute Map -QOS_RULE_COMMON_FIELDS = { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, -} - -RULE_TYPES = "rule_types" - -RESOURCE_ATTRIBUTE_MAP = { - COLLECTION_NAME: { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, 'primary_key': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': '', - 'validate': {'type:string': db_const.NAME_FIELD_SIZE}}, - 'shared': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': False, - 'convert_to': converters.convert_to_boolean}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'validate': { - 'type:string': db_const.PROJECT_ID_FIELD_SIZE}, - 'is_visible': True}, - 'rules': {'allow_post': False, 'allow_put': False, 'is_visible': True}, - }, - RULE_TYPES: { - 'type': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - } -} - -BANDWIDTH_LIMIT_RULES = "bandwidth_limit_rules" - -SUB_RESOURCE_ATTRIBUTE_MAP = { - BANDWIDTH_LIMIT_RULES: { - 'parent': {'collection_name': 'policies', - 'member_name': 'policy'}, - 'parameters': dict(QOS_RULE_COMMON_FIELDS, - **{'max_kbps': { - 'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None, - 'validate': {'type:range': [0, - db_const.DB_INTEGER_MAX_VALUE]}}, - 'max_burst_kbps': { - 'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': 0, - 'validate': {'type:range': [0, - db_const.DB_INTEGER_MAX_VALUE]}}}), - }, - 'dscp_marking_rules': { - 'parent': {'collection_name': 'policies', - 'member_name': 'policy'}, - 'parameters': dict(QOS_RULE_COMMON_FIELDS, - **{'dscp_mark': { - 'allow_post': True, 'allow_put': True, - 'convert_to': converters.convert_to_int, - 'is_visible': True, 'default': None, - 'validate': {'type:values': common_constants. - VALID_DSCP_MARKS}}}) - }, - 'minimum_bandwidth_rules': { - 'parent': {'collection_name': 'policies', - 'member_name': 'policy'}, - 'parameters': dict(QOS_RULE_COMMON_FIELDS, - **{'min_kbps': { - 'allow_post': True, 'allow_put': True, - 'is_visible': True, - 'validate': {'type:range': [0, - db_const.DB_INTEGER_MAX_VALUE]}}, - 'direction': { - 'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': 'egress', - 'validate': {'type:values': - [common_constants.EGRESS_DIRECTION]}}}) - } -} - -EXTENDED_ATTRIBUTES_2_0 = { - 'ports': {qos_consts.QOS_POLICY_ID: { - 'allow_post': True, - 'allow_put': True, - 'is_visible': True, - 'default': None, - 'validate': {'type:uuid_or_none': None}}}, - 'networks': {qos_consts.QOS_POLICY_ID: { - 'allow_post': True, - 'allow_put': True, - 'is_visible': True, - 'default': None, - 'validate': {'type:uuid_or_none': None}}}} - - -class Qos(api_extensions.ExtensionDescriptor): +class Qos(api_extensions.APIExtensionDescriptor): """Quality of Service API extension.""" - @classmethod - def get_name(cls): - return "Quality of Service" - - @classmethod - def get_alias(cls): - return "qos" - - @classmethod - def get_description(cls): - return "The Quality of Service extension." - - @classmethod - def get_updated(cls): - return "2015-06-08T10:00:00-00:00" + api_definition = apidef @classmethod def get_plugin_interface(cls): @@ -163,21 +44,23 @@ class Qos(api_extensions.ExtensionDescriptor): """Returns Ext Resources.""" special_mappings = {'policies': 'policy'} plural_mappings = resource_helper.build_plural_mappings( - special_mappings, itertools.chain(RESOURCE_ATTRIBUTE_MAP, - SUB_RESOURCE_ATTRIBUTE_MAP)) + special_mappings, itertools.chain( + apidef.RESOURCE_ATTRIBUTE_MAP, + apidef.SUB_RESOURCE_ATTRIBUTE_MAP)) resources = resource_helper.build_resource_info( plural_mappings, - RESOURCE_ATTRIBUTE_MAP, + apidef.RESOURCE_ATTRIBUTE_MAP, constants.QOS, translate_name=True, allow_bulk=True) plugin = directory.get_plugin(constants.QOS) - for collection_name in SUB_RESOURCE_ATTRIBUTE_MAP: + for collection_name in apidef.SUB_RESOURCE_ATTRIBUTE_MAP: resource_name = collection_name[:-1] - parent = SUB_RESOURCE_ATTRIBUTE_MAP[collection_name].get('parent') - params = SUB_RESOURCE_ATTRIBUTE_MAP[collection_name].get( + parent = apidef.SUB_RESOURCE_ATTRIBUTE_MAP[ + collection_name].get('parent') + params = apidef.SUB_RESOURCE_ATTRIBUTE_MAP[collection_name].get( 'parameters') controller = base.create_resource(collection_name, resource_name, @@ -190,23 +73,25 @@ class Qos(api_extensions.ExtensionDescriptor): resource = extensions.ResourceExtension( collection_name, controller, parent, - path_prefix=QOS_PREFIX, + path_prefix=apidef.API_PREFIX, attr_map=params) resources.append(resource) return resources def update_attributes_map(self, attributes, extension_attrs_map=None): + # TODO(boden): remove with I8ae11633962a48de6e8559b85447b8c8c753d705 super(Qos, self).update_attributes_map( attributes, - extension_attrs_map=dict(list(RESOURCE_ATTRIBUTE_MAP.items()) + - list(SUB_RESOURCE_ATTRIBUTE_MAP.items()))) + extension_attrs_map=dict( + list(apidef.RESOURCE_ATTRIBUTE_MAP.items()) + + list(apidef.SUB_RESOURCE_ATTRIBUTE_MAP.items()))) def get_extended_resources(self, version): + # TODO(boden): remove with I8ae11633962a48de6e8559b85447b8c8c753d705 if version == "2.0": - return dict(list(EXTENDED_ATTRIBUTES_2_0.items()) + - list(RESOURCE_ATTRIBUTE_MAP.items()) + - list(SUB_RESOURCE_ATTRIBUTE_MAP.items())) + return dict(list(apidef.RESOURCE_ATTRIBUTE_MAP.items()) + + list(apidef.SUB_RESOURCE_ATTRIBUTE_MAP.items())) else: return {} @@ -214,7 +99,7 @@ class Qos(api_extensions.ExtensionDescriptor): @six.add_metaclass(abc.ABCMeta) class QoSPluginBase(service_base.ServicePluginBase): - path_prefix = QOS_PREFIX + path_prefix = apidef.API_PREFIX # The rule object type to use for each incoming rule-related request. rule_objects = {'bandwidth_limit': rule_object.QosBandwidthLimitRule, diff --git a/neutron/extensions/qos_bw_limit_direction.py b/neutron/extensions/qos_bw_limit_direction.py index 5da5ab85c0a..b935cb796ad 100644 --- a/neutron/extensions/qos_bw_limit_direction.py +++ b/neutron/extensions/qos_bw_limit_direction.py @@ -13,11 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib.api.definitions import qos as qos_apidef from neutron_lib.api import extensions as api_extensions from neutron_lib import constants as common_constants -from neutron.extensions import qos - # The name of the extension. NAME = "Direction for QoS bandwidth limit rule" @@ -30,17 +29,17 @@ DESCRIPTION = ("Allow to configure QoS bandwidth limit rule with specific " "direction: ingress or egress") # The list of required extensions. -REQUIRED_EXTENSIONS = [qos.ALIAS] +REQUIRED_EXTENSIONS = [qos_apidef.ALIAS] # The list of optional extensions. OPTIONAL_EXTENSIONS = None # The resource attribute map for the extension. SUB_RESOURCE_ATTRIBUTE_MAP = { - qos.BANDWIDTH_LIMIT_RULES: { + qos_apidef.BANDWIDTH_LIMIT_RULES: { 'parameters': dict( - qos.SUB_RESOURCE_ATTRIBUTE_MAP[ - qos.BANDWIDTH_LIMIT_RULES]['parameters'], + qos_apidef.SUB_RESOURCE_ATTRIBUTE_MAP[ + qos_apidef.BANDWIDTH_LIMIT_RULES]['parameters'], **{'direction': { 'allow_post': True, 'allow_put': True, diff --git a/neutron/extensions/qos_default.py b/neutron/extensions/qos_default.py index d8534a0c31f..61eb50786d0 100644 --- a/neutron/extensions/qos_default.py +++ b/neutron/extensions/qos_default.py @@ -14,10 +14,9 @@ # under the License. from neutron_lib.api import converters +from neutron_lib.api.definitions import qos as qos_apidef from neutron_lib.api import extensions -from neutron.extensions import qos - # The alias of the extension. ALIAS = 'qos-default' @@ -32,14 +31,14 @@ DESCRIPTION = 'Expose the QoS default policy per project' TIMESTAMP = '2017-041-06T10:00:00-00:00' # The list of required extensions. -REQUIRED_EXTENSIONS = [qos.ALIAS] +REQUIRED_EXTENSIONS = [qos_apidef.ALIAS] # The list of optional extensions. OPTIONAL_EXTENSIONS = None # The resource attribute map for the extension. RESOURCE_ATTRIBUTE_MAP = { - qos.COLLECTION_NAME: { + qos_apidef.POLICIES: { 'is_default': {'allow_post': True, 'allow_put': True, 'default': False, diff --git a/neutron/extensions/qos_rule_type_details.py b/neutron/extensions/qos_rule_type_details.py index 2bf995d2d8c..ee0e7f97b77 100644 --- a/neutron/extensions/qos_rule_type_details.py +++ b/neutron/extensions/qos_rule_type_details.py @@ -13,10 +13,9 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib.api.definitions import qos as qos_apidef from neutron_lib.api import extensions as api_extensions -from neutron.extensions import qos - # The name of the extension. NAME = "Details of QoS rule types" @@ -29,14 +28,14 @@ DESCRIPTION = ("Expose details about QoS rule types supported by loaded " "backend drivers") # The list of required extensions. -REQUIRED_EXTENSIONS = [qos.ALIAS] +REQUIRED_EXTENSIONS = [qos_apidef.ALIAS] # The list of optional extensions. OPTIONAL_EXTENSIONS = None # The resource attribute map for the extension. RESOURCE_ATTRIBUTE_MAP = { - qos.RULE_TYPES: { + qos_apidef.RULE_TYPES: { 'drivers': {'allow_post': False, 'allow_put': False, 'is_visible': True} } diff --git a/neutron/services/qos/qos_plugin.py b/neutron/services/qos/qos_plugin.py index 3ca58911fc4..945cc1df68c 100644 --- a/neutron/services/qos/qos_plugin.py +++ b/neutron/services/qos/qos_plugin.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib.api.definitions import qos as qos_apidef from neutron_lib.callbacks import events as callbacks_events from neutron_lib.callbacks import registry as callbacks_registry from neutron_lib.callbacks import resources as callbacks_resources @@ -39,7 +40,7 @@ class QoSPlugin(qos.QoSPluginBase): service parameters over ports and networks. """ - supported_extension_aliases = ['qos', + supported_extension_aliases = [qos_apidef.ALIAS, 'qos-bw-limit-direction', 'qos-default', 'qos-rule-type-details'] diff --git a/neutron/tests/tempest/api/test_qos.py b/neutron/tests/tempest/api/test_qos.py index 83c20d70877..98b2931a32d 100644 --- a/neutron/tests/tempest/api/test_qos.py +++ b/neutron/tests/tempest/api/test_qos.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib.api.definitions import qos as qos_apidef from neutron_lib.services.qos import constants as qos_consts from tempest.common import utils from tempest.lib.common.utils import data_utils @@ -29,7 +30,7 @@ load_tests = testscenarios.load_tests_apply_scenarios class QosTestJSON(base.BaseAdminNetworkTest): - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @staticmethod def _get_driver_details(rule_type_details, driver_name): @@ -389,7 +390,7 @@ class QosTestJSON(base.BaseAdminNetworkTest): class QosBandwidthLimitRuleTestJSON(base.BaseAdminNetworkTest): direction = None - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @classmethod @base.require_qos_rule_type(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT) @@ -587,7 +588,7 @@ class RbacSharedQosPoliciesTest(base.BaseAdminNetworkTest): force_tenant_isolation = True credentials = ['primary', 'alt', 'admin'] - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @classmethod def resource_setup(cls): @@ -841,7 +842,7 @@ class QosDscpMarkingRuleTestJSON(base.BaseAdminNetworkTest): VALID_DSCP_MARK1 = 56 VALID_DSCP_MARK2 = 48 - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @classmethod @base.require_qos_rule_type(qos_consts.RULE_TYPE_DSCP_MARKING) @@ -975,7 +976,7 @@ class QosMinimumBandwidthRuleTestJSON(base.BaseAdminNetworkTest): DIRECTION_INGRESS = "ingress" RULE_NAME = qos_consts.RULE_TYPE_MINIMUM_BANDWIDTH + "_rule" RULES_NAME = RULE_NAME + "s" - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @classmethod @base.require_qos_rule_type(qos_consts.RULE_TYPE_MINIMUM_BANDWIDTH) @@ -1137,7 +1138,7 @@ class QosSearchCriteriaTest(base.BaseSearchCriteriaTest, list_kwargs = {'description': 'search-criteria-test'} list_as_admin = True - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @classmethod def resource_setup(cls): diff --git a/neutron/tests/tempest/api/test_qos_negative.py b/neutron/tests/tempest/api/test_qos_negative.py index 275fe0581cd..dddb2132509 100644 --- a/neutron/tests/tempest/api/test_qos_negative.py +++ b/neutron/tests/tempest/api/test_qos_negative.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib.api.definitions import qos as qos_apidef from neutron_lib.db import constants as db_const from tempest.lib import decorators from tempest.lib import exceptions as lib_exc @@ -23,7 +24,7 @@ LONG_TENANT_ID_NG = 'z' * (db_const.PROJECT_ID_FIELD_SIZE + 1) class QosNegativeTestJSON(base.BaseAdminNetworkTest): - required_extensions = ['qos'] + required_extensions = [qos_apidef.ALIAS] @decorators.attr(type='negative') @decorators.idempotent_id('b9dce555-d3b3-11e5-950a-54ee757c77da')