libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r1442714 [1/2] - in /libcloud/branches/0.12.x: ./ libcloud/common/ libcloud/compute/drivers/ libcloud/data/ libcloud/dns/drivers/ libcloud/test/common/ libcloud/test/compute/ libcloud/test/compute/fixtures/hostvirtual/ libcloud/test/compute...
Date Tue, 05 Feb 2013 19:50:18 GMT
Author: tomaz
Date: Tue Feb  5 19:50:18 2013
New Revision: 1442714

URL: http://svn.apache.org/viewvc?rev=1442714&view=rev
Log:
Backport changes from trunk.

Added:
    libcloud/branches/0.12.x/libcloud/common/xmlrpc.py
      - copied unchanged from r1442709, libcloud/trunk/libcloud/common/xmlrpc.py
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/get_node.json
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/get_node.json
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/SoftLayer_Account.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/softlayer/SoftLayer_Account.xml
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/empty.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/softlayer/empty.xml
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/fail.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/softlayer/fail.xml
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3__SoftLayer_Virtual_Guest_createObject.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/softlayer/v3__SoftLayer_Virtual_Guest_createObject.xml
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3__SoftLayer_Virtual_Guest_getCreateObjectOptions.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/softlayer/v3__SoftLayer_Virtual_Guest_getCreateObjectOptions.xml
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3__SoftLayer_Virtual_Guest_getObject.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/compute/fixtures/softlayer/v3__SoftLayer_Virtual_Guest_getObject.xml
    libcloud/branches/0.12.x/libcloud/test/dns/fixtures/gandi/zone_doesnt_exist.xml
      - copied unchanged from r1442709, libcloud/trunk/libcloud/test/dns/fixtures/gandi/zone_doesnt_exist.xml
Modified:
    libcloud/branches/0.12.x/   (props changed)
    libcloud/branches/0.12.x/CHANGES
    libcloud/branches/0.12.x/libcloud/common/gandi.py
    libcloud/branches/0.12.x/libcloud/common/hostvirtual.py
    libcloud/branches/0.12.x/libcloud/compute/drivers/ec2.py
    libcloud/branches/0.12.x/libcloud/compute/drivers/gandi.py
    libcloud/branches/0.12.x/libcloud/compute/drivers/hostvirtual.py
    libcloud/branches/0.12.x/libcloud/compute/drivers/softlayer.py
    libcloud/branches/0.12.x/libcloud/compute/drivers/vcl.py
    libcloud/branches/0.12.x/libcloud/data/pricing.json
    libcloud/branches/0.12.x/libcloud/dns/drivers/gandi.py
    libcloud/branches/0.12.x/libcloud/dns/drivers/hostvirtual.py
    libcloud/branches/0.12.x/libcloud/test/common/test_gandi.py
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Account_getVirtualGuests.xml
    libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Location_Datacenter_getDatacenters.xml
    libcloud/branches/0.12.x/libcloud/test/compute/test_ec2.py
    libcloud/branches/0.12.x/libcloud/test/compute/test_gandi.py
    libcloud/branches/0.12.x/libcloud/test/compute/test_hostvirtual.py
    libcloud/branches/0.12.x/libcloud/test/compute/test_softlayer.py
    libcloud/branches/0.12.x/libcloud/test/compute/test_vcl.py
    libcloud/branches/0.12.x/libcloud/test/dns/test_gandi.py

Propchange: libcloud/branches/0.12.x/
------------------------------------------------------------------------------
  Merged /libcloud/trunk:r1439256-1440131,1440135-1440288,1440290-1440816,1440818-1440820,1440822-1442709

Modified: libcloud/branches/0.12.x/CHANGES
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/CHANGES?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/CHANGES (original)
+++ libcloud/branches/0.12.x/CHANGES Tue Feb  5 19:50:18 2013
@@ -27,6 +27,17 @@ Changes with Apache Libcloud 0.12.0:
       CA file which is used to verifying the server certificate. (LIBCLOUD-283)
       [Tomaz Muraus, Erinn Looney-Triggs]
 
+    - Add a common module (libcloud.common.xmlrpc) for handling XML-RPC
+      requests using Libcloud http layer.
+
+      Also refactor existing drivers which use xmlrpclib directly (VCL, Gandi,
+      Softlayer) to use this module.
+
+      This change allows drivers to support LIBCLOUD_DEBUG and SSL certificate
+      validation functionality. Previously they have bypassed Libcloud http
+      layer so this functionality was not available. (LIBCLOUD-288)
+      [John Carr]
+
   *) Compute
 
     - Fix string interpolation bug in __repr__ methods in the IBM SCE driver.
@@ -112,6 +123,21 @@ Changes with Apache Libcloud 0.12.0:
      relative path for the script argument. (LIBCLOUD-278)
      [Jaume Devesa]
 
+   - Fix Softlayer driver and make sure all the code is up to date and works
+     with the latest version of the actual Softlayer deployment (v3).
+     (LIBCLOUD-287)
+     [Kevin McDonald]
+
+   - Update EC2 driver, m3 instance types are now available in all the regions
+     except Brazil.
+
+     Also update pricing to reflect new (decreased) prices.
+     [Tomaz Muraus]
+
+   - Minor improvements in the HostVirtual driver and add new ex_get_node and
+     ex_build_node extension method. (LIBCLOUD-249)
+     [Dinesh Bhoopathy]
+
   *) Storage
 
     - Add a new local storage driver.

Modified: libcloud/branches/0.12.x/libcloud/common/gandi.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/common/gandi.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/common/gandi.py (original)
+++ libcloud/branches/0.12.x/libcloud/common/gandi.py Tue Feb  5 19:50:18 2013
@@ -20,15 +20,13 @@ import time
 import hashlib
 import sys
 
-from libcloud.utils.py3 import xmlrpclib
 from libcloud.utils.py3 import b
 
 from libcloud.common.base import ConnectionKey
+from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
 
 # Global constants
 
-API_URL = "https://rpc.gandi.net/xmlrpc/"
-
 DEFAULT_TIMEOUT = 600   # operation pooling max seconds
 DEFAULT_INTERVAL = 20   # seconds between 2 operation.info
 
@@ -38,70 +36,30 @@ class GandiException(Exception):
     Exception class for Gandi driver
     """
     def __str__(self):
-        return "(%u) %s" % (self.args[0], self.args[1])
+        return '(%u) %s' % (self.args[0], self.args[1])
 
     def __repr__(self):
-        return "<GandiException code %u '%s'>" % (self.args[0], self.args[1])
-
-
-class GandiSafeTransport(xmlrpclib.SafeTransport):
-    pass
-
-
-class GandiTransport(xmlrpclib.Transport):
-    pass
+        return '<GandiException code %u "%s">' % (self.args[0], self.args[1])
 
 
-class GandiProxy(xmlrpclib.ServerProxy):
-    transportCls = (GandiTransport, GandiSafeTransport)
-
-    def __init__(self, user_agent, verbose=0):
-        cls = self.transportCls[0]
-        if API_URL.startswith("https://"):
-            cls = self.transportCls[1]
-        t = cls(use_datetime=0)
-        t.user_agent = user_agent
-        xmlrpclib.ServerProxy.__init__(
-            self,
-            uri=API_URL,
-            transport=t,
-            verbose=verbose,
-            allow_none=True
-        )
+class GandiResponse(XMLRPCResponse):
+    """
+    A Base Gandi Response class to derive from.
+    """
 
 
-class GandiConnection(ConnectionKey):
+class GandiConnection(XMLRPCConnection, ConnectionKey):
     """
     Connection class for the Gandi driver
     """
 
-    proxyCls = GandiProxy
-
-    def __init__(self, key, password=None):
-        super(GandiConnection, self).__init__(key)
-        self.driver = BaseGandiDriver
-
-        try:
-            self._proxy = self.proxyCls(self._user_agent())
-        except xmlrpclib.Fault:
-            e = sys.exc_info()[1]
-            raise GandiException(1000, e)
+    responseCls = GandiResponse
+    host = 'rpc.gandi.net'
+    endpoint = '/xmlrpc/'
 
     def request(self, method, *args):
-        """ Request xmlrpc method with given args"""
-        try:
-            return getattr(self._proxy, method)(self.key, *args)
-        except xmlrpclib.Fault:
-            e = sys.exc_info()[1]
-            self.parse_error(e.faultCode, e.faultString)
-            raise GandiException(1001, e.faultString)
-
-    def parse_error(self, code, message):
-        """
-        This hook allows you to inspect any xmlrpclib errors and
-        potentially raise a more useful and specific exception.
-        """
-        pass
+        args = (self.key, ) + args
+        return super(GandiConnection, self).request(method, *args)
 
 
 class BaseGandiDriver(object):
@@ -112,22 +70,6 @@ class BaseGandiDriver(object):
     connectionCls = GandiConnection
     name = 'Gandi'
 
-    def __init__(self, key, secret=None, secure=False):
-        """
-        @param    key:    API key or username to used (required)
-        @type     key:    C{str}
-
-        @param    secret: Secret password to be used (required)
-        @type     secret: C{str}
-
-        @param    secure: Weither to use HTTPS or HTTP.
-        @type     secure: C{bool}
-        """
-        self.key = key
-        self.secret = secret
-        self.connection = self.connectionCls(key, secret)
-        self.connection.driver = self
-
     # Specific methods for gandi
     def _wait_operation(self, id, timeout=DEFAULT_TIMEOUT,
                         check_interval=DEFAULT_INTERVAL):
@@ -135,7 +77,7 @@ class BaseGandiDriver(object):
 
         for i in range(0, timeout, check_interval):
             try:
-                op = self.connection.request('operation.info', int(id))
+                op = self.connection.request('operation.info', int(id)).object
 
                 if op['step'] == 'DONE':
                     return True
@@ -180,7 +122,7 @@ class BaseObject(object):
         Note, for example, that this example will always produce the
         same UUID!
         """
-        hashstring = "%s:%s:%s" % \
+        hashstring = '%s:%s:%s' % \
             (self.uuid_prefix, self.id, self.driver.type)
         return hashlib.sha1(b(hashstring)).hexdigest()
 

