]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
1) Added a bare-bones framework for quantum plugins.
authorSomik Behera <somik@nicira.com>
Fri, 13 May 2011 21:23:37 +0000 (14:23 -0700)
committerSomik Behera <somik@nicira.com>
Fri, 13 May 2011 21:23:37 +0000 (14:23 -0700)
2) Created demo quantum plugin that conforms to QuantumPluginBase
    Abstract class specification.
3) Demonstrated plugin registration and invocation using the demo
    plugin called "QuantumEchoPlugin"
4) Created the initial file structure for a quantum CLI
5) Seeded the utils module that will contain frequently used Quantum utilities.
6) Modified the manager module to initialize and register the quantum plugin
    defined in a configuration file. I have hard-coded the path to plugin for now
    but this will move to a quantum.conf file.

TODO:

1) Finish up the Quantum CLI
2) Write Quantum unit tests that can be run against any plug-in for certification.
3) Create a working quantum plugin.

quantum/manager.py
quantum/plugins/SamplePlugin.py [new file with mode: 0644]
quantum/plugins/__init__.py [new file with mode: 0644]
quantum/quantumCLI.py [new file with mode: 0644]
quantum/quantum_plugin_base.py
quantum/utils.py [new file with mode: 0644]

index b31702335098d193a8b5984298f57ddaaecc40f4..1d2c440b16e548a3cf7d0792066cebe6aac3808f 100644 (file)
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+# @author: Somik Behera, Nicira Networks, Inc.
 
+
+"""
+Quantum's Manager class is responsible for parsing a config file and instantiating the correct
+plugin that concretely implement quantum_plugin_base class
+
+The caller should make sure that QuantumManager is a singleton.
 """
-Manager is responsible for parsing a config file and instantiating the correct
-set of plugins that concretely implement quantum_plugin_base class
-"""
\ No newline at end of file
+
+import utils
+from quantum_plugin_base import QuantumPluginBase
+
+CONFIG_FILE = "quantum_plugin.conf"
+
+class QuantumManager(object):
+    
+   def __init__(self,config=CONFIG_FILE):
+        self.configuration_file = CONFIG_FILE
+        #TODO(somik): plugin location should be grabbed from a
+        # configuration file as opposed to hard-coding the location
+        #
+        #plugin_location = get_plugin_location(configuration_file)
+        plugin_location = "plugins.SamplePlugin.QuantumEchoPlugin"
+        plugin_klass = utils.import_class(plugin_location)
+        if not issubclass(plugin_klass, QuantumPluginBase):
+            raise Exception("Imported plugin didn't pass compatibility test")
+        else:
+            print("Imported plugin passed compatibility test\n") 
+        self.plugin = plugin_klass()
+        
+   def get_manager(self):
+       return self.plugin
+
+# TODO(somik): rmove the main class
+# Added for temporary testing purposes
+def main():
+    manager = QuantumManager()
+    myManager = manager.get_manager()
+    myManager.get_all_networks("tesst")
+    #print("is a plugin")
+
+# Standard boilerplate to call the main() function.
+if __name__ == '__main__':
+    main()
+    
+    
\ No newline at end of file
diff --git a/quantum/plugins/SamplePlugin.py b/quantum/plugins/SamplePlugin.py
new file mode 100644 (file)
index 0000000..8a0deae
--- /dev/null
@@ -0,0 +1,131 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011, Nicira Networks, 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.
+# @author: Somik Behera, Nicira Networks, Inc.
+
+class QuantumEchoPlugin(object):
+
+    """
+    QuantumEchoPlugin is a demo plugin that doesn't
+    do anything but demonstrated the concept of a
+    concrete Quantum Plugin. Any call to this plugin
+    will result in just a "print" to std. out with 
+    the name of the method that was called.
+    """
+    
+    def get_all_networks(self, tenant_id):
+        """
+        Returns a dictionary containing all
+        <network_uuid, network_name> for
+        the specified tenant. 
+        """
+        print("get_all_networks() called\n")
+    
+    
+    def create_network(self, tenant_id, net_name):
+        """
+        Creates a new Virtual Network, and assigns it
+        a symbolic name.
+        """
+        print("create_network() called\n")
+    
+    
+    def delete_network(self, tenant_id, net_id):
+        """
+        Deletes the network with the specified network identifier
+        belonging to the specified tenant.
+        """
+        print("delete_network() called\n")
+
+    
+    def get_network_details(self, tenant_id, net_id):
+        """
+        Deletes the Virtual Network belonging to a the
+        spec
+        """
+        print("get_network_details() called\n")
+    
+    
+    def rename_network(self, tenant_id, net_id, new_name):
+        """
+        Updates the symbolic name belonging to a particular
+        Virtual Network.
+        """
+        print("rename_network() called\n")
+    
+    
+    def get_all_ports(self, tenant_id, net_id):
+        """
+        Retrieves all port identifiers belonging to the
+        specified Virtual Network.
+        """
+        print("get_all_ports() called\n")
+    
+    
+    def create_port(self, tenant_id, net_id):
+        """
+        Creates a port on the specified Virtual Network.
+        """
+        print("create_port() called\n")
+    
+    
+    def delete_port(self, tenant_id, net_id, port_id):
+        """
+        Deletes a port on a specified Virtual Network,
+        if the port contains a remote interface attachment,
+        the remote interface is first un-plugged and then the port
+        is deleted.
+        """
+        print("delete_port() called\n")
+    
+    
+    def get_port_details(self, tenant_id, net_id, port_id):
+        """
+        This method allows the user to retrieve a remote interface
+        that is attached to this particular port.
+        """
+        print("get_port_details() called\n")
+    
+    
+    def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id):
+        """
+        Attaches a remote interface to the specified port on the
+        specified Virtual Network.
+        """
+        print("plug_interface() called\n")
+    
+    
+    def unplug_interface(self, tenant_id, net_id, port_id):
+        """
+        Detaches a remote interface from the specified port on the
+        specified Virtual Network.
+        """
+        print("unplug_interface() called\n")
+    
+    
+    def get_interface_details(self, tenant_id, net_id, port_id):
+        """
+        Retrieves the remote interface that is attached at this
+        particular port.
+        """
+        print("get_interface_details() called\n")
+    
+    
+    def get_all_attached_interfaces(self, tenant_id, net_id):
+        """
+        Retrieves all remote interfaces that are attached to
+        a particular Virtual Network.
+        """
+        print("get_all_attached_interfaces() called\n")
\ No newline at end of file
diff --git a/quantum/plugins/__init__.py b/quantum/plugins/__init__.py
new file mode 100644 (file)
index 0000000..df928bb
--- /dev/null
@@ -0,0 +1,16 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# Copyright 2011 Nicira Networks, 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.
+# @author: Somik Behera, Nicira Networks, Inc.
\ No newline at end of file
diff --git a/quantum/quantumCLI.py b/quantum/quantumCLI.py
new file mode 100644 (file)
index 0000000..2da173d
--- /dev/null
@@ -0,0 +1,33 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011, Nicira Networks, 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.
+# @author: Somik Behera, Nicira Networks, Inc.
+
+from manager import QuantumManager
+
+class CLI():
+    
+    def index(self):
+        pass
+    
+def main():
+    quantum = QuantumManager()
+    manager = quantum.get_manager()
+    manager.get_all_networks("tesst")
+    #print("is a plugin")
+
+# Standard boilerplate to call the main() function.
+if __name__ == '__main__':
+    main()
\ No newline at end of file
index 59601e9dd9ee8b37c5b6243af247832c511ae43d..7fedd528cf736fc615f15269aeb3fd0c5a394377 100644 (file)
@@ -132,4 +132,22 @@ class QuantumPluginBase(object):
         Retrieves all remote interfaces that are attached to
         a particular Virtual Network.
         """
