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 2011/03/24 20:52:41 UTC

svn commit: r1085099 - in /incubator/libcloud/trunk: libcloud/compute/ libcloud/compute/drivers/ libcloud/data/ test/ test/compute/ test/compute/fixtures/gandi/

Author: tomaz
Date: Thu Mar 24 19:52:40 2011
New Revision: 1085099

URL: http://svn.apache.org/viewvc?rev=1085099&view=rev
Log:
Add Gandi.net compute driver.

Changes submitted by Aymeric Barantal <mric at gandi dot net> as a part
of LIBCLOUD-76.

Added:
    incubator/libcloud/trunk/libcloud/compute/drivers/gandi.py
    incubator/libcloud/trunk/test/compute/fixtures/gandi/
    incubator/libcloud/trunk/test/compute/fixtures/gandi/account_info.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/datacenter_list.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/image_list_dc0.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/ip_list.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/operation_info.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_create_from.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_delete.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_info.xml
    incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_list.xml
    incubator/libcloud/trunk/test/compute/test_gandi.py
Modified:
    incubator/libcloud/trunk/libcloud/compute/providers.py
    incubator/libcloud/trunk/libcloud/compute/types.py
    incubator/libcloud/trunk/libcloud/data/pricing.json
    incubator/libcloud/trunk/test/secrets.py-dist

