You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2013/02/09 13:27:01 UTC

svn commit: r1444350 - in /libcloud/trunk: ./ libcloud/compute/drivers/ libcloud/test/compute/ libcloud/test/compute/fixtures/opennebula_3_8/

Author: tomaz
Date: Sat Feb  9 12:27:01 2013
New Revision: 1444350

URL: http://svn.apache.org/r1444350
Log:
Add support for OpenNebula 3.8.

Contributed by Guillaume ZITTA, part of LIBCLOUD-295.

Added:
    libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/
    libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_collection.xml
    libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_large.xml
    libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_medium.xml
    libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_small.xml
Modified:
    libcloud/trunk/CHANGES
    libcloud/trunk/libcloud/compute/drivers/opennebula.py
    libcloud/trunk/libcloud/test/compute/test_opennebula.py

Modified: libcloud/trunk/CHANGES
URL: http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1444350&r1=1444349&r2=1444350&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Sat Feb  9 12:27:01 2013
@@ -163,6 +163,9 @@ Changes with Apache Libcloud in developm
      driver by providing ex_image_ids argument. (LIBCLOUD-294)
      [Chris Psaltis, Joseph Hall]
 
+   - Add support for OpenNebula 3.8. (LIBCLOUD-295)
+     [Guillaume ZITTA]
+
   *) Storage
 
     - Add a new local storage driver.

Modified: libcloud/trunk/libcloud/compute/drivers/opennebula.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/opennebula.py?rev=1444350&r1=1444349&r2=1444350&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/opennebula.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/opennebula.py Sat Feb  9 12:27:01 2013
@@ -46,11 +46,13 @@ __all__ = [
     'OpenNebula_1_4_NodeDriver',
     'OpenNebula_2_0_NodeDriver',
     'OpenNebula_3_0_NodeDriver',
-    'OpenNebula_3_2_NodeDriver']
+    'OpenNebula_3_2_NodeDriver',
+    'OpenNebula_3_8_NodeDriver']
 
 API_HOST = ''
 API_PORT = (4567, 443)
 API_SECURE = True
+API_PLAIN_AUTH = False
 DEFAULT_API_VERSION = '3.2'
 
 
@@ -146,13 +148,20 @@ class OpenNebulaResponse(XmlResponse):
 class OpenNebulaConnection(ConnectionUserAndKey):
     """
     Connection class for the OpenNebula.org driver.
+    with plain_auth support
     """
 
     host = API_HOST
     port = API_PORT
     secure = API_SECURE
+    plain_auth = API_PLAIN_AUTH
     responseCls = OpenNebulaResponse
 
+    def __init__(self, *args, **kwargs):
+        if 'plain_auth' in kwargs:
+            self.plain_auth = kwargs.pop('plain_auth')
+        super(OpenNebulaConnection, self).__init__(*args, **kwargs)
+
     def add_default_headers(self, headers):
         """
         Add headers required by the OpenNebula.org OCCI interface.
@@ -166,10 +175,13 @@ class OpenNebulaConnection(ConnectionUse
         @rtype:  C{dict}
         @return: Dictionary containing updated headers.
         """
-        pass_sha1 = hashlib.sha1(b(self.key)).hexdigest()
+        if self.plain_auth:
+            passwd = self.key
+        else:
+            passwd = hashlib.sha1(b(self.key)).hexdigest()
         headers['Authorization'] =\
             ('Basic %s' % b64encode(b('%s:%s' % (self.user_id,
-                                                 pass_sha1))).decode('utf-8'))
+                                                 passwd))).decode('utf-8'))
         return headers
 
 
@@ -289,6 +301,12 @@ class OpenNebulaNodeDriver(NodeDriver):
                 cls = OpenNebula_3_0_NodeDriver
             elif api_version in ['3.2']:
                 cls = OpenNebula_3_2_NodeDriver