-        pass
\ No newline at end of file
+        pass
+   
+    @classmethod
+    def __subclasshook__(cls, klass):
+        """
+        The __subclasshook__ method is a class method
+        that will be called everytime a class is tested
+        using issubclass(klass, Plugin). 
+        In that case, it will check that every method
+        marked with the abstractmethod decorator is
+        provided by the plugin class.
+        """
+        if cls is QuantumPluginBase:
+            for method in cls.__abstractmethods__:
+                if any(method in base.__dict__ for base in klass.__mro__):
+                    continue
+                return NotImplemented
+            return True
+        return NotImplemented
\ No newline at end of file
diff --git a/quantum/utils.py b/quantum/utils.py
new file mode 100644 (file)
index 0000000..284b184
--- /dev/null
@@ -0,0 +1,57 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011, Nicira Networks, 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.
+#
+# Borrowed from nova code base, more utilities will be added/borrowed as and
+# when needed.
+# @author: Somik Behera, Nicira Networks, Inc.
+
+"""Utilities and helper functions."""
+
+import base64
+import datetime
+import functools
+import inspect
+import json
+import os
+import random
+import re
+import socket
+import string
+import struct
+import sys
+import time
+import types
+
+
+def import_class(import_str):
+    """Returns a class from a string including module and class."""
+    mod_str, _sep, class_str = import_str.rpartition('.')
+    try:
+        __import__(mod_str)
+        return getattr(sys.modules[mod_str], class_str)
+    except (ImportError, ValueError, AttributeError), exc:
+        print(('Inner Exception: %s'), exc)
+        raise exception.ClassNotFound(class_name=class_str)
+
+
+def import_object(import_str):
+    """Returns an object including a module or module and class."""
+    try:
+        __import__(import_str)
+        return sys.modules[import_str]
+    except ImportError:
+        cls = import_class(import_str)
+        return cls()