Added: incubator/libcloud/trunk/libcloud/compute/drivers/gandi.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/compute/drivers/gandi.py?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/compute/drivers/gandi.py (added)
+++ incubator/libcloud/trunk/libcloud/compute/drivers/gandi.py Thu Mar 24 19:52:40 2011
@@ -0,0 +1,367 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+Gandi driver
+"""
+
+import time
+import xmlrpclib
+
+import libcloud
+from libcloud.compute.types import Provider, NodeState
+from libcloud.compute.base import NodeDriver, Node, NodeLocation, NodeSize, NodeImage
+
+# Global constants
+API_VERSION = '2.0'
+API_PREFIX = "https://rpc.gandi.net/xmlrpc/%s/" % API_VERSION
+
+DEFAULT_TIMEOUT = 600   # operation pooling max seconds
+DEFAULT_INTERVAL = 20   # seconds between 2 operation.info
+
+NODE_STATE_MAP = {
+    'running': NodeState.RUNNING,
+    'halted': NodeState.TERMINATED,
+    'paused': NodeState.TERMINATED,
+    'locked' : NodeState.TERMINATED,
+    'being_created' : NodeState.PENDING,
+    'invalid' : NodeState.UNKNOWN,
+    'legally_locked' : NodeState.PENDING,
+    'deleted' : NodeState.TERMINATED
+}
+
+NODE_PRICE_HOURLY_USD = 0.02
+
+class GandiException(Exception):
+    """
+    Exception class for Gandi driver
+    """
+    def __str__(self):
+        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
+
+class GandiProxy(xmlrpclib.ServerProxy):
+    transportCls = (GandiTransport, GandiSafeTransport)
+
+    def __init__(self,user_agent, verbose=0):
+        cls = self.transportCls[0]
+        if API_PREFIX.startswith("https://"):
+            cls = self.transportCls[1]
+        t = cls(use_datetime=0)
+        t.user_agent = user_agent
+        xmlrpclib.ServerProxy.__init__(
+            self,
+            uri="%s" % (API_PREFIX),
+            transport=t,
+            verbose=verbose,
+            allow_none=True
+        )
+
+class GandiConnection(object):
+    """
+    Connection class for the Gandi driver
+    """
+
+    proxyCls = GandiProxy
+    driver = 'gandi'
+
+    def __init__(self, user, password=None):
+        self.ua = []
+
+        # Connect only with an api_key generated on website
+        self.api_key = user
+
+        try:
+            self._proxy = self.proxyCls(self._user_agent())
+        except xmlrpclib.Fault, e:
+            raise GandiException(1000, e)
+
+    def _user_agent(self):
+        return 'libcloud/%s (%s)%s' % (
+                libcloud.__version__,
+                self.driver,
+                "".join([" (%s)" % x for x in self.ua]))
+
+    def user_agent_append(self, s):
+        self.ua.append(s)
+
+    def request(self,method,*args):
+        """ Request xmlrpc method with given args"""
+        try:
+            return getattr(self._proxy, method)(self.api_key,*args)
+        except xmlrpclib.Fault, e:
+            raise GandiException(1001, e)
+
+
+class GandiNodeDriver(NodeDriver):
+    """
+    Gandi node driver
+
+    """
+    connectionCls = GandiConnection
+    name = 'Gandi'
+    api_name = 'gandi'
+    friendly_name = 'Gandi.net'
+    country = 'FR'
+    type = Provider.GANDI
+    # TODO : which features to enable ?
+    features = { }
+
+    def __init__(self, key, secret=None, secure=False):
+        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):
+        """ Wait for an operation to succeed"""
+
+        for i in range(0, timeout, check_interval):
+            try:
+                op = self.connection.request('operation.info', int(id))
+
+                if op['step'] == 'DONE':
+                    return True
+                if op['step'] in  ['ERROR','CANCEL']:
+                    return False
+            except (KeyError, IndexError):
+                pass
+            except Exception, e:
+                raise GandiException(1002, e)
+
+            time.sleep(check_interval)
+        return False
+
+    def _node_info(self,id):
+        try:
+            obj = self.connection.request('vm.info',int(id))
+            return obj
+        except Exception,e:
+            raise GandiException(1003, e)
+        return None
+
+    # Generic methods for driver
+    def _to_node(self, vm):
+        return Node(
+            id=vm['id'],
+            name=vm['hostname'],
+            state=NODE_STATE_MAP.get(
+                vm['state'],
+                NodeState.UNKNOWN
+            ),
+            public_ip=vm.get('ip'),
+            private_ip='',
+            driver=self,
+            extra={
+                'ai_active' : vm.get('ai_active'),
+                'datacenter_id' : vm.get('datacenter_id'),
+                'description' : vm.get('description')
+            }
+        )
+
+    def _to_nodes(self, vms):
+        return [self._to_node(v) for v in vms]
+
+    def list_nodes(self):
+        vms = self.connection.request('vm.list')
+        ips = self.connection.request('ip.list')
+        for vm in vms:
+            for ip in ips:
+                if vm['ifaces_id'][0] == ip['iface_id']:
+                    vm['ip'] = ip.get('ip')
+
+        nodes = self._to_nodes(vms)
+        return nodes
+
+    def reboot_node(self, node):
+        op = self.connection.request('vm.reboot',int(node.id))
+        op_res = self._wait_operation(op['id'])
+        vm = self.connection.request('vm.info',int(node.id))
+        if vm['state'] == 'running':
+            return True
+        return False
+
+    def destroy_node(self, node):
+        vm = self._node_info(node.id)
+        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']):
+                raise GandiException(1010, 'vm.stop failed')
+        # Delete
+        op = self.connection.request('vm.delete',int(node.id))
+        if self._wait_operation(op['id']):
+            return True
+        return False
+
+    def deploy_node(self, **kwargs):
+        raise NotImplementedError, \
+            'deploy_node not implemented for gandi driver'
+
+    def create_node(self, **kwargs):
+        """Create a new Gandi node
+
+        @keyword    name:   String with a name for this new node (required)
+        @type       name:   str
+
+        @keyword    image:  OS Image to boot on node. (required)
+        @type       image:  L{NodeImage}
+
+        @keyword    location: Which data center to create a node in. If empty,
+                              undefined behavoir will be selected. (optional)
+        @type       location: L{NodeLocation}
+
+        @keyword    size:   The size of resources allocated to this node.
+                            (required)
+        @type       size:   L{NodeSize}
+
+        @keyword    login:  user name to create for login on this machine (required)
+        @type       login: String
+
+        @keyword    password: password for user that'll be created (required)
+        @type       password: String
+
+        @keywork    inet_family: version of ip to use, default 4 (optional)
+        @type       inet_family: int
+        """
+
+        if kwargs.get('login') is None or kwargs.get('password') is None:
+            raise GandiException(1020, 'login and password must be defined for node creation')
+
+        location = kwargs.get('location')
+        if location and isinstance(location,NodeLocation):
+            dc_id = int(location.id)
+        else:
+            raise GandiException(1021, 'location must be a subclass of NodeLocation')
+
+        size = kwargs.get('size')
+        if not size and not isinstance(size,NodeSize):
+            raise GandiException(1022, 'size must be a subclass of NodeSize')
+
+        src_disk_id = int(kwargs['image'].id)
+
+        disk_spec = {
+            'datacenter_id': dc_id,
+            'name': 'disk_%s' % kwargs['name']
+            }
+
+        vm_spec = {
+            'datacenter_id': dc_id,
+            'hostname': kwargs['name'],
+            'login': kwargs['login'],
+            'password': kwargs['password'],  # TODO : use NodeAuthPassword
+            'memory': int(size.ram),
+            'cores': int(size.id),
+            'bandwidth' : int(size.bandwidth),
+            'ip_version':  kwargs.get('inet_family',4),
+            }
+
+        # Call create_from helper api. Return 3 operations : disk_create,
+        # iface_create,vm_create
+        (op_disk,op_iface,op_vm) = self.connection.request(
+            'vm.create_from',
+            vm_spec,disk_spec,src_disk_id
+        )
+
+        # We wait for vm_create to finish
+        if self._wait_operation(op_vm['id']):
+            # after successful operation, get ip information thru first interface
+            node = self._node_info(op_vm['vm_id'])
+            ifaces = node.get('ifaces')
+            if len(ifaces) > 0:
+                ips = ifaces[0].get('ips')
+                if len(ips) > 0:
+                    node['ip'] = ips[0]['ip']
+            return self._to_node(node)
+
+        return None
+
+    def _to_image(self, img):
+        return NodeImage(
+            id=img['disk_id'],
+            name=img['label'],
+            driver=self.connection.driver
+        )
+
+    def list_images(self, location=None):
+        try:
+            if location:
+                filtering = { 'datacenter_id' : int(location.id) }
+            else:
+                filtering = {}
+            images = self.connection.request('image.list', filtering )
+            return [self._to_image(i) for i in images]
+        except Exception, e:
+            raise GandiException(1011, e)
+
+    def _to_size(self, id, size):
+        return NodeSize(
+            id=id,
+            name='%s cores' % id,
+            ram=size['memory'],
+            disk=size['disk'],
+            bandwidth=size['bandwidth'],
+            price=(self._get_size_price(size_id='1') * id),
+            driver=self.connection.driver,
+        )
+
+    def list_sizes(self, location=None):
+        account = self.connection.request('account.info')
+        # Look for available shares, and return a list of share_definition
+        available_res = account['resources']['available']
+
+        if available_res['shares'] == 0:
+            return None
+        else:
+            share_def = account['share_definition']
+            available_cores = available_res['cores']
+            # 0.75 core given when creating a server
+            max_core = int(available_cores + 0.75)
+            shares = []
+            if available_res['servers'] < 1:
+                # No server quota, no way
+                return shares
+            for i in range(1,max_core + 1):
+                share = {id:i}
+                share_is_available = True
+                for k in ['memory', 'disk', 'bandwidth']:
+                    if share_def[k] * i > available_res[k]:
+                        # We run out for at least one resource inside
+                        share_is_available = False
+                    else:
+                        share[k] = share_def[k] * i
+                if share_is_available:
+                    nb_core = i
+                    shares.append(self._to_size(nb_core,share))
+            return shares
+
+    def _to_loc(self, loc):
+        return NodeLocation(
+            id=loc['id'],
+            name=loc['name'],
+            country=loc['country'],
+            driver=self
+        )
+
+    def list_locations(self):
+        res = self.connection.request("datacenter.list")
+        return [self._to_loc(l) for l in res]

Modified: incubator/libcloud/trunk/libcloud/compute/providers.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/compute/providers.py?rev=1085099&r1=1085098&r2=1085099&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/compute/providers.py (original)
+++ incubator/libcloud/trunk/libcloud/compute/providers.py Thu Mar 24 19:52:40 2011
@@ -77,6 +77,8 @@ DRIVERS = {
         ('libcloud.compute.drivers.ec2', 'NimbusNodeDriver'),
     Provider.BLUEBOX:
         ('libcloud.compute.drivers.bluebox', 'BlueboxNodeDriver'),
+    Provider.GANDI:
+        ('libcloud.compute.drivers.gandi', 'GandiNodeDriver'),
 }
 
 def get_driver(provider):

Modified: incubator/libcloud/trunk/libcloud/compute/types.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/compute/types.py?rev=1085099&r1=1085098&r2=1085099&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/compute/types.py (original)
+++ incubator/libcloud/trunk/libcloud/compute/types.py Thu Mar 24 19:52:40 2011
@@ -85,6 +85,7 @@ class Provider(object):
     EC2_AP_NORTHEAST = 26
     NIMBUS = 27
     BLUEBOX = 28
+    GANDI = 29
 
 class NodeState(object):
     """

