From 7c8b643e63203abd8e9e7cfbe903e175f2eba3bd Mon Sep 17 00:00:00 2001
From: Venkata Siva Vijayendra Bhamidipati <vbhamidipati@ebaysf.com>
Date: Tue, 4 Mar 2014 17:26:26 -0800
Subject: [PATCH] Adding a tag extension.

---
 neutron/extensions/tag.py           | 181 ++++++++++++++++++++++++++++++++++++
 neutron/plugins/common/constants.py |   1 +
 neutron/plugins/ml2/plugin.py       |   2 +-
 3 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 neutron/extensions/tag.py

diff --git a/neutron/extensions/tag.py b/neutron/extensions/tag.py
new file mode 100644
index 0000000..727a38d
--- /dev/null
+++ b/neutron/extensions/tag.py
@@ -0,0 +1,181 @@
+#    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 traceback
+
+from oslo.config import cfg
+
+from neutron.api import extensions
+from neutron.api.v2 import attributes as attr
+from neutron.api.v2 import base
+from neutron.common import exceptions as qexception
+from neutron import manager
+from neutron.openstack.common import log as logging
+from neutron.plugins.common import constants
+from neutron.services.service_base import ServicePluginBase
+
+
+LOG = logging.getLogger(__name__)
+
+
+# Tag Exceptions
+class TagNotFound(qexception.NotFound):
+    message = _("Tag %(tag_id)s could not be found.")
+
+
+def convert_action_to_case_insensitive(value):
+    if value is None:
+        return
+    else:
+        return value.lower()
+
+
+def convert_port_to_string(value):
+    if value is None:
+        return
+    else:
+        return str(value)
+
+
+# We send over the collection name
+# when registering these new API
+# extensions with the wsgi server.
+
+RESOURCE_NAME = 'tag'
+COLLECTION_NAME = RESOURCE_NAME + 's' 
+
+TAG_API_EXTENSIONS = {
+    'tags': {
+        'id': {'allow_post': True,
+               'allow_put': True,
+               'is_visible': True,
+               'primary_key': True,
+               'default': attributes.ATTR_NOT_SPECIFIED},
+        'tenant_id': {'allow_post': True,
+               'allow_put': False,
+               'required_by_policy': True,
+               'is_visible': True,
+               'default': attributes.ATTR_NOT_SPECIFIED},
+        'name': {'allow_post': True,
+               'allow_put': True,
+               'validate': {'type:string': None},
+               'is_visible': True,
+               'default': ''},
+        'key': {'allow_post': True,
+               'allow_put': True,
+               'validate': {'type:string': None},
+               'is_visible': True,
+               'default': ''},
+        'value': {'allow_post': True,
+               'allow_put': True,
+               'validate': {'type:string': None},
+               'is_visible': True,
+               'default': ''}
+    }
+}
+
+class Tag(extensions.ExtensionDescriptor):
+
+    @classmethod
+    def get_name(cls):
+        return "Tags resource"
+
+    @classmethod
+    def get_alias(cls):
+        return "tags"
+
+    @classmethod
+    def get_description(cls):
+        return "Extension for Tags resource"
+
+    @classmethod
+    def get_namespace(cls):
+        return "http://wiki.openstack.org/Neutron/Tags/API_2.0"
+
+    @classmethod
+    def get_updated(cls):
+        return "2014-03-7T10:00:00-00:00"
+
+    @classmethod
+    def get_resources(cls):
+        resources = []
+        #plugin = manager.NeutronManager.get_service_plugins()[
+        #    constants.TAG]
+        plugin = manager.NeutronManager.get_plugin()
+        params = TAG_API_EXTENSIONS[COLLECTION_NAME]
+
+        controller = base.create_resource(
+            COLLECTION_NAME, RESOURCE_NAME, plugin, params,
+            member_actions=member_actions,
+            allow_pagination=cfg.CONF.allow_pagination,
+            allow_sorting=cfg.CONF.allow_sorting)
+
+        resource = extensions.ResourceExtension(
+            COLLECTION_NAME,
+            controller,
+            path_prefix=constants.COMMON_PREFIXES[constants.TAG],
+            member_actions=None,
+            attr_map=params)
+        resources.append(resource)
+
+        return resources
+
+
+    @classmethod
+    def get_plugin_interface(cls):
+        return TagPluginBase
+
+    def update_attributes_map(self, attributes):
+        super(Tag, self).update_attributes_map(
+            attributes, extension_attrs_map=TAG_API_EXTENSIONS)
+
+    def get_extended_resources(self, version):
+        if version == "2.0":
+            return TAG_API_EXTENSIONS
+        else:
+            return {}
+
+
+
+class TagPluginBase(ServicePluginBase):
+    __metaclass__ = abc.ABCMeta
+
+    def get_plugin_name(self):
+        return constants.TAG
+
+    def get_plugin_type(self):
+        return constants.TAG
+
+    def get_plugin_description(self):
+        return 'Tag resource plugin'
+
+    @abc.abstractmethod
+    def get_tags(self, context, filters=None, fields=None):
+        pass
+
+    @abc.abstractmethod
+    def get_tag(self, context, id, fields=None):
+        pass
+
+    @abc.abstractmethod
+    def create_tag(self, context, tag):
+        pass
+
+    @abc.abstractmethod
+    def update_tag(self, context, id, tag):
+        pass
+
+    @abc.abstractmethod
+    def delete_tag(self, context, id):
+        pass
diff --git a/neutron/plugins/common/constants.py b/neutron/plugins/common/constants.py
index e3ed1ab..b5c5302 100644
--- a/neutron/plugins/common/constants.py
+++ b/neutron/plugins/common/constants.py
@@ -23,6 +23,7 @@ FIREWALL = "FIREWALL"
 VPN = "VPN"
 METERING = "METERING"
 L3_ROUTER_NAT = "L3_ROUTER_NAT"
+TAG = "TAG"
 
 
 #maps extension alias to service type
diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py
index 973a9fe..d34cd4f 100644
--- a/neutron/plugins/ml2/plugin.py
+++ b/neutron/plugins/ml2/plugin.py
@@ -86,7 +86,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
                                     "quotas", "security-group", "agent",
                                     "dhcp_agent_scheduler",
                                     "multi-provider", "allowed-address-pairs",
-                                    "extra_dhcp_opt"]
+                                    "extra_dhcp_opt", "tags"]
 
     @property
     def supported_extension_aliases(self):
-- 
1.8.3.2

