From: Ihar Hrachyshka Date: Tue, 7 Jul 2015 13:37:58 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/feature/qos' into merge-branch X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=2fed2617cd843f10aa74e34cef5efe7f7dae00c3;p=openstack-build%2Fneutron-build.git Merge remote-tracking branch 'origin/feature/qos' into merge-branch Change-Id: I7f2342d62634f5b4af3a083cc1aaff46efe28519 --- 2fed2617cd843f10aa74e34cef5efe7f7dae00c3 diff --cc neutron/db/migration/alembic_migrations/versions/48153cb5f051_qos_db_changes.py index 000000000,7f79253d1..f246f3587 mode 000000,100755..100755 --- a/neutron/db/migration/alembic_migrations/versions/48153cb5f051_qos_db_changes.py +++ b/neutron/db/migration/alembic_migrations/versions/48153cb5f051_qos_db_changes.py @@@ -1,0 -1,79 +1,79 @@@ + # Copyright 2015 Huawei Technologies India Pvt Ltd, Inc + # + # 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. + # + + """qos db changes + + Revision ID: 48153cb5f051 + Revises: 599c6a226151 + Create Date: 2015-06-24 17:03:34.965101 + + """ + + # revision identifiers, used by Alembic. + revision = '48153cb5f051' -down_revision = '599c6a226151' ++down_revision = '52c5312f6baf' + + from alembic import op + import sqlalchemy as sa + + from neutron.api.v2 import attributes as attrs + + + def upgrade(): + op.create_table( + 'qos_policies', + sa.Column('id', sa.String(length=36), primary_key=True), + sa.Column('name', sa.String(length=attrs.NAME_MAX_LEN)), + sa.Column('description', sa.String(length=attrs.DESCRIPTION_MAX_LEN)), + sa.Column('shared', sa.Boolean()), + sa.Column('tenant_id', sa.String(length=attrs.TENANT_ID_MAX_LEN), + index=True)) + + op.create_table( + 'qos_network_policy_bindings', + sa.Column('policy_id', sa.String(length=36), + sa.ForeignKey('qos_policies.id', ondelete='CASCADE'), + nullable=False), + sa.Column('network_id', sa.String(length=36), + sa.ForeignKey('networks.id', ondelete='CASCADE'), + nullable=False, unique=True)) + + op.create_table( + 'qos_port_policy_bindings', + sa.Column('policy_id', sa.String(length=36), + sa.ForeignKey('qos_policies.id', ondelete='CASCADE'), + nullable=False), + sa.Column('port_id', sa.String(length=36), + sa.ForeignKey('ports.id', ondelete='CASCADE'), + nullable=False, unique=True)) + + op.create_table( + 'qos_rules', + sa.Column('id', sa.String(length=36), primary_key=True), + sa.Column('qos_policy_id', sa.String(length=36), + sa.ForeignKey('qos_policies.id', ondelete='CASCADE'), + nullable=False), + sa.Column('type', sa.String(length=255)), + sa.Column('tenant_id', sa.String(length=attrs.TENANT_ID_MAX_LEN), + index=True)) + + op.create_table( + 'qos_bandwidth_limit_rules', + sa.Column('qos_rule_id', sa.String(length=36), + sa.ForeignKey('qos_rules.id', ondelete='CASCADE'), + nullable=False, + primary_key=True), + sa.Column('max_kbps', sa.Integer()), + sa.Column('max_burst_kbps', sa.Integer())) diff --cc neutron/db/migration/alembic_migrations/versions/HEAD index 5d2bcdc22,d746e10e7..7733e549b --- a/neutron/db/migration/alembic_migrations/versions/HEAD +++ b/neutron/db/migration/alembic_migrations/versions/HEAD @@@ -1,1 -1,1 +1,1 @@@ - 52c5312f6baf -48153cb5f051 ++48153cb5f051 diff --cc neutron/extensions/qos.py index 000000000,396a1c089..4fff03333 mode 000000,100644..100644 --- a/neutron/extensions/qos.py +++ b/neutron/extensions/qos.py @@@ -1,0 -1,234 +1,235 @@@ + # 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. + + import abc + import itertools + + import six + + from neutron.api import extensions + from neutron.api.v2 import attributes as attr + from neutron.api.v2 import base + from neutron.api.v2 import resource_helper + from neutron import manager + from neutron.plugins.common import constants + from neutron.services import service_base + ++QOS_PREFIX = "/qos" ++ + RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth_limit' + VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT] + + # Attribute Map + QOS_RULE_COMMON_FIELDS = { + 'id': {'allow_post': False, 'allow_put': False, + 'validate': {'type:uuid': None}, + 'is_visible': True, + 'primary_key': True}, + 'type': {'allow_post': True, 'allow_put': True, 'is_visible': True, + 'default': '', + 'validate': {'type:values': VALID_RULE_TYPES}}, + 'tenant_id': {'allow_post': True, 'allow_put': False, + 'required_by_policy': True, + 'is_visible': True}, + } + + RESOURCE_ATTRIBUTE_MAP = { + 'policies': { + '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': None}}, + 'description': {'allow_post': True, 'allow_put': True, + 'is_visible': True, 'default': '', + 'validate': {'type:string': None}}, + 'shared': {'allow_post': True, 'allow_put': True, + 'is_visible': True, 'default': False, + 'convert_to': attr.convert_to_boolean}, + 'tenant_id': {'allow_post': True, 'allow_put': False, + 'required_by_policy': True, + 'is_visible': True} + } + } + + 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:non_negative': None}}, + 'max_burst_kbps': { + 'allow_post': True, 'allow_put': True, + 'is_visible': True, 'default': 0, + 'validate': {'type:non_negative': None}}}) + } + } + + QOS_POLICY_ID = "qos_policy_id" + + EXTENDED_ATTRIBUTES_2_0 = { + 'ports': {QOS_POLICY_ID: {'allow_post': True, + 'allow_put': True, + 'is_visible': True, + 'default': None, + 'validate': {'type:uuid_or_none': None}}}, + 'networks': {QOS_POLICY_ID: {'allow_post': True, + 'allow_put': True, + 'is_visible': True, + 'default': None, + 'validate': {'type:uuid_or_none': None}}}} + + + class Qos(extensions.ExtensionDescriptor): + """Quality of service API extension.""" + + @classmethod + def get_name(cls): + return "qos" + + @classmethod + def get_alias(cls): + return "qos" + + @classmethod + def get_namespace(cls): + #TODO(QoS): Remove, there's still a caller using it for log/debug + # which will crash otherwise + return None + + @classmethod + def get_description(cls): + return "The Quality of Service extension." + + @classmethod + def get_updated(cls): + return "2015-06-08T10:00:00-00:00" + + @classmethod + def get_plugin_interface(cls): + return QoSPluginBase + + @classmethod + def get_resources(cls): + """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)) + attr.PLURALS.update(plural_mappings) + + resources = resource_helper.build_resource_info( + plural_mappings, + RESOURCE_ATTRIBUTE_MAP, + constants.QOS, + translate_name=True, + allow_bulk=True) + + plugin = manager.NeutronManager.get_service_plugins()[constants.QOS] + for collection_name in 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( + 'parameters') + + controller = base.create_resource(collection_name, resource_name, + plugin, params, + allow_bulk=True, + parent=parent, + allow_pagination=True, + allow_sorting=True) + + resource = extensions.ResourceExtension( + collection_name, + controller, parent, - path_prefix=constants.COMMON_PREFIXES[ - constants.QOS], ++ path_prefix=QOS_PREFIX, + attr_map=params) + resources.append(resource) + + return resources + + def update_attributes_map(self, attributes, extension_attrs_map=None): + super(Qos, self).update_attributes_map( + attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) + + def get_extended_resources(self, version): + if version == "2.0": + return dict(EXTENDED_ATTRIBUTES_2_0.items() + + RESOURCE_ATTRIBUTE_MAP.items()) + else: + return {} + + + @six.add_metaclass(abc.ABCMeta) + class QoSPluginBase(service_base.ServicePluginBase): + + def get_plugin_description(self): + """returns string description of the plugin.""" + return "QoS Service Plugin for ports and networks" + + def get_plugin_type(self): + return constants.QOS + + @abc.abstractmethod + def get_policy(self, context, policy_id, fields=None): + pass + + @abc.abstractmethod + def get_policies(self, context, filters=None, fields=None, + sorts=None, limit=None, marker=None, + page_reverse=False): + pass + + @abc.abstractmethod + def create_policy(self, context, policy): + pass + + @abc.abstractmethod + def update_policy(self, context, policy_id, policy): + pass + + @abc.abstractmethod + def delete_policy(self, context, policy_id): + pass + + @abc.abstractmethod + def get_policy_bandwidth_limit_rule(self, context, rule_id, + policy_id, fields=None): + pass + + @abc.abstractmethod + def get_policy_bandwidth_limit_rules(self, context, policy_id, + filters=None, fields=None, + sorts=None, limit=None, + marker=None, page_reverse=False): + pass + + @abc.abstractmethod + def create_policy_bandwidth_limit_rule(self, context, policy_id, + bandwidth_limit_rule): + pass + + @abc.abstractmethod + def update_policy_bandwidth_limit_rule(self, context, rule_id, + policy_id, bandwidth_limit_rule): + pass + + @abc.abstractmethod + def delete_policy_bandwidth_limit_rule(self, context, rule_id, policy_id): + pass diff --cc neutron/plugins/common/constants.py index 63947ae6f,df2638e22..b20e551c7 --- a/neutron/plugins/common/constants.py +++ b/neutron/plugins/common/constants.py @@@ -31,9 -32,26 +32,10 @@@ EXT_TO_SERVICE_MAPPING = 'fwaas': FIREWALL, 'vpnaas': VPN, 'metering': METERING, - 'router': L3_ROUTER_NAT + 'router': L3_ROUTER_NAT, + 'qos': QOS, } -# TODO(salvatore-orlando): Move these (or derive them) from conf file -ALLOWED_SERVICES = [CORE, DUMMY, LOADBALANCER, FIREWALL, VPN, METERING, - L3_ROUTER_NAT, LOADBALANCERV2, QOS] - -COMMON_PREFIXES = { - CORE: "", - DUMMY: "/dummy_svc", - LOADBALANCER: "/lb", - LOADBALANCERV2: "/lbaas", - FIREWALL: "/fw", - VPN: "/vpn", - METERING: "/metering", - L3_ROUTER_NAT: "", - QOS: "/qos", -} - # Service operation status constants ACTIVE = "ACTIVE" DOWN = "DOWN"