Modified: incubator/libcloud/trunk/libcloud/data/pricing.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/data/pricing.json?rev=1085099&r1=1085098&r2=1085099&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/data/pricing.json (original)
+++ incubator/libcloud/trunk/libcloud/data/pricing.json Thu Mar 24 19:52:40 2011
@@ -106,7 +106,7 @@
 
     "elastichosts": {
        "small": 0.100,
-       "medium": 0.223, 
+       "medium": 0.223,
        "large": 0.378,
        "extra-large": 0.579,
        "high-cpu-medium": 0.180,
@@ -121,6 +121,10 @@
         "8GB": 1.52
     },
 
+    "gandi": {
+        "1": 0.02
+    },
+
     "vps_net": {
         "1": 0.416
     }

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/account_info.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/account_info.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/account_info.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/account_info.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,317 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><struct>
+<member>
+<name>handle</name>
+<value><string>AB3917-GANDI</string></value>
+</member>
+<member>
+<name>products</name>
+<value><array><data>
+<value><struct>
+<member>
+<name>errors_for_updating</name>
+<value><array><data>
+<value><string>product_name_does_not_match</string></value>
+<value><string>no_action_on_free_product</string></value>
+</data></array></value>
+</member>
+<member>
+<name>can_release</name>
+<value><boolean>1</boolean></value>
+</member>
+<member>
+<name>date_end</name>
+<value><string></string></value>
+</member>
+<member>
+<name>product_name</name>
+<value><string>shares_fixed</string></value>
+</member>
+<member>
+<name>autorenew</name>
+<value><string></string></value>
+</member>
+<member>
+<name>errors_for_removing</name>
+<value><array><data>
+</data></array></value>
+</member>
+<member>
+<name>errors_for_releasing</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+<value><string>not_available_resource</string></value>
+</data></array></value>
+</member>
+<member>
+<name>is_in_redemption</name>
+<value><string></string></value>
+</member>
+<member>
+<name>errors_for_autorenewing</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+</data></array></value>
+</member>
+<member>
+<name>duration</name>
+<value><string>1y</string></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20101028T12:38:17</dateTime.iso8601></value>
+</member>
+<member>
+<name>quantity</name>
+<value><int>12</int></value>
+</member>
+<member>
+<name>errors_for_renewing</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+</data></array></value>
+</member>
+<member>
+<name>id</name>
+<value><int>11153</int></value>
+</member>
+<member>
+<name>redemption</name>
+<value><int>7</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>errors_for_updating</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+</data></array></value>
+</member>
+<member>
+<name>can_release</name>
+<value><boolean>0</boolean></value>
+</member>
+<member>
+<name>date_end</name>
+<value><string></string></value>
+</member>
+<member>
+<name>product_name</name>
+<value><string>ips</string></value>
+</member>
+<member>
+<name>autorenew</name>
+<value><string></string></value>
+</member>
+<member>
+<name>errors_for_removing</name>
+<value><array><data>
+</data></array></value>
+</member>
+<member>
+<name>errors_for_releasing</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+<value><string>db_can_not_release</string></value>
+</data></array></value>
+</member>
+<member>
+<name>is_in_redemption</name>
+<value><string></string></value>
+</member>
+<member>
+<name>errors_for_autorenewing</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+</data></array></value>
+</member>
+<member>
+<name>duration</name>
+<value><string>1m</string></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110124T11:42:35</dateTime.iso8601></value>
+</member>
+<member>
+<name>quantity</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>errors_for_renewing</name>
+<value><array><data>
+<value><string>no_action_on_free_product</string></value>
+</data></array></value>
+</member>
+<member>
+<name>id</name>
+<value><int>11196</int></value>
+</member>
+<member>
+<name>redemption</name>
+<value><int>7</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</member>
+<member>
+<name>share_definition</name>
+<value><struct>
+<member>
+<name>servers</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>bandwidth</name>
+<value><double>5120.0</double></value>
+</member>
+<member>
+<name>memory</name>
+<value><int>256</int></value>
+</member>
+<member>
+<name>cores</name>
+<value><double>0.25</double></value>
+</member>
+<member>
+<name>slots</name>
+<value><double>0.66666666666666663</double></value>
+</member>
+<member>
+<name>disk</name>
+<value><int>8192</int></value>
+</member>
+</struct></value>
+</member>
+<member>
+<name>fullname</name>
+<value><string>Aymeric Barantal</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>58757</int></value>
+</member>
+<member>
+<name>resources</name>
+<value><struct>
+<member>
+<name>available</name>
+<value><struct>
+<member>
+<name>shares</name>
+<value><int>12</int></value>
+</member>
+<member>
+<name>servers</name>
+<value><int>8</int></value>
+</member>
+<member>
+<name>ips</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>bandwidth</name>
+<value><double>51200.0</double></value>
+</member>
+<member>
+<name>memory</name>
+<value><int>2560</int></value>
+</member>
+<member>
+<name>cores</name>
+<value><double>3.0</double></value>
+</member>
+<member>
+<name>slots</name>
+<value><double>4.0</double></value>
+</member>
+<member>
+<name>disk</name>
+<value><int>89088</int></value>
+</member>
+</struct></value>
+</member>
+<member>
+<name>granted</name>
+<value><struct>
+<member>
+<name>shares</name>
+<value><int>12</int></value>
+</member>
+<member>
+<name>servers</name>
+<value><int>12</int></value>
+</member>
+<member>
+<name>ips</name>
+<value><int>8</int></value>
+</member>
+<member>
+<name>bandwidth</name>
+<value><int>61440</int></value>
+</member>
+<member>
+<name>memory</name>
+<value><int>3072</int></value>
+</member>
+<member>
+<name>cores</name>
+<value><double>5.0</double></value>
+</member>
+<member>
+<name>slots</name>
+<value><double>8.0</double></value>
+</member>
+<member>
+<name>disk</name>
+<value><int>98304</int></value>
+</member>
+</struct></value>
+</member>
+<member>
+<name>used</name>
+<value><struct>
+<member>
+<name>servers</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>ips</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>bandwidth</name>
+<value><double>10240.0</double></value>
+</member>
+<member>
+<name>memory</name>
+<value><int>512</int></value>
+</member>
+<member>
+<name>cores</name>
+<value><double>2.0</double></value>
+</member>
+<member>
+<name>slots</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>disk</name>
+<value><int>9216</int></value>
+</member>
+</struct></value>
+</member>
+<member>
+<name>expired</name>
+<value><struct>
+</struct></value>
+</member>
+</struct></value>
+</member>
+</struct></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/datacenter_list.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/datacenter_list.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/datacenter_list.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/datacenter_list.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+    <params>
+        <param>
+            <value>
+                <array>
+                    <data>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>country</name>
+                                    <value><string>France</string></value>
+                                </member>
+                                <member>
+                                    <name>iso</name>
+                                    <value><string>FR</string></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>name</name>
+                                    <value><string>Equinix Paris</string></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>country</name>
+                                    <value><string>United States of America</string></value>
+                                </member>
+                                <member>
+                                    <name>iso</name>
+                                    <value><string>US</string></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>2</int></value>
+                                </member>
+                                <member>
+                                    <name>name</name>
+                                    <value><string>Level3 Baltimore</string></value>
+                                </member>
+                            </struct>
+                        </value>
+                    </data>
+                </array>
+            </value>
+        </param>
+    </params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/image_list_dc0.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/image_list_dc0.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/image_list_dc0.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/image_list_dc0.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,493 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+    <params>
+        <param>
+            <value>
+                <array>
+                    <data>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100928T10:41:38</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>34198</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>GandiOS</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20070101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>2</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11233</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Mandriva 2008.0</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20070101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>3</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11235</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Centos 5</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20070101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>4</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11236</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Fedora Core 7</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20070101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>5</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11237</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Open SUSE 10.3</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20070101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>6</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11238</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Debian 4</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20070101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>7</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11239</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Fedora Core 8</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20080101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>8</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11240</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Open SUSE 11.0</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20080101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>9</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11241</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Mandriva 2008.1</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20080101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>10</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>11242</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Ubuntu 8.04</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20080101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>11</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100922T11:56:05</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>23351</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Debian 5</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20090101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>12</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                        <value>
+                            <struct>
+                                <member>
+                                    <name>date_updated</name>
+                                    <value><dateTime.iso8601>20100811T16:30:06</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>disk_id</name>
+                                    <value><int>23352</int></value>
+                                </member>
+                                <member>
+                                    <name>label</name>
+                                    <value><string>Ubuntu 9.04</string></value>
+                                </member>
+                                <member>
+                                    <name>datacenter_id</name>
+                                    <value><int>1</int></value>
+                                </member>
+                                <member>
+                                    <name>visibility</name>
+                                    <value><string>all</string></value>
+                                </member>
+                                <member>
+                                    <name>os_arch</name>
+                                    <value><string>x86-32</string></value>
+                                </member>
+                                <member>
+                                    <name>date_created</name>
+                                    <value><dateTime.iso8601>20090101T00:00:00</dateTime.iso8601></value>
+                                </member>
+                                <member>
+                                    <name>author_id</name>
+                                    <value><int>248842</int></value>
+                                </member>
+                                <member>
+                                    <name>id</name>
+                                    <value><int>13</int></value>
+                                </member>
+                            </struct>
+                        </value>
+                    </data>
+                </array>
+            </value>
+        </param>
+    </params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/ip_list.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/ip_list.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/ip_list.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/ip_list.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,261 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><array><data>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm-6-186.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><int>7857</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T14:57:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>10.5.6.186</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20101028T12:49:11</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9256</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm6-fe37-9f7b.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><int>7857</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T14:58:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>2001:4b98:dc0:543:216:3eff:fe37:9f7b</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>6</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110120T14:58:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9294</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm-6-179.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><int>7861</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110124T15:53:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>10.5.6.179</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110124T11:43:17</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9298</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm6-fea8-3724.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><int>7861</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110124T15:54:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>2001:4b98:dc0:543:216:3eff:fea8:3724</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>6</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110124T15:54:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9301</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string></string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110217T17:39:39</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string></string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>being_created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><string></string></value>
+</member>
+<member>
+<name>version</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110217T17:39:39</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9323</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm-6-26.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110225T11:59:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>10.5.6.26</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110224T16:46:33</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9332</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/operation_info.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/operation_info.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/operation_info.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/operation_info.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><struct>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110324T15:49:50</dateTime.iso8601></value>
+</member>
+<member>
+<name>last_error</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_start</name>
+<value><string></string></value>
+</member>
+<member>
+<name>source</name>
+<value><string>AB3917-GANDI</string></value>
+</member>
+<member>
+<name>step</name>
+<value><string>DONE</string></value>
+</member>
+<member>
+<name>eta</name>
+<value><int>39</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110324T15:49:32</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>vm_delete</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>637366</int></value>
+</member>
+</struct></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_create_from.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_create_from.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_create_from.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_create_from.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,147 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><array><data>
+<value><struct>
+<member>
+<name>iface_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110324T17:14:06</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>disk_create</string></value>
+</member>
+<member>
+<name>date_start</name>
+<value><string></string></value>
+</member>
+<member>
+<name>disk_id</name>
+<value><int>35170</int></value>
+</member>
+<member>
+<name>source</name>
+<value><string>AB3917-GANDI</string></value>
+</member>
+<member>
+<name>step</name>
+<value><string>WAIT</string></value>
+</member>
+<member>
+<name>ip_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110324T17:14:06</dateTime.iso8601></value>
+</member>
+<member>
+<name>vm_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>637370</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>iface_id</name>
+<value><int>8019</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110324T17:14:06</dateTime.iso8601></value>
+</member>
+<member>
+<name>vm_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_start</name>
+<value><string></string></value>
+</member>
+<member>
+<name>disk_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>source</name>
+<value><string>AB3917-GANDI</string></value>
+</member>
+<member>
+<name>step</name>
+<value><string>WAIT</string></value>
+</member>
+<member>
+<name>ip_id</name>
+<value><int>9298</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110324T17:14:06</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>iface_create</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>637371</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>iface_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110324T17:14:07</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>vm_create</string></value>
+</member>
+<member>
+<name>date_start</name>
+<value><string></string></value>
+</member>
+<member>
+<name>disk_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>source</name>
+<value><string>AB3917-GANDI</string></value>
+</member>
+<member>
+<name>step</name>
+<value><string>WAIT</string></value>
+</member>
+<member>
+<name>ip_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110324T17:14:07</dateTime.iso8601></value>
+</member>
+<member>
+<name>vm_id</name>
+<value><int>250288</int></value>
+</member>
+<member>
+<name>id</name>
+<value><int>637372</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_delete.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_delete.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_delete.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_delete.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><struct>
+<member>
+<name>iface_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110324T15:49:32</dateTime.iso8601></value>
+</member>
+<member>
+<name>vm_id</name>
+<value><int>250136</int></value>
+</member>
+<member>
+<name>date_start</name>
+<value><string></string></value>
+</member>
+<member>
+<name>disk_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>source</name>
+<value><string>AB3917-GANDI</string></value>
+</member>
+<member>
+<name>step</name>
+<value><string>WAIT</string></value>
+</member>
+<member>
+<name>ip_id</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110324T15:49:32</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>vm_delete</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>637366</int></value>
+</member>
+</struct></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_info.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_info.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_info.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_info.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,330 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><struct>
+<member>
+<name>memory</name>
+<value><int>256</int></value>
+</member>
+<member>
+<name>hostname</name>
+<value><string>test2</string></value>
+</member>
+<member>
+<name>console</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>description</name>
+<value><string></string></value>
+</member>
+<member>
+<name>triggers</name>
+<value><array><data>
+</data></array></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T15:25:07</dateTime.iso8601></value>
+</member>
+<member>
+<name>disks</name>
+<value><array><data>
+<value><struct>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>name</name>
+<value><string>test2</string></value>
+</member>
+<member>
+<name>kernel_version</name>
+<value><string>2.6.32</string></value>
+</member>
+<member>
+<name>can_snapshot</name>
+<value><string></string></value>
+</member>
+<member>
+<name>kernel_cmdline</name>
+<value><struct>
+<member>
+<name>root</name>
+<value><string>/dev/xvda1</string></value>
+</member>
+<member>
+<name>ro</name>
+<value><boolean>1</boolean></value>
+</member>
+<member>
+<name>console</name>
+<value><string>xvc0</string></value>
+</member>
+<member>
+<name>nosep</name>
+<value><boolean>1</boolean></value>
+</member>
+</struct></value>
+</member>
+<member>
+<name>visibility</name>
+<value><string>private</string></value>
+</member>
+<member>
+<name>label</name>
+<value><string>Debian 5</string></value>
+</member>
+<member>
+<name>vms_id</name>
+<value><array><data>
+<value><int>250133</int></value>
+</data></array></value>
+</member>
+<member>
+<name>source</name>
+<value><int>23351</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>halted</string></value>
+</member>
+<member>
+<name>is_boot_disk</name>
+<value><boolean>1</boolean></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T15:02:01</dateTime.iso8601></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110120T14:57:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>data</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>34951</int></value>
+</member>
+<member>
+<name>size</name>
+<value><int>3072</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</member>
+<member>
+<name>disks_id</name>
+<value><array><data>
+<value><int>34951</int></value>
+</data></array></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>halted</string></value>
+</member>
+<member>
+<name>flex_shares</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>ai_active</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>vm_max_memory</name>
+<value><int>2048</int></value>
+</member>
+<member>
+<name>ifaces</name>
+<value><array><data>
+<value><struct>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T14:58:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>vm_id</name>
+<value><int>250133</int></value>
+</member>
+<member>
+<name>bandwidth</name>
+<value><double>5120.0</double></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>ips</name>
+<value><array><data>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm-6-186.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><int>7857</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T14:57:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>10.5.6.186</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>4</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20101028T12:49:11</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9256</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>reverse</name>
+<value><string>xvm6-fe37-9f7b.ghst.net</string></value>
+</member>
+<member>
+<name>iface_id</name>
+<value><int>7857</int></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T14:58:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>ip</name>
+<value><string>2001:4b98:dc0:543:216:3eff:fe37:9f7b</string></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>created</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>version</name>
+<value><int>6</int></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110120T14:58:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>9294</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</member>
+<member>
+<name>state</name>
+<value><string>used</string></value>
+</member>
+<member>
+<name>num</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>ips_id</name>
+<value><array><data>
+<value><int>9256</int></value>
+<value><int>9294</int></value>
+</data></array></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110120T14:57:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>type</name>
+<value><string>public</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>7857</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</member>
+<member>
+<name>cores</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>ifaces_id</name>
+<value><array><data>
+<value><int>7857</int></value>
+</data></array></value>
+</member>
+<member>
+<name>graph_urls</name>
+<value><struct>
+<member>
+<name>vcpu</name>
+<value><array><data>
+<value><string>http://graph.dev.hosting.gandi.net:8080//?key=88a6b2a04f21c3b9c055d73310ee37ea47fe25c7&amp;vm_id=379&amp;dc_id=1&amp;stats_target=vcpu&amp;device_number=0</string></value>
+</data></array></value>
+</member>
+<member>
+<name>vdi</name>
+<value><array><data>
+<value><string>http://graph.dev.hosting.gandi.net:8080//?key=88a6b2a04f21c3b9c055d73310ee37ea47fe25c7&amp;vm_id=379&amp;dc_id=1&amp;stats_target=vdi&amp;device_number=0</string></value>
+</data></array></value>
+</member>
+<member>
+<name>vif</name>
+<value><array><data>
+<value><string>http://graph.dev.hosting.gandi.net:8080//?key=88a6b2a04f21c3b9c055d73310ee37ea47fe25c7&amp;vm_id=379&amp;dc_id=1&amp;stats_target=vif&amp;device_number=0</string></value>
+</data></array></value>
+</member>
+</struct></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110120T14:57:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>250133</int></value>
+</member>
+</struct></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_list.xml
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_list.xml?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_list.xml (added)
+++ incubator/libcloud/trunk/test/compute/fixtures/gandi/vm_list.xml Thu Mar 24 19:52:40 2011
@@ -0,0 +1,141 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><array><data>
+<value><struct>
+<member>
+<name>memory</name>
+<value><int>256</int></value>
+</member>
+<member>
+<name>console</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>description</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110120T15:25:07</dateTime.iso8601></value>
+</member>
+<member>
+<name>hostname</name>
+<value><string>test1</string></value>
+</member>
+<member>
+<name>disks_id</name>
+<value><array><data>
+<value><int>34951</int></value>
+</data></array></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>running</string></value>
+</member>
+<member>
+<name>flex_shares</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>ai_active</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>vm_max_memory</name>
+<value><int>2048</int></value>
+</member>
+<member>
+<name>cores</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>ifaces_id</name>
+<value><array><data>
+<value><int>7857</int></value>
+</data></array></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110120T14:57:55</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>250133</int></value>
+</member>
+</struct></value>
+<value><struct>
+<member>
+<name>memory</name>
+<value><int>256</int></value>
+</member>
+<member>
+<name>console</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>description</name>
+<value><string></string></value>
+</member>
+<member>
+<name>date_updated</name>
+<value><dateTime.iso8601>20110225T12:09:31</dateTime.iso8601></value>
+</member>
+<member>
+<name>hostname</name>
+<value><string>test2</string></value>
+</member>
+<member>
+<name>disks_id</name>
+<value><array><data>
+<value><int>34954</int></value>
+</data></array></value>
+</member>
+<member>
+<name>datacenter_id</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>state</name>
+<value><string>halted</string></value>
+</member>
+<member>
+<name>flex_shares</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>ai_active</name>
+<value><int>0</int></value>
+</member>
+<member>
+<name>vm_max_memory</name>
+<value><int>2048</int></value>
+</member>
+<member>
+<name>cores</name>
+<value><int>1</int></value>
+</member>
+<member>
+<name>ifaces_id</name>
+<value><array><data>
+<value><int>7861</int></value>
+</data></array></value>
+</member>
+<member>
+<name>date_created</name>
+<value><dateTime.iso8601>20110124T15:53:44</dateTime.iso8601></value>
+</member>
+<member>
+<name>id</name>
+<value><int>250136</int></value>
+</member>
+</struct></value>
+</data></array></value>
+</param>
+</params>
+</methodResponse>
\ No newline at end of file

