]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Create the QoS API extension stub
authorMiguel Angel Ajo <mangelajo@redhat.com>
Fri, 19 Jun 2015 14:28:26 +0000 (16:28 +0200)
committerMiguel Angel Ajo <mangelajo@redhat.com>
Mon, 29 Jun 2015 14:50:43 +0000 (17:50 +0300)
This patch introduces the QoS API extension, in a basic
form where we could, in combination with the service plugin
stub, start creating some experimental test jobs that install
the service plugin.

Please not that URL mapping is not fully according to spec,
neither it does include any testing. We need to work that out.

blueprint quantum-qos-api
Change-Id: I86e8048e2d9b84690dbede9a94cfc884985069c5

etc/policy.json
neutron/extensions/qos.py [new file with mode: 0644]
neutron/plugins/common/constants.py
neutron/tests/etc/policy.json

index 87f6b266897acb5c47292a9bce68c5682e84852f..4a04f1090bbc65a8aecd5bbe53c5f16c4a6fbbd8 100644 (file)
     "get_network:provider:physical_network": "rule:admin_only",
     "get_network:provider:segmentation_id": "rule:admin_only",
     "get_network:queue_id": "rule:admin_only",
+    "get_network:qos_policy_id": "rule:admin_only",
     "create_network:shared": "rule:admin_only",
     "create_network:router:external": "rule:admin_only",
     "create_network:segments": "rule:admin_only",
     "create_network:provider:network_type": "rule:admin_only",
     "create_network:provider:physical_network": "rule:admin_only",
     "create_network:provider:segmentation_id": "rule:admin_only",
+    "create_network:qos_policy_id": "rule:admin_only",
     "update_network": "rule:admin_or_owner",
     "update_network:segments": "rule:admin_only",
     "update_network:shared": "rule:admin_only",
@@ -44,6 +46,7 @@
     "update_network:provider:physical_network": "rule:admin_only",
     "update_network:provider:segmentation_id": "rule:admin_only",
     "update_network:router:external": "rule:admin_only",
+    "update_network:qos_policy_id": "rule:admin_only",
     "delete_network": "rule:admin_or_owner",
 
     "create_port": "",
     "create_port:binding:profile": "rule:admin_only",
     "create_port:mac_learning_enabled": "rule:admin_or_network_owner or rule:context_is_advsvc",
     "create_port:allowed_address_pairs": "rule:admin_or_network_owner",
+    "create_port:qos_policy_id": "rule:admin_only",
     "get_port": "rule:admin_or_owner or rule:context_is_advsvc",
     "get_port:queue_id": "rule:admin_only",
     "get_port:binding:vif_type": "rule:admin_only",
     "get_port:binding:vif_details": "rule:admin_only",
     "get_port:binding:host_id": "rule:admin_only",
     "get_port:binding:profile": "rule:admin_only",
+    "get_port:qos_policy_id": "rule:admin_only",
     "update_port": "rule:admin_or_owner or rule:context_is_advsvc",
     "update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
     "update_port:fixed_ips": "rule:admin_or_network_owner or rule:context_is_advsvc",
@@ -68,6 +73,7 @@
     "update_port:binding:profile": "rule:admin_only",
     "update_port:mac_learning_enabled": "rule:admin_or_network_owner or rule:context_is_advsvc",
     "update_port:allowed_address_pairs": "rule:admin_or_network_owner",
+    "update_port:qos_policy_id": "rule:admin_only",
     "delete_port": "rule:admin_or_owner or rule:context_is_advsvc",
 
     "get_router:ha": "rule:admin_only",