Modified: libcloud/branches/0.12.x/libcloud/common/hostvirtual.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/common/hostvirtual.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/common/hostvirtual.py (original)
+++ libcloud/branches/0.12.x/libcloud/common/hostvirtual.py Tue Feb  5 19:50:18 2013
@@ -19,6 +19,7 @@ except ImportError:
 
 from libcloud.utils.py3 import httplib
 from libcloud.common.base import ConnectionKey, JsonResponse
+from libcloud.compute.types import InvalidCredsError
 from libcloud.common.types import LibcloudError
 
 API_HOST = 'www.vr.org'
@@ -57,13 +58,10 @@ class HostVirtualResponse(JsonResponse):
         return data
 
     def parse_error(self):
-        context = self.connection.context
         data = self.parse_body()
-        status = int(self.status)
 
         if self.status == httplib.UNAUTHORIZED:
-            raise InvalidCredsError(
-                data['error']['code'] + ': ' + data['error']['message'])
+            raise InvalidCredsError('%(code)s:%(message)s' % (data['error']))
         elif self.status == httplib.PRECONDITION_FAILED:
             raise HostVirtualException(
                 data['error']['code'], data['error']['message'])

Modified: libcloud/branches/0.12.x/libcloud/compute/drivers/ec2.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/compute/drivers/ec2.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/compute/drivers/ec2.py (original)
+++ libcloud/branches/0.12.x/libcloud/compute/drivers/ec2.py Tue Feb  5 19:50:18 2013
@@ -204,6 +204,8 @@ REGION_DETAILS = {
             'm2.xlarge',
             'm2.2xlarge',
             'm2.4xlarge',
+            'm3.xlarge',
+            'm3.2xlarge',
             'c1.medium',
             'c1.xlarge'
         ]