+            elif api_version in ['3.8']:
+                cls = OpenNebula_3_8_NodeDriver
+                if 'plain_auth' not in kwargs:
+                    kwargs['plain_auth'] = cls.plain_auth
+                else:
+                    cls.plain_auth = kwargs['plain_auth']
             else:
                 raise NotImplementedError(
                     "No OpenNebulaNodeDriver found for API version %s" %
@@ -1019,22 +1037,86 @@ class OpenNebula_3_2_NodeDriver(OpenNebu
         @rtype:  C{list} of L{OpenNebulaNodeSize}
         """
         sizes = []
-        ids = 1
+        size_id = 1
+
+        attributes = [('name', str, None), ('ram', int, 'MEMORY'),
+                      ('cpu', float, None), ('vcpu', float, None),
+                      ('disk', str, None), ('bandwidth', float, None),
+                      ('price', float, None)]
+
         for element in object.findall('INSTANCE_TYPE'):
-            sizes.append(OpenNebulaNodeSize(id=ids,
-                         name=element.findtext('NAME'),
-                         ram=int(element.findtext('MEMORY'))
-                             if element.findtext('MEMORY', None) else None,
-                         cpu=float(element.findtext('CPU'))
-                             if element.findtext('CPU', None) else None,
-                         vcpu=int(element.findtext('VCPU'))
-                             if element.findtext('VCPU', None) else None,
-                         disk=element.findtext('DISK', None),
-                         bandwidth=float(element.findtext('BANDWIDTH'))
-                             if element.findtext('BANDWIDTH', None) else None,
-                         price=float(element.findtext('PRICE'))
-                             if element.findtext('PRICE', None) else None,
-                         driver=self))
-            ids += 1
+            size_kwargs = {'id': size_id, 'driver': self}
+            values = self._get_attributes_values(attributes=attributes,
+                                                 element=element)
+            size_kwargs.update(values)
+
+            size = OpenNebulaNodeSize(**size_kwargs)
+            sizes.append(size)
+            size_id += 1
 
         return sizes
+
+    def _get_attributes_values(self, attributes, element):
+        values = {}
+
+        for attribute_name, attribute_type, alias in attributes:
+                key = alias if alias else attribute_name.upper()
+                value = element.findtext(key)
+
+                if value is not None:
+                    value = attribute_type(value)
+
+                values[attribute_name] = value
+
+        return values
+
+
+class OpenNebula_3_8_NodeDriver(OpenNebula_3_2_NodeDriver):
+    """
+    OpenNebula.org node driver for OpenNebula.org v3.8.
+    """
+
+    plain_auth = API_PLAIN_AUTH
+
+    def _to_sizes(self, object):
+        """
+        Request a list of instance types and convert that list to a list of
+        OpenNebulaNodeSize objects.
+
+        Request a list of instance types from the OpenNebula web interface,
+        and issue a request to convert each XML object representation of an
+        instance type to an OpenNebulaNodeSize object.
+
+        @return: List of instance types.
+        @rtype:  C{list} of L{OpenNebulaNodeSize}
+        """
+        sizes = []
+        size_id = 1
+
+        attributes = [('name', str, None), ('ram', int, 'MEMORY'),
+                      ('cpu', float, None), ('vcpu', float, None),
+                      ('disk', str, None), ('bandwidth', float, None),
+                      ('price', float, None)]
+
+        for element in object.findall('INSTANCE_TYPE'):
+            element = self.connection.request(
+                ('/instance_type/%s') % (element.attrib['name'])).object
+
+            size_kwargs = {'id': size_id, 'driver': self}
+            values = self._get_attributes_values(attributes=attributes,
+                                                 element=element)
+            size_kwargs.update(values)
+
+            size = OpenNebulaNodeSize(**size_kwargs)
+            sizes.append(size)
+            size_id += 1
+        return sizes
+
+    def _ex_connection_class_kwargs(self):
+        """
+        Set plain_auth as an extra L{OpenNebulaConnection_3_8} argument
+
+        @return: C{dict} of L{OpenNebulaConnection_3_8} input arguments
+        """
+
+        return {'plain_auth': self.plain_auth}

Added: libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_collection.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_collection.xml?rev=1444350&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_collection.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_collection.xml Sat Feb  9 12:27:01 2013
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<INSTANCE_TYPE_COLLECTION>  
+    <INSTANCE_TYPE href="http://www.opennebula.org/instance_type/small" name="small"/>
+    <INSTANCE_TYPE href="http://www.opennebula.org/instance_type/medium" name="medium"/>
+    <INSTANCE_TYPE href="http://www.opennebula.org/instance_type/large" name="large"/>
+</INSTANCE_TYPE_COLLECTION>

Added: libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_large.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_large.xml?rev=1444350&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_large.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_large.xml Sat Feb  9 12:27:01 2013
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<INSTANCE_TYPE href="http://www.opennebula.org/instance_type/large">
+    <NAME>large</NAME>
+    <CPU>8</CPU>
+    <MEMORY>8192</MEMORY>
+</INSTANCE_TYPE>

Added: libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_medium.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_medium.xml?rev=1444350&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_medium.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_medium.xml Sat Feb  9 12:27:01 2013
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<INSTANCE_TYPE href="http://www.opennebula.org/instance_type/medium">
+    <NAME>medium</NAME>
+    <CPU>4</CPU>
+    <MEMORY>4096</MEMORY>
+</INSTANCE_TYPE>

Added: libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_small.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_small.xml?rev=1444350&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_small.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/opennebula_3_8/instance_type_small.xml Sat Feb  9 12:27:01 2013
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<INSTANCE_TYPE href="http://www.opennebula.org/instance_type/small">
+    <NAME>small</NAME>
+    <CPU>1</CPU>
+    <MEMORY>1024</MEMORY>
+</INSTANCE_TYPE>

Modified: libcloud/trunk/libcloud/test/compute/test_opennebula.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/test_opennebula.py?rev=1444350&r1=1444349&r2=1444350&view=diff
==============================================================================
--- libcloud/trunk/libcloud/test/compute/test_opennebula.py (original)
+++ libcloud/trunk/libcloud/test/compute/test_opennebula.py Sat Feb  9 12:27:01 2013
@@ -631,6 +631,56 @@ class OpenNebula_3_2_Tests(unittest.Test
         self.assertEqual(size.bandwidth, None)
         self.assertEqual(size.price, None)
 
+class OpenNebula_3_8_Tests(unittest.TestCase, OpenNebulaCaseMixin):
+    """
+    OpenNebula.org test suite for OpenNebula v3.8.
+    """
+
+    def setUp(self):
+        """
+        Setup test environment.
+        """
+        OpenNebulaNodeDriver.connectionCls.conn_classes = (
+            OpenNebula_3_8_MockHttp, OpenNebula_3_8_MockHttp)
+        self.driver = OpenNebulaNodeDriver(*OPENNEBULA_PARAMS + ('3.8',))
+
+    def test_list_sizes(self):
+        """
+        Test ex_list_networks functionality.
+        """
+        sizes = self.driver.list_sizes()
+
+        self.assertEqual(len(sizes), 3)
+        size = sizes[0]
+        self.assertEqual(size.id, '1')
+        self.assertEqual(size.name, 'small')
+        self.assertEqual(size.ram, 1024)
+        self.assertEqual(size.cpu, 1)
+        self.assertEqual(size.vcpu, None)
+        self.assertEqual(size.disk, None)
+        self.assertEqual(size.bandwidth, None)
+        self.assertEqual(size.price, None)
+
+        size = sizes[1]
+        self.assertEqual(size.id, '2')
+        self.assertEqual(size.name, 'medium')
+        self.assertEqual(size.ram, 4096)
+        self.assertEqual(size.cpu, 4)
+        self.assertEqual(size.vcpu, None)
+        self.assertEqual(size.disk, None)
+        self.assertEqual(size.bandwidth, None)
+        self.assertEqual(size.price, None)
+
+        size = sizes[2]
+        self.assertEqual(size.id, '3')
+        self.assertEqual(size.name, 'large')
+        self.assertEqual(size.ram, 8192)
+        self.assertEqual(size.cpu, 8)
+        self.assertEqual(size.vcpu, None)
+        self.assertEqual(size.disk, None)
+        self.assertEqual(size.bandwidth, None)
+        self.assertEqual(size.price, None)
+
 
 class OpenNebula_1_4_MockHttp(MockHttp):
     """
@@ -1019,5 +1069,45 @@ class OpenNebula_3_2_MockHttp(OpenNebula
             body = self.fixtures_3_2.load('instance_type_collection.xml')
             return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+
+class OpenNebula_3_8_MockHttp(OpenNebula_3_2_MockHttp):
+    """
+    Mock HTTP server for testing v3.8 of the OpenNebula.org compute driver.
+    """
+
+    fixtures_3_8 = ComputeFileFixtures('opennebula_3_8')
+
+    def _instance_type(self, method, url, body, headers):
+        """
+        Instance type pool.
+        """
+        if method == 'GET':
+            body = self.fixtures_3_8.load('instance_type_collection.xml')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _instance_type_small(self, method, url, body, headers):
+        """
+        Small instance type.
+        """
+        if method == 'GET':
+            body = self.fixtures_3_8.load('instance_type_small.xml')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _instance_type_medium(self, method, url, body, headers):
+        """
+        Medium instance type pool.
+        """
+        if method == 'GET':
+            body = self.fixtures_3_8.load('instance_type_medium.xml')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _instance_type_large(self, method, url, body, headers):
+        """
+        Large instance type pool.
+        """
+        if method == 'GET':
+            body = self.fixtures_3_8.load('instance_type_large.xml')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
 if __name__ == '__main__':
     sys.exit(unittest.main())