]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Merge remote-tracking branch 'origin/feature/qos' into merge-branch
authorIhar Hrachyshka <ihrachys@redhat.com>
Tue, 7 Jul 2015 13:37:58 +0000 (15:37 +0200)
committerIhar Hrachyshka <ihrachys@redhat.com>
Tue, 7 Jul 2015 14:01:17 +0000 (16:01 +0200)
Change-Id: I7f2342d62634f5b4af3a083cc1aaff46efe28519

1  2 
doc/source/devref/index.rst
etc/policy.json
neutron/agent/ovsdb/native/commands.py
neutron/db/migration/alembic_migrations/versions/48153cb5f051_qos_db_changes.py
neutron/db/migration/alembic_migrations/versions/HEAD
neutron/extensions/qos.py
neutron/plugins/common/constants.py
neutron/plugins/ml2/plugin.py
neutron/tests/etc/policy.json
neutron/tests/functional/agent/test_ovs_lib.py
neutron/tests/unit/plugins/ml2/test_plugin.py

Simple merge
diff --cc etc/policy.json
Simple merge
index 0000000000000000000000000000000000000000,7f79253d1773d51e36443ed3b5a7c9da14aec742..f246f35875ff5aa7e58eeb7cf5baee9c7e2b3791
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,79 +1,79 @@@
 -down_revision = '599c6a226151'
+ # 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 = '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()))
index 5d2bcdc22c2ea5a88a2a4bb949e4feeb234182d3,d746e10e7c5f2b180364c38dfbd867c9e363870e..7733e549b5ddfaa457d6758d6f65c86045d5af89
@@@ -1,1 -1,1 +1,1 @@@
- 52c5312f6baf
 -48153cb5f051
++48153cb5f051
index 0000000000000000000000000000000000000000,396a1c089335f8fa958e1ae91ede13322bfd9f9c..4fff03333158421a196fe70e89723e5aa59c05fb
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,234 +1,235 @@@
 -                path_prefix=constants.COMMON_PREFIXES[
 -                    constants.QOS],
+ # 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=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
index 63947ae6fd1152eaf0592b2d52ce4acf63750a51,df2638e22d55118a73dae1de977dd32240aca40c..b20e551c7f104287356d059a26c291649061cf70
@@@ -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"
Simple merge
Simple merge