Added: incubator/libcloud/trunk/test/compute/test_gandi.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_gandi.py?rev=1085099&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_gandi.py (added)
+++ incubator/libcloud/trunk/test/compute/test_gandi.py Thu Mar 24 19:52:40 2011
@@ -0,0 +1,124 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+import sys
+import random
+import string
+import httplib
+import xmlrpclib
+
+from libcloud.compute.drivers.gandi import GandiNodeDriver as Gandi
+
+from xml.etree import ElementTree as ET
+from test import MockHttp
+from test.file_fixtures import ComputeFileFixtures
+from test.secrets import GANDI_USER
+
+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 = GandiMockHttp(host, 80)
+        mock.request('POST', "%s/%s" % (handler, method))
+        resp = mock.getresponse()
+        return self._parse_response(resp.body, None)
+
+class GandiTests(unittest.TestCase):
+
+    node_name = 'test2'
+    def setUp(self):
+        Gandi.connectionCls.proxyCls.transportCls = [MockGandiTransport, MockGandiTransport]
+        self.driver = Gandi(GANDI_USER)
+
+    def test_list_nodes(self):
+        nodes = self.driver.list_nodes()
+        self.assertTrue(len(nodes)>0)
+
+    def test_list_locations(self):
+        loc = filter(lambda x: 'france' in x.country.lower(), self.driver.list_locations())[0]
+        self.assertEqual(loc.country, 'France')
+
+    def test_list_images(self):
+        loc = filter(lambda x: 'france' in x.country.lower(), self.driver.list_locations())[0]
+        images = self.driver.list_images(loc)
+        self.assertTrue(len(images)>2)
+
+    def test_list_sizes(self):
+        sizes = self.driver.list_sizes()
+        self.assertTrue(len(sizes)>=1)
+
+    def test_destroy_node(self):
+        nodes = self.driver.list_nodes()
+        test_node = filter(lambda x: self.node_name in x.name, nodes)[0]
+        self.assertTrue(self.driver.destroy_node(test_node))
+
+    def test_create_node(self):
+        login = 'libcloud'
+        passwd = ''.join(random.choice(string.letters + string.digits) for i in xrange(10))
+        # Get france datacenter
+        loc = filter(lambda x: 'france' in x.country.lower(), self.driver.list_locations())[0]
+        # Get a debian image
+        images = self.driver.list_images(loc)
+        images = [x for x in images if x.name.lower().startswith('debian')]
+        img = filter(lambda x: '5' in x.name, images)[0]
+        # Get a configuration size
+        size = self.driver.list_sizes()[0]
+        node = self.driver.create_node(name=self.node_name,login=login,password=passwd,image=img,location=loc,size=size)
+        self.assertEqual(node.name, self.node_name)
+
+class GandiMockHttp(MockHttp):
+
+    fixtures = ComputeFileFixtures('gandi')
+
+    def _xmlrpc_2_0__datacenter_list(self, method, url, body, headers):
+        body = self.fixtures.load('datacenter_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__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_2_0__vm_list(self, method, url, body, headers):
+        body = self.fixtures.load('vm_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__ip_list(self, method, url, body, headers):
+        body = self.fixtures.load('ip_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__account_info(self, method, url, body, headers):
+        body = self.fixtures.load('account_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__vm_info(self, method, url, body, headers):
+        body = self.fixtures.load('vm_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__vm_delete(self, method, url, body, headers):
+        body = self.fixtures.load('vm_delete.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__operation_info(self, method, url, body, headers):
+        body = self.fixtures.load('operation_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc_2_0__vm_create_from(self, method, url, body, headers):
+        body = self.fixtures.load('vm_create_from.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())

Modified: incubator/libcloud/trunk/test/secrets.py-dist
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/secrets.py-dist?rev=1085099&r1=1085098&r2=1085099&view=diff
==============================================================================
--- incubator/libcloud/trunk/test/secrets.py-dist (original)
+++ incubator/libcloud/trunk/test/secrets.py-dist Thu Mar 24 19:52:40 2011
@@ -57,7 +57,9 @@ ECP_PASSWORD = ''
 IBM_USER = ''
 IBM_SECRET = ''
 
+DREAMHOST_KEY=''
+
+GANDI_USER = ''
+
 OPENNEBULA_USER = ''
 OPENNEBULA_KEY = ''
-
-DREAMHOST_KEY = ''