diff --git a/neutron/extensions/qos.py b/neutron/extensions/qos.py
new file mode 100644 (file)
index 0000000..4f164ba
--- /dev/null
@@ -0,0 +1,190 @@
+# 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 six
+
+from neutron.api import extensions
+from neutron.api.v2 import attributes as attr
+from neutron.api.v2 import resource_helper
+from neutron.plugins.common import constants
+from neutron.services import service_base
+
+VALID_RULE_TYPES = ['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},
+    'qos_policy_id': {'allow_post': True, 'allow_put': False,
+                      'is_visible': True, 'required_by_policy': 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 = {
+    'qos_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}},
+    #TODO(QoS): Here instead of using the resource helper we may
+    #           need to set a subcontroller for qos-rules, so we
+    #           can meet the spec definition.
+    'qos_bandwidthlimit_rules':
+        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."""
+        plural_mappings = resource_helper.build_plural_mappings(
+            {'policies': 'policy'}, RESOURCE_ATTRIBUTE_MAP)
+        attr.PLURALS.update(plural_mappings)
+        #TODO(QoS): manually register some resources to make sure
+        #           we match what's defined in the spec.
+        return resource_helper.build_resource_info(plural_mappings,
+                                                   RESOURCE_ATTRIBUTE_MAP,
+                                                   constants.QOS,
+                                                   translate_name=True,
+                                                   allow_bulk=True)
+
+    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_qos_policy(self, context, qos_policy_id, fields=None):
+        pass
+
+    @abc.abstractmethod
+    def get_qos_policies(self, context, filters=None, fields=None,
+                         sorts=None, limit=None, marker=None,
+                         page_reverse=False):
+        pass
+
+    @abc.abstractmethod
+    def create_qos_policy(self, context, qos_policy):
+        pass
+
+    @abc.abstractmethod
+    def update_qos_policy(self, context, qos_policy_id, qos_policy):
+        pass
+
+    @abc.abstractmethod
+    def delete_qos_policy(self, context, qos_policy_id):
+        pass
+
+    @abc.abstractmethod
+    def get_qos_bandwidth_limit_rule(self, context, rule_id, fields=None):
+        pass
+
+    @abc.abstractmethod
+    def get_qos_bandwith_limit_rules(self, context, filters=None, fields=None,
+                                     sorts=None, limit=None, marker=None,
+                                     page_reverse=False):
+        pass
+
+    @abc.abstractmethod
+    def create_qos_bandwidth_limit_rule(self, context, rule):
+        pass
+
+    @abc.abstractmethod
+    def update_qos_bandwidth_limit_rule(self, context, rule_id, rule):
+        pass
+
+    @abc.abstractmethod
+    def delete_qos_bandwith_limit_rule(self, context, rule_id):
+        pass
index 5c562dc3b7b6344fd91f9320c83e855bb088e323..659c8d948297f96cfc5792b7db7d37335674acac 100644 (file)
@@ -22,7 +22,7 @@ FIREWALL = "FIREWALL"
 VPN = "VPN"
 METERING = "METERING"
 L3_ROUTER_NAT = "L3_ROUTER_NAT"
-
+QOS = "QOS"
 
 # Maps extension alias to service type
 EXT_TO_SERVICE_MAPPING = {
index 87f6b266897acb5c47292a9bce68c5682e84852f..4a04f1090bbc65a8aecd5bbe53c5f16c4a6fbbd8 100644 (file)
     "get_network:provider:physical_network": "rule:admin_only",
     "get_network:provider:segmentation_id": "rule:admin_only",
     "get_network:queue_id": "rule:admin_only",
+    "get_network:qos_policy_id": "rule:admin_only",
     "create_network:shared": "rule:admin_only",
     "create_network:router:external": "rule:admin_only",
     "create_network:segments": "rule:admin_only",
     "create_network:provider:network_type": "rule:admin_only",
     "create_network:provider:physical_network": "rule:admin_only",
     "create_network:provider:segmentation_id": "rule:admin_only",
+    "create_network:qos_policy_id": "rule:admin_only",
     "update_network": "rule:admin_or_owner",
     "update_network:segments": "rule:admin_only",
     "update_network:shared": "rule:admin_only",
@@ -44,6 +46,7 @@
     "update_network:provider:physical_network": "rule:admin_only",
     "update_network:provider:segmentation_id": "rule:admin_only",
     "update_network:router:external": "rule:admin_only",
+    "update_network:qos_policy_id": "rule:admin_only",
     "delete_network": "rule:admin_or_owner",
 
     "create_port": "",
     "create_port:binding:profile": "rule:admin_only",
     "create_port:mac_learning_enabled": "rule:admin_or_network_owner or rule:context_is_advsvc",
     "create_port:allowed_address_pairs": "rule:admin_or_network_owner",
+    "create_port:qos_policy_id": "rule:admin_only",
     "get_port": "rule:admin_or_owner or rule:context_is_advsvc",
     "get_port:queue_id": "rule:admin_only",
     "get_port:binding:vif_type": "rule:admin_only",
     "get_port:binding:vif_details": "rule:admin_only",
     "get_port:binding:host_id": "rule:admin_only",
     "get_port:binding:profile": "rule:admin_only",
+    "get_port:qos_policy_id": "rule:admin_only",
     "update_port": "rule:admin_or_owner or rule:context_is_advsvc",
     "update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
     "update_port:fixed_ips": "rule:admin_or_network_owner or rule:context_is_advsvc",
@@ -68,6 +73,7 @@
     "update_port:binding:profile": "rule:admin_only",
     "update_port:mac_learning_enabled": "rule:admin_or_network_owner or rule:context_is_advsvc",
     "update_port:allowed_address_pairs": "rule:admin_or_network_owner",
+    "update_port:qos_policy_id": "rule:admin_only",
     "delete_port": "rule:admin_or_owner or rule:context_is_advsvc",
 
     "get_router:ha": "rule:admin_only",