@@ -239,6 +241,8 @@ REGION_DETAILS = {
             'm2.xlarge',
             'm2.2xlarge',
             'm2.4xlarge',
+            'm3.xlarge',
+            'm3.2xlarge',
             'c1.medium',
             'c1.xlarge',
             'cc2.8xlarge'
@@ -257,6 +261,8 @@ REGION_DETAILS = {
             'm2.xlarge',
             'm2.2xlarge',
             'm2.4xlarge',
+            'm3.xlarge',
+            'm3.2xlarge',
             'c1.medium',
             'c1.xlarge'
         ]
@@ -274,6 +280,8 @@ REGION_DETAILS = {
             'm2.xlarge',
             'm2.2xlarge',
             'm2.4xlarge',
+            'm3.xlarge',
+            'm3.2xlarge',
             'c1.medium',
             'c1.xlarge'
         ]
@@ -309,6 +317,8 @@ REGION_DETAILS = {
             'm2.xlarge',
             'm2.2xlarge',
             'm2.4xlarge',
+            'm3.xlarge',
+            'm3.2xlarge',
             'c1.medium',
             'c1.xlarge'
         ]

Modified: libcloud/branches/0.12.x/libcloud/compute/drivers/gandi.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/compute/drivers/gandi.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/compute/drivers/gandi.py (original)
+++ libcloud/branches/0.12.x/libcloud/compute/drivers/gandi.py Tue Feb  5 19:50:18 2013
@@ -62,7 +62,7 @@ class GandiNodeDriver(BaseGandiDriver, N
     def _resource_info(self, type, id):
         try:
             obj = self.connection.request('%s.info' % type, int(id))
-            return obj
+            return obj.object
         except Exception:
             e = sys.exc_info()[1]
             raise GandiException(1003, e)
@@ -109,8 +109,8 @@ class GandiNodeDriver(BaseGandiDriver, N
         return [self._to_volume(d) for d in disks]
 
     def list_nodes(self):
-        vms = self.connection.request('vm.list')
-        ips = self.connection.request('ip.list')
+        vms = self.connection.request('vm.list').object
+        ips = self.connection.request('ip.list').object
         for vm in vms:
             vm['ips'] = []
             for ip in ips:
@@ -124,7 +124,7 @@ class GandiNodeDriver(BaseGandiDriver, N
 
     def reboot_node(self, node):
         op = self.connection.request('vm.reboot', int(node.id))
-        self._wait_operation(op['id'])
+        self._wait_operation(op.object['id'])
         vm = self._node_info(int(node.id))
         if vm['state'] == 'running':
             return True
@@ -135,11 +135,11 @@ class GandiNodeDriver(BaseGandiDriver, N
         if vm['state'] == 'running':
             # Send vm_stop and wait for accomplish
             op_stop = self.connection.request('vm.stop', int(node.id))
-            if not self._wait_operation(op_stop['id']):
+            if not self._wait_operation(op_stop.object['id']):
                 raise GandiException(1010, 'vm.stop failed')
             # Delete
         op = self.connection.request('vm.delete', int(node.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -221,7 +221,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         (op_disk, op_iface, op_vm) = self.connection.request(
             'vm.create_from',
             vm_spec, disk_spec, src_disk_id
-        )
+        ).object
 
         # We wait for vm_create to finish
         if self._wait_operation(op_vm['id']):
@@ -251,7 +251,7 @@ class GandiNodeDriver(BaseGandiDriver, N
             else:
                 filtering = {}
             images = self.connection.request('image.list', filtering)
-            return [self._to_image(i) for i in images]
+            return [self._to_image(i) for i in images.object]
         except Exception:
             e = sys.exc_info()[1]
             raise GandiException(1011, e)
@@ -268,7 +268,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         )
 
     def list_sizes(self, location=None):
-        account = self.connection.request('account.info')
+        account = self.connection.request('account.info').object
         # Look for available shares, and return a list of share_definition
         available_res = account['resources']['available']
 
@@ -306,8 +306,8 @@ class GandiNodeDriver(BaseGandiDriver, N
         )
 
     def list_locations(self):
-        res = self.connection.request("datacenter.list")
-        return [self._to_loc(l) for l in res]
+        res = self.connection.request('datacenter.list')
+        return [self._to_loc(l) for l in res.object]
 
     def list_volumes(self):
         """
@@ -315,7 +315,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         @rtype: C{list} of L{StorageVolume}
         """
         res = self.connection.request('disk.list', {})
-        return self._to_volumes(res)
+        return self._to_volumes(res.object)
 
     def create_volume(self, size, name, location=None, snapshot=None):
         disk_param = {
@@ -328,15 +328,15 @@ class GandiNodeDriver(BaseGandiDriver, N
                                          disk_param, int(snapshot.id))
         else:
             op = self.connection.request('disk.create', disk_param)
-        if self._wait_operation(op['id']):
-            disk = self._volume_info(op['disk_id'])
+        if self._wait_operation(op.object['id']):
+            disk = self._volume_info(op.object['disk_id'])
             return self._to_volume(disk)
         return None
 
     def attach_volume(self, node, volume, device=None):
         op = self.connection.request('vm.disk_attach',
                                      int(node.id), int(volume.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -354,13 +354,13 @@ class GandiNodeDriver(BaseGandiDriver, N
         """
         op = self.connection.request('vm.disk_detach',
                                      int(node.id), int(volume.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
     def destroy_volume(self, volume):
         op = self.connection.request('disk.delete', int(volume.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -401,8 +401,8 @@ class GandiNodeDriver(BaseGandiDriver, N
 
         @rtype: C{list} of L{GandiNetworkInterface}
         """
-        ifaces = self.connection.request('iface.list')
-        ips = self.connection.request('ip.list')
+        ifaces = self.connection.request('iface.list').object
+        ips = self.connection.request('ip.list').object
         for iface in ifaces:
             iface['ips'] = list(
                 filter(lambda i: i['iface_id'] == iface['id'], ips))
@@ -432,7 +432,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         @rtype: C{list} of L{GandiDisk}
         """
         res = self.connection.request('disk.list', {})
-        return self._to_disks(res)
+        return self._to_disks(res.object)
 
     def ex_node_attach_disk(self, node, disk):
         """
@@ -448,7 +448,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         """
         op = self.connection.request('vm.disk_attach',
                                      int(node.id), int(disk.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -466,7 +466,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         """
         op = self.connection.request('vm.disk_detach',
                                      int(node.id), int(disk.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -485,7 +485,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         """
         op = self.connection.request('vm.iface_attach',
                                      int(node.id), int(iface.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -504,7 +504,7 @@ class GandiNodeDriver(BaseGandiDriver, N
         """
         op = self.connection.request('vm.iface_detach',
                                      int(node.id), int(iface.id))
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -521,16 +521,16 @@ class GandiNodeDriver(BaseGandiDriver, N
         @rtype: C{bool}
         """
         if not disk.extra.get('can_snapshot'):
-            raise GandiException(1021, "Disk %s can't snapshot" % disk.id)
+            raise GandiException(1021, 'Disk %s can\'t snapshot' % disk.id)
         if not name:
-            suffix = datetime.today().strftime("%Y%m%d")
-            name = "snap_%s" % (suffix)
+            suffix = datetime.today().strftime('%Y%m%d')
+            name = 'snap_%s' % (suffix)
         op = self.connection.request(
             'disk.create_from',
             {'name': name, 'type': 'snapshot', },
             int(disk.id),
         )
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False
 
@@ -557,6 +557,6 @@ class GandiNodeDriver(BaseGandiDriver, N
         op = self.connection.request('disk.update',
                                      int(disk.id),
                                      params)
-        if self._wait_operation(op['id']):
+        if self._wait_operation(op.object['id']):
             return True
         return False

Modified: libcloud/branches/0.12.x/libcloud/compute/drivers/hostvirtual.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/compute/drivers/hostvirtual.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/compute/drivers/hostvirtual.py (original)
+++ libcloud/branches/0.12.x/libcloud/compute/drivers/hostvirtual.py Tue Feb  5 19:50:18 2013
@@ -29,7 +29,7 @@ from libcloud.common.hostvirtual import 
 from libcloud.common.hostvirtual import HostVirtualConnection
 from libcloud.common.hostvirtual import HostVirtualException
 from libcloud.compute.providers import Provider
-from libcloud.compute.types import NodeState, InvalidCredsError
+from libcloud.compute.types import NodeState
 from libcloud.compute.base import Node, NodeDriver
 from libcloud.compute.base import NodeImage, NodeSize, NodeLocation
 from libcloud.compute.base import NodeAuthSSHKey, NodeAuthPassword
@@ -72,6 +72,13 @@ class HostVirtualNodeDriver(NodeDriver):
         private_ips = []
         extra = {}
 
+        if 'plan_id' in data:
+            extra['size'] = data['plan_id']
+        if 'os_id' in data:
+            extra['image'] = data['os_id']
+        if 'location_id' in data:
+            extra['location'] = data['location_id']
+
         public_ips.append(data['ip'])
 
         node = Node(id=data['mbpkgid'], name=data['fqdn'], state=state,
@@ -99,7 +106,7 @@ class HostVirtualNodeDriver(NodeDriver):
             data=json.dumps(params)).object
         sizes = []
         for size in result:
-            n = NodeSize(id=size['plan'],
+            n = NodeSize(id=size['plan_id'],
                          name=size['plan'],
                          ram=size['ram'],
                          disk=size['disk'],
@@ -116,9 +123,9 @@ class HostVirtualNodeDriver(NodeDriver):
             i = NodeImage(id=image["id"],
                           name=image["os"],
                           driver=self.connection.driver,
-                          extra={
-                              'hypervisor': image['tech'],
-                              'arch': image['bits']})
+                          extra=image)
+            del i.extra['id']
+            del i.extra['os']
             images.append(i)
         return images
 
@@ -143,7 +150,7 @@ class HostVirtualNodeDriver(NodeDriver):
             dc = '3'
 
         params = {'fqdn': name,
-                  'plan': size.id,
+                  'plan': size.name,
                   'image': image.id,
                   'location': dc
                   }
@@ -158,10 +165,7 @@ class HostVirtualNodeDriver(NodeDriver):
             params['password'] = password
 
         if not ssh_key and not password:
-            raise HostVirtualException(500, "Need SSH key or root password")
-
-        if password is None:
-            raise HostVirtualException(500, "Root password cannot be empty")
+            raise HostVirtualException(500, "Need SSH key or Root password")
 
         result = self.connection.request(API_ROOT + '/cloud/buy_build',
                                          data=json.dumps(params),
@@ -185,6 +189,22 @@ class HostVirtualNodeDriver(NodeDriver):
 
         return bool(result)
 
+    def ex_get_node(self, node_id):
+        """
+        Get a single node.
+
+        @param      node_id: id of the node that we need the node object for
+        @type       node_id: C{str}
+
+        @rtype: L{Node}
+        """
+
+        params = {'mbpkgid': node_id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/server', params=params).object
+        node = self._to_node(result)
+        return node
+
     def ex_stop_node(self, node):
         """
         Stop a node.
@@ -218,3 +238,72 @@ class HostVirtualNodeDriver(NodeDriver):
             method='POST').object
 
         return bool(result)
+
+    def ex_build_node(self, **kwargs):
+        """
+        Build a server on a VR package and get it booted
+
+        @keyword node: node which should be used
+        @type    node: L{Node}
+
+        @keyword image: The distribution to deploy on your server (mandatory)
+        @type    image: L{NodeImage}
+
+        @keyword auth: an SSH key or root password (mandatory)
+        @type    auth: L{NodeAuthSSHKey} or L{NodeAuthPassword}
+
+        @keyword location: which datacenter to create the server in
+        @type    location: L{NodeLocation}
+
+        @rtype: C{bool}
+        """
+
+        node = kwargs['node']
+
+        if 'image' in kwargs:
+            image = kwargs['image']
+        else:
+            image = node.extra['image']
+
+        params = {
+            'mbpkgid': node.id,
+            'image': image,
+            'fqdn': node.name,
+            'location': node.extra['location'],
+        }
+
+        auth = kwargs['auth']
+
+        ssh_key = None
+        password = None
+        if isinstance(auth, NodeAuthSSHKey):
+            ssh_key = auth.pubkey
+            params['ssh_key'] = ssh_key
+        elif isinstance(auth, NodeAuthPassword):
+            password = auth.password
+            params['password'] = password
+
+        if not ssh_key and not password:
+            raise HostVirtualException(500, "Need SSH key or Root password")
+
+        result = self.connection.request(API_ROOT + '/cloud/server/build',
+                                         data=json.dumps(params),
+                                         method='POST').object
+        return bool(result)
+
+    def ex_delete_node(self, node):
+        """
+        Delete a node.
+
+        @param      node: Node which should be used
+        @type       node: L{Node}
+
+        @rtype: C{bool}
+        """
+
+        params = {'mbpkgid': node.id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/server/delete', data=json.dumps(params),
+            method='POST').object
+
+        return bool(result)

Modified: libcloud/branches/0.12.x/libcloud/compute/drivers/softlayer.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/compute/drivers/softlayer.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/compute/drivers/softlayer.py (original)
+++ libcloud/branches/0.12.x/libcloud/compute/drivers/softlayer.py Tue Feb  5 19:50:18 2013
@@ -23,15 +23,26 @@ import libcloud
 
 from libcloud.utils.py3 import xmlrpclib
 
+from libcloud.common.base import ConnectionUserAndKey
+from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
 from libcloud.common.types import InvalidCredsError, LibcloudError
 from libcloud.compute.types import Provider, NodeState
 from libcloud.compute.base import NodeDriver, Node, NodeLocation, NodeSize, \
     NodeImage
 
 DATACENTERS = {
+    'hou02': {'country': 'US'},
     'sea01': {'country': 'US'},
     'wdc01': {'country': 'US'},
-    'dal01': {'country': 'US'}
+    'dal01': {'country': 'US'},
+    'dal02': {'country': 'US'},
+    'dal04': {'country': 'US'},
+    'dal05': {'country': 'US'},
+    'dal06': {'country': 'US'},
+    'dal07': {'country': 'US'},
+    'sjc01': {'country': 'US'},
+    'sng01': {'country': 'SG'},
+    'ams01': {'country': 'NL'},
 }
 
 NODE_STATE_MAP = {
@@ -40,113 +51,45 @@ NODE_STATE_MAP = {
     'PAUSED': NodeState.TERMINATED,
 }
 
-DEFAULT_PACKAGE = 46
-
-SL_IMAGES = [
-    {'id': 1684, 'name': 'CentOS 5 - Minimal Install (32 bit)'},
-    {'id': 1685, 'name': 'CentOS 5 - Minimal Install (64 bit)'},
-    {'id': 1686, 'name': 'CentOS 5 - LAMP Install (32 bit)'},
-    {'id': 1687, 'name': 'CentOS 5 - LAMP Install (64 bit)'},
-    {'id': 1688,
-     'name': 'Red Hat Enterprise Linux 5 - Minimal Install (32 bit)'},
-    {'id': 1689,
-     'name': 'Red Hat Enterprise Linux 5 - Minimal Install (64 bit)'},
-    {'id': 1690, 'name': 'Red Hat Enterprise Linux 5 - LAMP Install (32 bit)'},
-    {'id': 1691, 'name': 'Red Hat Enterprise Linux 5 - LAMP Install (64 bit)'},
-    {'id': 1692,
-     'name': 'Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (32 bit)'},
-    {'id': 1693,
-     'name': 'Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)'},
-    {'id': 1694,
-     'name': 'Ubuntu Linux 8 LTS Hardy Heron - LAMP Install (32 bit)'},
-    {'id': 1695,
-     'name': 'Ubuntu Linux 8 LTS Hardy Heron - LAMP Install (64 bit)'},
-    {'id': 1696,
-     'name': 'Debian GNU/Linux 5.0 Lenny/Stable - Minimal Install (32 bit)'},
-    {'id': 1697,
-     'name': 'Debian GNU/Linux 5.0 Lenny/Stable - Minimal Install (64 bit)'},
-    {'id': 1698,
-     'name': 'Debian GNU/Linux 5.0 Lenny/Stable - LAMP Install (32 bit)'},
-    {'id': 1699,
-     'name': 'Debian GNU/Linux 5.0 Lenny/Stable - LAMP Install (64 bit)'},
-    {'id': 1700, 'name': 'Windows Server 2003 Standard SP2 with R2 (32 bit)'},
-    {'id': 1701, 'name': 'Windows Server 2003 Standard SP2 with R2 (64 bit)'},
-    {'id': 1703,
-     'name': 'Windows Server 2003 Enterprise SP2 with R2 (64 bit)'},
-    {'id': 1705, 'name': 'Windows Server 2008 Standard Edition (64bit)'},
-    {'id': 1715, 'name': 'Windows Server 2003 Datacenter SP2 (64 bit)'},
-    {'id': 1716, 'name': 'Windows Server 2003 Datacenter SP2 (32 bit)'},
-    {'id': 1742, 'name': 'Windows Server 2008 Standard Edition SP2 (32bit)'},
-    {'id': 1752, 'name': 'Windows Server 2008 Standard Edition SP2 (64bit)'},
-    {'id': 1756, 'name': 'Windows Server 2008 Enterprise Edition SP2 (32bit)'},
-    {'id': 1761, 'name': 'Windows Server 2008 Enterprise Edition SP2 (64bit)'},
-    {'id': 1766, 'name': 'Windows Server 2008 Datacenter Edition SP2 (32bit)'},
-    {'id': 1770, 'name': 'Windows Server 2008 Datacenter Edition SP2 (64bit)'},
-    {'id': 1857, 'name': 'Windows Server 2008 R2 Standard Edition (64bit)'},
-    {'id': 1860, 'name': 'Windows Server 2008 R2 Enterprise Edition (64bit)'},
-    {'id': 1863, 'name': 'Windows Server 2008 R2 Datacenter Edition (64bit)'},
-]
-
-"""
-The following code snippet will print out all available "prices"
-    mask = { 'items': '' }
-    res = self.connection.request(
-        "SoftLayer_Product_Package",
-        "getObject",
-        res,
-        id=46,
-        object_mask=mask
-    )
-
-    from pprint import pprint; pprint(res)
-"""
-SL_TEMPLATES = {
-    'sl1': {
-        'imagedata': {
-            'name': '2 x 2.0 GHz, 1GB ram, 100GB',
-            'ram': 1024,
-            'disk': 100,
-            'bandwidth': None
-        },
-        'prices': [
-            {'id': 1644},  # 1 GB
-            {'id': 1639},  # 100 GB (SAN)
-            {'id': 1963},  # Private 2 x 2.0 GHz Cores
-            {'id': 21},  # 1 IP Address
-            {'id': 55},  # Host Ping
-            {'id': 58},  # Automated Notification
-            {'id': 1800},  # 0 GB Bandwidth
-            {'id': 57},  # Email and Ticket
-            {'id': 274},  # 1000 Mbps Public & Private Networks
-            {'id': 905},  # Reboot / Remote Console
-            {'id': 418},  # Nessus Vulnerability Assessment & Reporting
-            {'id': 420},  # Unlimited SSL VPN Users & 1 PPTP VPN User per account
-        ],
-    },
-    'sl2': {
-        'imagedata': {
-            'name': '2 x 2.0 GHz, 4GB ram, 350GB',
-            'ram': 4096,
-            'disk': 350,
-            'bandwidth': None
-        },
-        'prices': [
-            {'id': 1646},  # 4 GB
-            {'id': 1639},  # 100 GB (SAN) - This is the only available "First Disk"
-            {'id': 1638},  # 250 GB (SAN)
-            {'id': 1963},  # Private 2 x 2.0 GHz Cores
-            {'id': 21},  # 1 IP Address
-            {'id': 55},  # Host Ping
-            {'id': 58},  # Automated Notification
-            {'id': 1800},  # 0 GB Bandwidth
-            {'id': 57},  # Email and Ticket
-            {'id': 274},  # 1000 Mbps Public & Private Networks
-            {'id': 905},  # Reboot / Remote Console
-            {'id': 418},  # Nessus Vulnerability Assessment & Reporting
-            {'id': 420},  # Unlimited SSL VPN Users & 1 PPTP VPN User per account
-        ],
-    }
-}
+SL_BASE_TEMPLATES = [
+    {
+        'name': '1 CPU, 1GB ram, 25GB',
+        'ram': 1024,
+        'disk': 25,
+        'cpus': 1,
+    }, {
+        'name': '1 CPU, 1GB ram, 100GB',
+        'ram': 1024,
+        'disk': 100,
+        'cpus': 1,
+    }, {
+        'name': '2 CPU, 2GB ram, 100GB',
+        'ram': 4 * 1024,
+        'disk': 100,
+        'cpus': 2,
+    }, {
+        'name': '4 CPU, 4GB ram, 100GB',
+        'ram': 4 * 1024,
+        'disk': 100,
+        'cpus': 4,
+    }, {
+        'name': '8 CPU, 8GB ram, 100GB',
+        'ram': 8 * 1024,
+        'disk': 100,
+        'cpus': 8,
+    }]
+
+SL_TEMPLATES = {}
+for i, template in enumerate(SL_BASE_TEMPLATES):
+    # Add local disk templates
+    local = template.copy()
+    local['local_disk'] = True
+    SL_TEMPLATES['sl%s_local_disk' % (i + 1,)] = local
+
+    # Add san disk templates
+    san = template.copy()
+    san['local_disk'] = False
+    SL_TEMPLATES['sl%s_san_disk' % (i + 1,)] = san
 
 
 class SoftLayerException(LibcloudError):
@@ -156,75 +99,37 @@ class SoftLayerException(LibcloudError):
     pass
 
 
-class SoftLayerSafeTransport(xmlrpclib.SafeTransport):
-    pass
-
-
-class SoftLayerTransport(xmlrpclib.Transport):
-    pass
-
-
-class SoftLayerProxy(xmlrpclib.ServerProxy):
-    transportCls = (SoftLayerTransport, SoftLayerSafeTransport)
-    API_PREFIX = 'https://api.softlayer.com/xmlrpc/v3/'
-
-    def __init__(self, service, user_agent, verbose=0):
-        cls = self.transportCls[0]
-        if SoftLayerProxy.API_PREFIX[:8] == "https://":
-            cls = self.transportCls[1]
-        t = cls(use_datetime=0)
-        t.user_agent = user_agent
-        xmlrpclib.ServerProxy.__init__(
-            self,
-            uri="%s/%s" % (SoftLayerProxy.API_PREFIX, service),
-            transport=t,
-            verbose=verbose
-        )
-
-
-class SoftLayerConnection(object):
-    """
-    Connection class for the SoftLayer driver
-    """
+class SoftLayerResponse(XMLRPCResponse):
+    defaultExceptionCls = SoftLayerException
+    exceptions = {
+        'SoftLayer_Account': InvalidCredsError,
+    }
 
-    proxyCls = SoftLayerProxy
-    driver = None
 
-    def __init__(self, user, key):
-        self.user = user
-        self.key = key
-        self.ua = []
+class SoftLayerConnection(XMLRPCConnection, ConnectionUserAndKey):
+    responseCls = SoftLayerResponse
+    endpoint = '/xmlrpc/v3/'
 
     def request(self, service, method, *args, **kwargs):
-        sl = self.proxyCls(service, self._user_agent())
-
         headers = {}
         headers.update(self._get_auth_headers())
         headers.update(self._get_init_params(service, kwargs.get('id')))
         headers.update(
             self._get_object_mask(service, kwargs.get('object_mask')))
-        params = [{'headers': headers}] + list(args)
+        headers.update(
+            self._get_object_mask(service, kwargs.get('object_mask')))
 
-        try:
-            return getattr(sl, method)(*params)
-        except xmlrpclib.Fault:
-            e = sys.exc_info()[1]
-            if e.faultCode == "SoftLayer_Account":
-                raise InvalidCredsError(e.faultString)
-            raise SoftLayerException(e)
-
-    def _user_agent(self):
-        return 'libcloud/%s (%s)%s' % (libcloud.__version__,
-                                       self.driver.name,
-                                       "".join([" (%s)" % x for x in self.ua]))
+        args = ({'headers': headers}, ) + args
+        endpoint = '%s/%s' % (self.endpoint, service)
 
-    def user_agent_append(self, s):
-        self.ua.append(s)
+        return super(SoftLayerConnection, self).request(method, *args,
+                                                        **{'endpoint':
+                                                            endpoint})
 
     def _get_auth_headers(self):
         return {
             'authenticate': {
-                'username': self.user,
+                'username': self.user_id,
                 'apiKey': self.key
             }
         }
@@ -262,30 +167,12 @@ class SoftLayerNodeDriver(NodeDriver):
     website = 'http://www.softlayer.com/'
     type = Provider.SOFTLAYER
 
-    features = {"create_node": ["generates_password"]}
-
-    def __init__(self, key, secret=None, secure=False):
-        """
-        @param    key:    API key or username to used (required)
-        @type     key:    C{str}
-
-        @param    secret: Secret password to be used (required)
-        @type     secret: C{str}
-
-        @param    secure: Weither to use HTTPS or HTTP.
-        @type     secure: C{bool}
-
-        @rtype: C{None}
-        """
-        self.key = key
-        self.secret = secret
-        self.connection = self.connectionCls(key, secret)
-        self.connection.driver = self
+    features = {'create_node': ['generates_password']}
 
     def _to_node(self, host):
         try:
             password = \
-                host['softwareComponents'][0]['passwords'][0]['password']
+                host['operatingSystem']['passwords'][0]['password']
         except (IndexError, KeyError):
             password = None
 
@@ -293,13 +180,13 @@ class SoftLayerNodeDriver(NodeDriver):
             'hourlyRecurringFee', 0)
         recurringFee = host.get('billingItem', {}).get('recurringFee', 0)
         recurringMonths = host.get('billingItem', {}).get('recurringMonths', 0)
+        createDate = host.get('createDate', None)
 
         return Node(
             id=host['id'],
             name=host['hostname'],
             state=NODE_STATE_MAP.get(
-                host['powerState']['keyName'],
-                NodeState.UNKNOWN
+                host['powerState']['keyName'], NodeState.UNKNOWN
             ),
             public_ips=[host['primaryIpAddress']],
             private_ips=[host['primaryBackendIpAddress']],
@@ -309,59 +196,44 @@ class SoftLayerNodeDriver(NodeDriver):
                 'hourlyRecurringFee': hourlyRecurringFee,
                 'recurringFee': recurringFee,
                 'recurringMonths': recurringMonths,
+                'created': createDate,
             }
         )
 
-    def _to_nodes(self, hosts):
-        return [self._to_node(h) for h in hosts]
-
     def destroy_node(self, node):
-        billing_item = self.connection.request(
-            "SoftLayer_Virtual_Guest",
-            "getBillingItem",
-            id=node.id
+        self.connection.request(
+            'SoftLayer_Virtual_Guest', 'deleteObject', id=node.id
         )
+        return True
 
-        if billing_item:
-            res = self.connection.request(
-                "SoftLayer_Billing_Item",
-                "cancelService",
-                id=billing_item['id']
-            )
-            return res
-        else:
-            return False
+    def reboot_node(self, node):
+        self.connection.request(
+            'SoftLayer_Virtual_Guest', 'rebootSoft', id=node.id
+        )
+        return True
 
-    def _get_order_information(self, order_id, timeout=1200, check_interval=5):
+    def _get_order_information(self, node_id, timeout=1200, check_interval=5):
         mask = {
-            'orderTopLevelItems': {
-                'billingItem': {
-                    'resource': {
-                        'softwareComponents': {'passwords': ''},
-                        'powerState': '',
-                    }
-                },
-            }
+            'billingItem': '',
+            'powerState': '',
+            'operatingSystem': {'passwords': ''},
+            'provisionDate': '',
         }
 
         for i in range(0, timeout, check_interval):
-            try:
-                res = self.connection.request(
-                    "SoftLayer_Billing_Order",
-                    "getObject",
-                    id=order_id,
-                    object_mask=mask
-                )
-                item = res['orderTopLevelItems'][0]['billingItem']['resource']
-                if item['softwareComponents'][0]['passwords']:
-                    return item
+            res = self.connection.request(
+                'SoftLayer_Virtual_Guest',
+                'getObject',
+                id=node_id,
+                object_mask=mask
+            ).object
 
-            except (KeyError, IndexError):
-                pass
+            if res.get('provisionDate', None):
+                return res
 
             time.sleep(check_interval)
 
-        return None
+        raise SoftLayerException('Timeout on getting node details')
 
     def create_node(self, **kwargs):
         """Create a new SoftLayer node
@@ -370,55 +242,111 @@ class SoftLayerNodeDriver(NodeDriver):
 
         @keyword    ex_domain: e.g. libcloud.org
         @type       ex_domain: C{str}
+        @keyword    ex_cpus: e.g. 2
+        @type       ex_cpus: C{int}
+        @keyword    ex_disk: e.g. 100
+        @type       ex_disk: C{int}
+        @keyword    ex_ram: e.g. 2048
+        @type       ex_ram: C{int}
+        @keyword    ex_bandwidth: e.g. 100
+        @type       ex_bandwidth: C{int}
+        @keyword    ex_local_disk: e.g. True
+        @type       ex_local_disk: C{bool}
+        @keyword    ex_datacenter: e.g. Dal05
+        @type       ex_datacenter: C{str}
+        @keyword    ex_os: e.g. UBUNTU_LATEST
+        @type       ex_os: C{str}
         """
         name = kwargs['name']
-        image = kwargs['image']
-        size = kwargs['size']
+        os = 'DEBIAN_LATEST'
+        if 'ex_os' in kwargs:
+            os = kwargs['ex_os']
+        elif 'image' in kwargs:
+            os = kwargs['image'].id
+
+        size = kwargs.get('size', NodeSize(id=None, name='Custom', ram=None,
+                                           disk=None, bandwidth=None,
+                                           price=None,
+                                           driver=self.connection.driver))
+
+        ex_size_data = SL_TEMPLATES.get(size.id) or {}
+        cpu_count = kwargs.get('ex_cpus') or ex_size_data.get('cpus') or 1
+        ram = kwargs.get('ex_ram') or size.ram or 2048
+        bandwidth = kwargs.get('ex_bandwidth') or size.bandwidth or 10
+        hourly = 'true' if kwargs.get('ex_hourly', True) else 'false'
+
+        local_disk = 'true'
+        if ex_size_data.get('local_disk') is False:
+            local_disk = 'false'
+
+        if kwargs.get('ex_local_disk') is False:
+            local_disk = 'false'
+
+        disk_size = 100
+        if size.disk:
+            disk_size = size.disk
+        if kwargs.get('ex_disk'):
+            disk_size = kwargs.get('ex_disk')
+
+        datacenter = ''
+        if 'ex_datacenter' in kwargs:
+            datacenter = kwargs['ex_datacenter']
+        elif 'location' in kwargs:
+            datacenter = kwargs['location'].id
+
         domain = kwargs.get('ex_domain')
-        location = kwargs['location']
         if domain is None:
-            if name.find(".") != -1:
+            if name.find('.') != -1:
                 domain = name[name.find('.') + 1:]
-
         if domain is None:
             # TODO: domain is a required argument for the Sofylayer API, but it
             # it shouldn't be.
-            domain = "exmaple.com"
+            domain = 'example.com'
 
-        res = {'prices': SL_TEMPLATES[size.id]['prices']}
-        res['packageId'] = DEFAULT_PACKAGE
-        res['prices'].append({'id': image.id})  # Add OS to order
-        res['location'] = location.id
-        res['complexType'] = 'SoftLayer_Container_Product_Order_Virtual_Guest'
-        res['quantity'] = 1
-        res['useHourlyPricing'] = True
-        res['virtualGuests'] = [
-            {
-                'hostname': name,
-                'domain': domain
-            }
-        ]
+        newCCI = {
+            'hostname': name,
+            'domain': domain,
+            'startCpus': cpu_count,
+            'maxMemory': ram,
+            'networkComponents': [{'maxSpeed': bandwidth}],
+            'hourlyBillingFlag': hourly,
+            'operatingSystemReferenceCode': os,
+            'localDiskFlag': local_disk,
+            'blockDevices': [
+                {
+                    'device': '0',
+                    'diskImage': {
+                        'capacity': disk_size,
+                    }
+                }
+            ]
+
+        }
+
+        if datacenter:
+            newCCI['datacenter'] = {'name': datacenter}
 
         res = self.connection.request(
-            "SoftLayer_Product_Order",
-            "placeOrder",
-            res
-        )
+            'SoftLayer_Virtual_Guest', 'createObject', newCCI
+        ).object
 
-        order_id = res['orderId']
-        raw_node = self._get_order_information(order_id)
+        node_id = res['id']
+        raw_node = self._get_order_information(node_id)
 
         return self._to_node(raw_node)
 
     def _to_image(self, img):
         return NodeImage(
-            id=img['id'],
-            name=img['name'],
+            id=img['template']['operatingSystemReferenceCode'],
+            name=img['itemPrice']['item']['description'],
             driver=self.connection.driver
         )
 
     def list_images(self, location=None):
-        return [self._to_image(i) for i in SL_IMAGES]
+        result = self.connection.request(
+            'SoftLayer_Virtual_Guest', 'getCreateObjectOptions'
+        ).object
+        return [self._to_image(i) for i in result['operatingSystems']]
 
     def _to_size(self, id, size):
         return NodeSize(
@@ -426,38 +354,32 @@ class SoftLayerNodeDriver(NodeDriver):
             name=size['name'],
             ram=size['ram'],
             disk=size['disk'],
-            bandwidth=size['bandwidth'],
+            bandwidth=size.get('bandwidth'),
             price=None,
             driver=self.connection.driver,
         )
 
     def list_sizes(self, location=None):
-        return [self._to_size(id, s['imagedata']) for id, s in
-                list(SL_TEMPLATES.items())]
+        return [self._to_size(id, s) for id, s in SL_TEMPLATES.items()]
 
     def _to_loc(self, loc):
-        return NodeLocation(
-            id=loc['id'],
-            name=loc['name'],
-            country=DATACENTERS[loc['name']]['country'],
-            driver=self
-        )
+        country = 'UNKNOWN'
+        if loc['name'] in DATACENTERS:
+            country = DATACENTERS[loc['name']]['country']
+        return NodeLocation(id=loc['name'], name=loc['longName'],
+                            country=country, driver=self)
 
     def list_locations(self):
         res = self.connection.request(
-            "SoftLayer_Location_Datacenter",
-            "getDatacenters"
-        )
-
-        # checking "in DATACENTERS", because some of the locations returned
-        # by getDatacenters are not useable.
-        return [self._to_loc(l) for l in res if l['name'] in DATACENTERS]
+            'SoftLayer_Location_Datacenter', 'getDatacenters'
+        ).object
+        return [self._to_loc(l) for l in res]
 
     def list_nodes(self):
         mask = {
             'virtualGuests': {
                 'powerState': '',
-                'softwareComponents': {'passwords': ''},
+                'operatingSystem': {'passwords': ''},
                 'billingItem': '',
             },
         }
@@ -465,14 +387,5 @@ class SoftLayerNodeDriver(NodeDriver):
             "SoftLayer_Account",
             "getVirtualGuests",
             object_mask=mask
-        )
-        nodes = self._to_nodes(res)
-        return nodes
-
-    def reboot_node(self, node):
-        res = self.connection.request(
-            "SoftLayer_Virtual_Guest",
-            "rebootHard",
-            id=node.id
-        )
-        return res
+        ).object
+        return [self._to_node(h) for h in res]

Modified: libcloud/branches/0.12.x/libcloud/compute/drivers/vcl.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/compute/drivers/vcl.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/compute/drivers/vcl.py (original)
+++ libcloud/branches/0.12.x/libcloud/compute/drivers/vcl.py Tue Feb  5 19:50:18 2013
@@ -16,89 +16,30 @@
 VCL driver
 """
 
-import sys
 import time
 
-from libcloud.utils.py3 import xmlrpclib
-
+from libcloud.common.base import ConnectionUserAndKey
+from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
 from libcloud.common.types import InvalidCredsError, LibcloudError
 from libcloud.compute.types import Provider, NodeState
 from libcloud.compute.base import NodeDriver, Node
 from libcloud.compute.base import NodeSize, NodeImage
 
 
-class VCLSafeTransport(xmlrpclib.SafeTransport):
-    def __init__(self, datetime, user, passwd, host):
-
-        self._pass = passwd
-        self._use_datetime = datetime
-        self._connection = (None, None)
-        self._extra_headers = []
-
-    def send_content(self, connection, request_body):
-        connection.putheader('Content-Type', 'text/xml')
-        connection.putheader('X-APIVERSION', '2')
-        connection.putheader('X-User', self._user)
-        connection.putheader('X-Pass', self._pass)
-        connection.putheader('Content-Length', str(len(request_body)))
-        connection.endheaders(request_body)
-
-
-class VCLProxy(xmlrpclib.ServerProxy):
-    API_POSTFIX = '/index.php?mode=xmlrpccall'
-    transportCls = VCLSafeTransport
-
-    def __init__(self, user, key, secure, host, port, driver, verbose=False):
-        url = ''
-        cls = self.transportCls
-
-        if secure:
-            url = 'https://'
-            port = port or 443
-        else:
-            url = 'http://'
-            port = port or 80
-
-        url += host + ':' + str(port)
-        url += VCLProxy.API_POSTFIX
-
-        self.API = url
-        t = cls(0, user, key, self.API)
-
-        xmlrpclib.ServerProxy.__init__(
-            self,
-            uri=self.API,
-            transport=t,
-            verbose=verbose
-        )
-
-
-class VCLConnection(object):
-    """
-    Connection class for the VCL driver
-    """
+class VCLResponse(XMLRPCResponse):
+    exceptions = {
+        'VCL_Account': InvalidCredsError,
+    }
 
-    proxyCls = VCLProxy
-    driver = None
 
-    def __init__(self, user, key, secure, host, port):
-        self.user = user
-        self.key = key
-        self.secure = secure
-        self.host = host
-        self.port = port
-
-    def request(self, method, *args, **kwargs):
-        sl = self.proxyCls(user=self.user, key=self.key, secure=self.secure,
-                           host=self.host, port=self.port, driver=self.driver)
+class VCLConnection(XMLRPCConnection, ConnectionUserAndKey):
+    endpoint = '/index.php?mode=xmlrpccall'
 
-        try:
-            return getattr(sl, method)(*args)
-        except xmlrpclib.Fault:
-            e = sys.exc_info()[1]
-            if e.faultCode == 'VCL_Account':
-                raise InvalidCredsError(e.faultString)
-            raise LibcloudError(e, driver=self.driver)
+    def add_default_headers(self, headers):
+        headers['X-APIVERSION'] = '2'
+        headers['X-User'] = self.user_id
+        headers['X-Pass'] = self.key
+        return headers
 
 
 class VCLNodeDriver(NodeDriver):
@@ -151,17 +92,15 @@ class VCLNodeDriver(NodeDriver):
             raise Exception('When instantiating VCL driver directly ' +
                             'you also need to provide host')
 
-        self.key = key
-        self.host = host
-        self.secret = secret
-        self.connection = self.connectionCls(key, secret, secure, host, port)
-        self.connection.driver = self
+        super(VCLNodeDriver, self).__init__(key, secret, secure=True,
+                                            host=None, port=None, *args,
+                                            **kwargs)
 
     def _vcl_request(self, method, *args):
         res = self.connection.request(
             method,
             *args
-        )
+        ).object
         if(res['status'] == 'error'):
             raise LibcloudError(res['errormsg'], driver=self)
         return res
@@ -237,7 +176,7 @@ class VCLNodeDriver(NodeDriver):
         """
         res = self.connection.request(
             "XMLRPCgetImages"
-        )
+        ).object
         return [self._to_image(i) for i in res]
 
     def list_sizes(self, location=None):

Modified: libcloud/branches/0.12.x/libcloud/data/pricing.json
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/data/pricing.json?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/data/pricing.json (original)
+++ libcloud/branches/0.12.x/libcloud/data/pricing.json Tue Feb  5 19:50:18 2013
@@ -57,8 +57,8 @@
             "m2.xlarge": 0.50,
             "m2.2xlarge": 1.0,
             "m2.4xlarge": 2.0,
-            "m3.xlarge": 0.58,
-            "m3.2xlarge": 1.16,
+            "m3.xlarge": 0.50,
+            "m3.2xlarge": 1.00,
             "cg1.4xlarge": 2.1,
             "cc1.4xlarge": 1.3,
             "cc2.8xlarge": 2.4,
@@ -76,7 +76,9 @@
             "c1.xlarge": 0.76,
             "m2.xlarge": 0.57,
             "m2.2xlarge": 1.14,
-            "m2.4xlarge": 2.28
+            "m2.4xlarge": 2.28,
+            "m3.xlarge": 0.55,
+            "m3.2xlarge": 1.10
         },
 
         "ec2_us_west_oregon": {
@@ -90,6 +92,8 @@
             "m2.xlarge": 0.50,
             "m2.2xlarge": 1.0,
             "m2.4xlarge": 2.0,
+            "m3.xlarge": 0.50,
+            "m3.2xlarge": 1.00,
             "cc2.8xlarge": 2.400
         },
 
@@ -104,6 +108,8 @@
             "m2.xlarge": 0.57,
             "m2.2xlarge": 1.14,
             "m2.4xlarge": 2.28,
+            "m3.xlarge": 0.55,
+            "m3.2xlarge": 1.10,
             "cc2.8xlarge": 2.7
         },
 
@@ -117,7 +123,9 @@
             "c1.xlarge": 0.76,
             "m2.xlarge": 0.57,
             "m2.2xlarge": 1.14,
-            "m2.4xlarge": 2.28
+            "m2.4xlarge": 2.28,
+            "m3.xlarge": 0.70,
+            "m3.2xlarge": 1.40
         },
 
        "ec2_ap_northeast": {
@@ -130,7 +138,9 @@
             "c1.xlarge": 0.80,
             "m2.xlarge": 0.60,
             "m2.2xlarge": 1.20,
-            "m2.4xlarge": 2.39
+            "m2.4xlarge": 2.39,
+            "m3.xlarge": 0.76,
+            "m3.2xlarge": 1.52
        },
 
         "ec2_sa_east": {
@@ -156,7 +166,9 @@
             "c1.xlarge": 0.744,
             "m2.xlarge": 0.506,
             "m2.2xlarge": 1.012,
-            "m2.4xlarge": 2.024
+            "m2.4xlarge": 2.024,
+            "m3.xlarge": 0.70,
+            "m3.2xlarge": 1.40
         },
 
         "nimbus" : {

Modified: libcloud/branches/0.12.x/libcloud/dns/drivers/gandi.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/dns/drivers/gandi.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/dns/drivers/gandi.py (original)
+++ libcloud/branches/0.12.x/libcloud/dns/drivers/gandi.py Tue Feb  5 19:50:18 2013
@@ -20,6 +20,7 @@ __all__ = [
 ]
 
 from libcloud.common.gandi import BaseGandiDriver, GandiConnection
+from libcloud.common.gandi import GandiResponse
 from libcloud.dns.types import Provider, RecordType
 from libcloud.dns.types import RecordError
 from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
@@ -51,7 +52,7 @@ class NewZoneVersion(object):
     def __enter__(self):
         zid = int(self.zone.id)
         self.connection.set_context({'zone_id': self.zone.id})
-        vid = self.connection.request('domain.zone.version.new', zid)
+        vid = self.connection.request('domain.zone.version.new', zid).object
         self.vid = vid
         return vid
 
@@ -60,16 +61,17 @@ class NewZoneVersion(object):
             zid = int(self.zone.id)
             con = self.connection
             con.set_context({'zone_id': self.zone.id})
-            con.request('domain.zone.version.set', zid, self.vid)
+            con.request('domain.zone.version.set', zid, self.vid).object
 
 
-class GandiDNSConnection(GandiConnection):
+class GandiDNSResponse(GandiResponse):
+    exceptions = {
+        581042: ZoneDoesNotExistError,
+    }
+
 
-    def parse_error(self, code, message):
-        if code == 581042:
-            zone_id = str(self.context.get('zone_id', None))
-            raise ZoneDoesNotExistError(value='', driver=self.driver,
-                                        zone_id=zone_id)
+class GandiDNSConnection(GandiConnection):
+    responseCls = GandiDNSResponse
 
 
 class GandiDNSDriver(BaseGandiDriver, DNSDriver):
@@ -100,7 +102,7 @@ class GandiDNSDriver(BaseGandiDriver, DN
 
     def _to_zone(self, zone):
         return Zone(
-            id=zone['id'],
+            id=str(zone['id']),
             domain=zone['name'],
             type='master',
             ttl=0,
@@ -116,31 +118,33 @@ class GandiDNSDriver(BaseGandiDriver, DN
 
     def list_zones(self):
         zones = self.connection.request('domain.zone.list')
-        return self._to_zones(zones)
+        return self._to_zones(zones.object)
 
     def get_zone(self, zone_id):
         zid = int(zone_id)
-        self.connection.set_context({'zone_id': zid})
+        self.connection.set_context({'zone_id': zone_id})
         zone = self.connection.request('domain.zone.info', zid)
-        return self._to_zone(zone)
+        return self._to_zone(zone.object)
 
     def create_zone(self, domain, type='master', ttl=None, extra=None):
-        params = {'name': domain}
+        params = {
+            'name': domain,
+        }
         info = self.connection.request('domain.zone.create', params)
-        return self._to_zone(info)
+        return self._to_zone(info.object)
 
     def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
         zid = int(zone.id)
         params = {'name': domain}
-        self.connection.set_context({'zone_id': zid})
+        self.connection.set_context({'zone_id': zone.id})
         zone = self.connection.request('domain.zone.update', zid, params)
-        return self._to_zone(zone)
+        return self._to_zone(zone.object)
 
     def delete_zone(self, zone):
         zid = int(zone.id)
-        self.connection.set_context({'zone_id': zid})
+        self.connection.set_context({'zone_id': zone.id})
         res = self.connection.request('domain.zone.delete', zid)
-        return res
+        return res.object
 
     def _to_record(self, record, zone):
         return Record(
@@ -161,9 +165,9 @@ class GandiDNSDriver(BaseGandiDriver, DN
 
     def list_records(self, zone):
         zid = int(zone.id)
-        self.connection.set_context({'zone_id': zid})
+        self.connection.set_context({'zone_id': zone.id})
         records = self.connection.request('domain.zone.record.list', zid, 0)
-        return self._to_records(records, zone)
+        return self._to_records(records.object, zone)
 
     def get_record(self, zone_id, record_id):
         zid = int(zone_id)
@@ -172,9 +176,9 @@ class GandiDNSDriver(BaseGandiDriver, DN
             'name': name,
             'type': record_type
         }
-        self.connection.set_context({'zone_id': zid})
+        self.connection.set_context({'zone_id': zone_id})
         records = self.connection.request('domain.zone.record.list',
-                                          zid, 0, filter_opts)
+                                          zid, 0, filter_opts).object
 
         if len(records) == 0:
             raise RecordDoesNotExistError(value='', driver=self,
@@ -210,9 +214,9 @@ class GandiDNSDriver(BaseGandiDriver, DN
 
         with NewZoneVersion(self, zone) as vid:
             con = self.connection
-            con.set_context({'zone_id': zid})
+            con.set_context({'zone_id': zone.id})
             rec = con.request('domain.zone.record.add',
-                              zid, vid, create)
+                              zid, vid, create).object
 
         return self._to_record(rec, zone)
 
@@ -237,11 +241,11 @@ class GandiDNSDriver(BaseGandiDriver, DN
 
         with NewZoneVersion(self, record.zone) as vid:
             con = self.connection
-            con.set_context({'zone_id': zid})
+            con.set_context({'zone_id': record.zone.id})
             con.request('domain.zone.record.delete',
                         zid, vid, filter_opts)
             res = con.request('domain.zone.record.add',
-                              zid, vid, update)
+                              zid, vid, update).object
 
         return self._to_record(res, record.zone)
 
@@ -255,9 +259,9 @@ class GandiDNSDriver(BaseGandiDriver, DN
 
         with NewZoneVersion(self, record.zone) as vid:
             con = self.connection
-            con.set_context({'zone_id': zid})
+            con.set_context({'zone_id': record.zone.id})
             count = con.request('domain.zone.record.delete',
-                                zid, vid, filter_opts)
+                                zid, vid, filter_opts).object
 
         if count == 1:
             return True

Modified: libcloud/branches/0.12.x/libcloud/dns/drivers/hostvirtual.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/dns/drivers/hostvirtual.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/dns/drivers/hostvirtual.py (original)
+++ libcloud/branches/0.12.x/libcloud/dns/drivers/hostvirtual.py Tue Feb  5 19:50:18 2013
@@ -21,8 +21,6 @@ from libcloud.utils.misc import merge_va
 from libcloud.common.hostvirtual import HostVirtualResponse
 from libcloud.common.hostvirtual import HostVirtualConnection
 from libcloud.compute.drivers.hostvirtual import API_ROOT
-from libcloud.compute.drivers.hostvirtual import HostVirtualConnection
-from libcloud.compute.drivers.hostvirtual import HostVirtualResponse
 from libcloud.dns.types import Provider, RecordType
 from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
 from libcloud.dns.base import DNSDriver, Zone, Record

Modified: libcloud/branches/0.12.x/libcloud/test/common/test_gandi.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/common/test_gandi.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/common/test_gandi.py (original)
+++ libcloud/branches/0.12.x/libcloud/test/common/test_gandi.py Tue Feb  5 19:50:18 2013
@@ -1,33 +1,15 @@
-import sys
-import unittest
-
-from xml.etree import ElementTree as ET
-
 from libcloud.utils.py3 import xmlrpclib
+from libcloud.test import MockHttp
 
 
-class MockGandiTransport(xmlrpclib.Transport):
-
-    def request(self, host, handler, request_body, verbose=0):
-        self.verbose = 0
-        method = ET.XML(request_body).find('methodName').text
-        mock = self.mockCls(host, 80)
-        mock.request('POST', '%s/%s' % (handler, method))
-        resp = mock.getresponse()
-
-        if sys.version[0] == '2' and sys.version[2] == '7':
-            response = self.parse_response(resp)
-        else:
-            response = self.parse_response(resp.body)
-        return response
-
+class BaseGandiMockHttp(MockHttp):
 
-class BaseGandiTests(unittest.TestCase):
+    def _get_method_name(self, type, use_param, qs, path):
+        return "_xmlrpc"
 
-    def setUp(self):
-        d = self.driverCls
-        t = self.transportCls
-        t.mockCls.type = None
-        d.connectionCls.proxyCls.transportCls = \
-            [t, t]
-        self.driver = d(*self.params)
+    def _xmlrpc(self, method, url, body, headers):
+        params, methodName = xmlrpclib.loads(body)
+        meth_name = '_xmlrpc__' + methodName.replace('.', '_')
+        if self.type:
+            meth_name = '%s_%s' % (meth_name, self.type)
+        return getattr(self, meth_name)(method, url, body, headers)

Modified: libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json (original)
+++ libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json Tue Feb  5 19:50:18 2013
@@ -1,62 +1,72 @@
-[
-  {
-    "host": "659",
-    "rescue": "0",
-    "fqdn": "server1.vr-cluster.org",
-    "mbpkgid": "62291",
-    "locked": "0",
-    "os": "Debian 6 i386 PV",
-    "ip": "208.111.45.250",
-    "installed": "0",
-    "state": "DOWN",
-    "package": "VR512",
-    "ipv6": "2607:f740:10::f98",
-    "city": "MAA - Chennai (Madras), India",
-    "status": "TERMINATED"
-  },
-  {
-    "host": "902",
-    "rescue": "0",
-    "fqdn": "newbuild.vr.com",
-    "mbpkgid": "62327",
-    "locked": "0",
-    "os": "CentOS 5.8 x64",
-    "ip": "208.111.39.118",
-    "installed": "0",
-    "state": "DOWN",
-    "package": "VR512",
-    "ipv6": "2607:f740:0:3f::f0d",
-    "city": "SJC - San Jose, CA",
-    "status": "TERMINATED"
-  },
-  {
-    "host": "1010",
-    "rescue": "0",
-    "fqdn": "3test.build.com",
-    "mbpkgid": "62300",
-    "locked": "0",
-    "os": "CentOS 6.2 x64",
-    "ip": "208.111.40.179",
-    "installed": "0",
-    "state": "DOWN",
-    "package": "VR512",
-    "ipv6": "2607:f740:c::f4f",
-    "city": "LAX3 - Los Angeles, CA",
-    "status": "TERMINATED"
-  },
-  {
-    "host": "1028",
-    "rescue": "0",
-    "fqdn": "libcloud2.node.com",
-    "mbpkgid": "74567",
-    "locked": "0",
-    "os": "CentOS 5.8 x64",
-    "ip": "209.177.157.99",
-    "installed": "1",
-    "state": "UP",
-    "package": "VR512",
-    "ipv6": "2607:f740:b::eff",
-    "city": "IAD2- Reston, VA",
-    "status": "RUNNING"
-  }
-]
+[{
+	"host": "659",
+	"rescue": "0",
+	"fqdn": "server1.vr-cluster.org",
+	"mbpkgid": "62291",
+	"locked": "0",
+	"os": "Debian 6 i386 PV",
+	"ip": "208.111.45.250",
+	"installed": "0",
+	"state": "DOWN",
+	"package": "VR512",
+	"ipv6": "2607:f740:10::f98",
+	"city": "MAA - Chennai (Madras), India",
+	"status": "TERMINATED",
+	"os_id" : "1613",
+	"location_id" : "3",
+	"plan_id" : "51"
+},
+{
+	"host": "902",
+	"rescue": "0",
+	"fqdn": "newbuild.vr.com",
+	"mbpkgid": "62327",
+	"locked": "0",
+	"os": "CentOS 5.8 x64",
+	"ip": "208.111.39.118",
+	"installed": "0",
+	"state": "DOWN",
+	"package": "VR512",
+	"ipv6": "2607:f740:0:3f::f0d",
+	"city": "SJC - San Jose, CA",
+	"status": "TERMINATED",
+	"os_id" : "1613",
+	"location_id" : "3",
+	"plan_id" : "51"
+},
+{
+	"host": "1010",
+	"rescue": "0",
+	"fqdn": "3test.build.com",
+	"mbpkgid": "62300",
+	"locked": "0",
+	"os": "CentOS 6.2 x64",
+	"ip": "208.111.40.179",
+	"installed": "0",
+	"state": "DOWN",
+	"package": "VR512",
+	"ipv6": "2607:f740:c::f4f",
+	"city": "LAX3 - Los Angeles, CA",
+	"status": "TERMINATED",
+	"os_id" : "1613",
+	"location_id" : "3",
+	"plan_id" : "51"
+},
+{
+	"host": "1028",
+	"rescue": "0",
+	"fqdn": "libcloud2.node.com",
+	"mbpkgid": "74567",
+	"locked": "0",
+	"os": "CentOS 5.8 x64",
+	"ip": "209.177.157.99",
+	"installed": "1",
+	"state": "UP",
+	"package": "VR512",
+	"ipv6": "2607:f740:b::eff",
+	"city": "IAD2- Reston, VA",
+	"status": "RUNNING",
+	"os_id" : "1613",
+	"location_id" : "3",
+	"plan_id" : "51"
+}]

Modified: libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json (original)
+++ libcloud/branches/0.12.x/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json Tue Feb  5 19:50:18 2013
@@ -1,82 +1,128 @@
 [
   {
+    "plan_id": "31",
     "plan": "VR256",
     "ram": "256MB",
     "disk": "10GB",
     "transfer": "200GB",
     "price": "10.00",
-    "available": "1421"
+    "available": "1167"
   },
   {
+    "plan_id": "41",
     "plan": "VR384",
     "ram": "384MB",
     "disk": "15GB",
     "transfer": "300GB",
     "price": "15.00",
-    "available": "939"
+    "available": "768"
   },
   {
+    "plan_id": "51",
     "plan": "VR512",
     "ram": "512MB",
     "disk": "20GB",
     "transfer": "400GB",
     "price": "20.00",
-    "available": "713"
+    "available": "620"
   },
   {
+    "plan_id": "61",
     "plan": "VR768",
     "ram": "768MB",
     "disk": "30GB",
     "transfer": "600GB",
     "price": "30.00",
-    "available": "476"
+    "available": "403"
   },
   {
+    "plan_id": "71",
     "plan": "VR1024",
     "ram": "1024MB",
     "disk": "40GB",
     "transfer": "800GB",
     "price": "40.00",
-    "available": "350"
+    "available": "304"
   },
   {
+    "plan_id": "81",
     "plan": "VR1280",
     "ram": "1280MB",
     "disk": "50GB",
     "transfer": "1000GB",
     "price": "50.00",
-    "available": "276"
+    "available": "234"
   },
   {
+    "plan_id": "91",
     "plan": "VR1536",
     "ram": "1536MB",
     "disk": "60GB",
     "transfer": "1200GB",
     "price": "60.00",
-    "available": "226"
+    "available": "190"
   },
   {
+    "plan_id": "101",
     "plan": "VR2048",
     "ram": "2048MB",
     "disk": "80GB",
     "transfer": "1600GB",
     "price": "80.00",
-    "available": "160"
+    "available": "138"
   },
   {
+    "plan_id": "128",
+    "plan": "VRBL1G",
+    "ram": "1024MB",
+    "disk": "50GB",
+    "transfer": "1000GB",
+    "price": "150.00",
+    "available": "34"
+  },
+  {
+    "plan_id": "111",
     "plan": "VR4048",
     "ram": "4048MB",
     "disk": "160GB",
     "transfer": "3200GB",
     "price": "160.00",
-    "available": "69"
+    "available": "60"
+  },
+  {
+    "plan_id": "137",
+    "plan": "VRBL2G",
+    "ram": "2048MB",
+    "disk": "100GB",
+    "transfer": "2000GB",
+    "price": "200.00",
+    "available": "16"
+  },
+  {
+    "plan_id": "146",
+    "plan": "VRBL4G",
+    "ram": "4048MB",
+    "disk": "150GB",
+    "transfer": "3000GB",
+    "price": "300.00",
+    "available": "8"
   },
   {
+    "plan_id": "119",
     "plan": "VR8096",
     "ram": "8096MB",
     "disk": "320GB",
     "transfer": "6400GB",
     "price": "320.00",
-    "available": "9"
+    "available": "11"
+  },
+  {
+    "plan_id": "155",
+    "plan": "VRBL8G",
+    "ram": "8096MB",
+    "disk": "200GB",
+    "transfer": "5000GB",
+    "price": "400.00",
+    "available": "4"
   }
 ]

Modified: libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Account_getVirtualGuests.xml
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Account_getVirtualGuests.xml?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Account_getVirtualGuests.xml (original)
+++ libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Account_getVirtualGuests.xml Tue Feb  5 19:50:18 2013
@@ -116,9 +116,8 @@
        </value>
       </member>
       <member>
-       <name>softwareComponents</name>
+       <name>operatingSystem</name>
        <value>
-        <array>
          <data>
           <value>
            <struct>
@@ -198,7 +197,6 @@
            </struct>
           </value>
          </data>
-        </array>
        </value>
       </member>
       <member>
@@ -1064,3 +1062,4 @@
  </value>
 </param>
 </params>
+

Modified: libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Location_Datacenter_getDatacenters.xml
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Location_Datacenter_getDatacenters.xml?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Location_Datacenter_getDatacenters.xml (original)
+++ libcloud/branches/0.12.x/libcloud/test/compute/fixtures/softlayer/v3_SoftLayer_Location_Datacenter_getDatacenters.xml Tue Feb  5 19:50:18 2013
@@ -15,13 +15,13 @@
       <member>
        <name>name</name>
        <value>
-        <string>dal00</string>
+        <string>dal05</string>
        </value>
       </member>
       <member>
        <name>longName</name>
        <value>
-        <string>Corporate HQ</string>
+        <string>Dallas 5</string>
        </value>
       </member>
      </struct>
@@ -92,6 +92,28 @@
       </member>
      </struct>
     </value>
+    <value>
+     <struct>
+      <member>
+       <name>id</name>
+       <value>
+        <int>12345</int>
+       </value>
+      </member>
+      <member>
+       <name>name</name>
+       <value>
+        <string>newcity01</string>
+       </value>
+      </member>
+      <member>
+       <name>longName</name>
+       <value>
+        <string>New City</string>
+       </value>
+      </member>
+     </struct>
+    </value>
    </data>
   </array>
  </value>

Modified: libcloud/branches/0.12.x/libcloud/test/compute/test_ec2.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/compute/test_ec2.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/compute/test_ec2.py (original)
+++ libcloud/branches/0.12.x/libcloud/test/compute/test_ec2.py Tue Feb  5 19:50:18 2013
@@ -231,9 +231,9 @@ class EC2Tests(LibcloudTestCase, TestCas
                 self.assertTrue('cc2.8xlarge' in ids)
                 self.assertTrue('cr1.8xlarge' in ids)
             elif region_name == 'eu-west-1':
-                self.assertEqual(len(sizes), 11)
+                self.assertEqual(len(sizes), 13)
             else:
-                self.assertEqual(len(sizes), 10)
+                self.assertEqual(len(sizes), 12)
 
         self.driver.region_name = region_old
 

Modified: libcloud/branches/0.12.x/libcloud/test/compute/test_gandi.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/test/compute/test_gandi.py?rev=1442714&r1=1442713&r2=1442714&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/test/compute/test_gandi.py (original)
+++ libcloud/branches/0.12.x/libcloud/test/compute/test_gandi.py Tue Feb  5 19:50:18 2013
@@ -19,125 +19,26 @@ import random
 import string
 
 from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import xmlrpclib
 
 from libcloud.compute.drivers.gandi import GandiNodeDriver
-from libcloud.compute.base import StorageVolume
 from libcloud.common.gandi import GandiException
 from libcloud.compute.types import NodeState
 
-from xml.etree import ElementTree as ET
-from libcloud.test import MockHttp
 from libcloud.test.file_fixtures import ComputeFileFixtures
 from libcloud.test.secrets import GANDI_PARAMS
-from libcloud.test.common.test_gandi import MockGandiTransport, BaseGandiTests
+from libcloud.test.common.test_gandi import BaseGandiMockHttp
 
 
-class GandiMockHttp(MockHttp):
-
-    fixtures = ComputeFileFixtures('gandi')
-
-    def _xmlrpc__datacenter_list(self, method, url, body, headers):
-        body = self.fixtures.load('datacenter_list.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__image_list(self, method, url, body, headers):
-        body = self.fixtures.load('image_list_dc0.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_list(self, method, url, body, headers):
-        body = self.fixtures.load('vm_list.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__ip_list(self, method, url, body, headers):
-        body = self.fixtures.load('ip_list.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__account_info(self, method, url, body, headers):
-        body = self.fixtures.load('account_info.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_info(self, method, url, body, headers):
-        body = self.fixtures.load('vm_info.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_delete(self, method, url, body, headers):
-        body = self.fixtures.load('vm_delete.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__operation_info(self, method, url, body, headers):
-        body = self.fixtures.load('operation_info.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_create_from(self, method, url, body, headers):
-        body = self.fixtures.load('vm_create_from.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_reboot(self, method, url, body, headers):
-        body = self.fixtures.load('vm_reboot.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_stop(self, method, url, body, headers):
-        body = self.fixtures.load('vm_stop.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__iface_list(self, method, url, body, headers):
-        body = self.fixtures.load('iface_list.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__disk_list(self, method, url, body, headers):
-        body = self.fixtures.load('disk_list.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_iface_attach(self, method, url, body, headers):
-        body = self.fixtures.load('iface_attach.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_iface_detach(self, method, url, body, headers):
-        body = self.fixtures.load('iface_detach.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_disk_attach(self, method, url, body, headers):
-        body = self.fixtures.load('disk_attach.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__vm_disk_detach(self, method, url, body, headers):
-        body = self.fixtures.load('disk_detach.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__disk_create(self, method, url, body, headers):
-        body = self.fixtures.load('disk_create.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__disk_create_from(self, method, url, body, headers):
-        body = self.fixtures.load('disk_create_from.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__disk_info(self, method, url, body, headers):
-        body = self.fixtures.load('disk_info.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__disk_update(self, method, url, body, headers):
-        body = self.fixtures.load('disk_update.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _xmlrpc__disk_delete(self, method, url, body, headers):
-        body = self.fixtures.load('disk_delete.xml')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-
-class DummyTransport(MockGandiTransport):
-    mockCls = GandiMockHttp
-
-
-class GandiTests(BaseGandiTests):
-
-    driverCls = GandiNodeDriver
-    transportCls = DummyTransport
-    params = GANDI_PARAMS
+class GandiTests(unittest.TestCase):
 
     node_name = 'test2'
 
+    def setUp(self):
+        GandiNodeDriver.connectionCls.conn_classes = (
+            GandiMockHttp, GandiMockHttp)
+        GandiMockHttp.type = None
+        self.driver = GandiNodeDriver(*GANDI_PARAMS)
+
     def test_list_nodes(self):
         nodes = self.driver.list_nodes()
         self.assertTrue(len(nodes) > 0)
@@ -254,5 +155,98 @@ class GandiTests(BaseGandiTests):
         self.assertTrue(self.driver.ex_update_disk(disks[0], new_size=4096))
 
 
+class GandiMockHttp(BaseGandiMockHttp):
+
+    fixtures = ComputeFileFixtures('gandi')
+
+    def _xmlrpc__datacenter_list(self, method, url, body, headers):
+        body = self.fixtures.load('datacenter_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__image_list(self, method, url, body, headers):
+        body = self.fixtures.load('image_list_dc0.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_list(self, method, url, body, headers):
+        body = self.fixtures.load('vm_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__ip_list(self, method, url, body, headers):
+        body = self.fixtures.load('ip_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__account_info(self, method, url, body, headers):
+        body = self.fixtures.load('account_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_info(self, method, url, body, headers):
+        body = self.fixtures.load('vm_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_delete(self, method, url, body, headers):
+        body = self.fixtures.load('vm_delete.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__operation_info(self, method, url, body, headers):
+        body = self.fixtures.load('operation_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_create_from(self, method, url, body, headers):
+        body = self.fixtures.load('vm_create_from.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_reboot(self, method, url, body, headers):
+        body = self.fixtures.load('vm_reboot.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_stop(self, method, url, body, headers):
+        body = self.fixtures.load('vm_stop.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__iface_list(self, method, url, body, headers):
+        body = self.fixtures.load('iface_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__disk_list(self, method, url, body, headers):
+        body = self.fixtures.load('disk_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_iface_attach(self, method, url, body, headers):
+        body = self.fixtures.load('iface_attach.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_iface_detach(self, method, url, body, headers):
+        body = self.fixtures.load('iface_detach.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_disk_attach(self, method, url, body, headers):
+        body = self.fixtures.load('disk_attach.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__vm_disk_detach(self, method, url, body, headers):
+        body = self.fixtures.load('disk_detach.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__disk_create(self, method, url, body, headers):
+        body = self.fixtures.load('disk_create.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__disk_create_from(self, method, url, body, headers):
+        body = self.fixtures.load('disk_create_from.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__disk_info(self, method, url, body, headers):
+        body = self.fixtures.load('disk_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__disk_update(self, method, url, body, headers):
+        body = self.fixtures.load('disk_update.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__disk_delete(self, method, url, body, headers):
+        body = self.fixtures.load('disk_delete.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+
 if __name__ == '__main__':
     sys.exit(unittest.main())



Mime
View raw message