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 2015/06/13 14:44:11 UTC

[1/7] libcloud git commit: Added GandiNodeDriver.list_key_pairs and get_key_pair

Repository: libcloud
Updated Branches:
  refs/heads/trunk 699584f90 -> 78b95fd9d


Added GandiNodeDriver.list_key_pairs and get_key_pair

Closes #534

Signed-off-by: Tomaz Muraus <to...@tomaz.me>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/562e4d2a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/562e4d2a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/562e4d2a

Branch: refs/heads/trunk
Commit: 562e4d2ae0e7aa8585072bc7ec3a3822f3d11d84
Parents: 699584f
Author: ZuluPro <mo...@hotmail.com>
Authored: Wed May 27 16:13:44 2015 -0400
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:31:46 2015 +0800

----------------------------------------------------------------------
 libcloud/compute/drivers/cloudstack.py |  8 +++++++
 libcloud/compute/drivers/gandi.py      | 35 +++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/562e4d2a/libcloud/compute/drivers/cloudstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/cloudstack.py b/libcloud/compute/drivers/cloudstack.py
index b226c55..41b5c06 100644
--- a/libcloud/compute/drivers/cloudstack.py
+++ b/libcloud/compute/drivers/cloudstack.py
@@ -2260,6 +2260,14 @@ class CloudStackNodeDriver(CloudStackDriverMixIn, NodeDriver):
         return key_pairs
 
     def get_key_pair(self, name):
+        """
+        Retrieve a single key pair.
+
+        :param name: Name of the key pair to retrieve.
+        :type name: ``str``
+
+        :rtype: :class:`.KeyPair`
+        """
         params = {'name': name}
         res = self._sync_request(command='listSSHKeyPairs',
                                  params=params,

http://git-wip-us.apache.org/repos/asf/libcloud/blob/562e4d2a/libcloud/compute/drivers/gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gandi.py b/libcloud/compute/drivers/gandi.py
index e5593b4..7a54ada 100644
--- a/libcloud/compute/drivers/gandi.py
+++ b/libcloud/compute/drivers/gandi.py
@@ -20,6 +20,7 @@ from datetime import datetime
 
 from libcloud.common.gandi import BaseGandiDriver, GandiException,\
     NetworkInterface, IPAddress, Disk
+from libcloud.compute.base import KeyPair
 from libcloud.compute.base import StorageVolume
 from libcloud.compute.types import NodeState, Provider
 from libcloud.compute.base import Node, NodeDriver
@@ -617,3 +618,37 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         if self._wait_operation(op.object['id']):
             return True
         return False
+
+    def _to_key_pair(self, data):
+        key_pair = KeyPair(name=data['name'],
+                           fingerprint=data['fingerprint'],
+                           public_key=data.get('value', None),
+                           private_key=data.get('privatekey', None),
+                           driver=self, extra={'id': data['id']})
+        return key_pair
+
+    def _to_key_pairs(self, data):
+        return [self._to_key_pair(k) for k in data]
+
+    def list_key_pairs(self):
+        """
+        List registered key pairs.
+
+        :return:   A list of key par objects.
+        :rtype:   ``list`` of :class:`libcloud.compute.base.KeyPair`
+        """
+        kps = self.connection.request('hosting.ssh.list').object
+        return self._to_key_pairs(kps)
+
+    def get_key_pair(self, name):
+        """
+        Retrieve a single key pair.
+
+        :param name: Name of the key pair to retrieve.
+        :type name: ``str``
+
+        :rtype: :class:`.KeyPair`
+        """
+        filter_params = {'name': name}
+        kps = self.connection.request('hosting.ssh.list', filter_params).object
+        return self._to_key_pair(kps[0])


[6/7] libcloud git commit: Update changelog.

Posted by to...@apache.org.
Update changelog.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e42b7515
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e42b7515
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e42b7515

Branch: refs/heads/trunk
Commit: e42b75154734d22500d06c8bae2d8eb717f8052e
Parents: 3c5522f
Author: Tomaz Muraus <to...@tomaz.me>
Authored: Sat Jun 13 20:32:35 2015 +0800
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:32:35 2015 +0800

----------------------------------------------------------------------
 CHANGES.rst | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/e42b7515/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 94e8607..42a5ff6 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -204,7 +204,7 @@ Compute
   (GITHUB-528)
   [Michael Bennett]
 
-- Add ``ex_get_node`` and ``ex_get_volume`` methods to CloudStack driver
+- Add ``ex_get_node`` and ``ex_get_volume`` methods to CloudStack driver.
   (GITHUB-532)
   [ZuluPro]
 
@@ -213,6 +213,14 @@ Compute
   (GITHUB-517)
   [Chris O'Brien]
 
+- Add SSH key pair management methods to the Gandi driver.
+  (GITHUB-534)
+  [ZuluPro]
+
+- Add ``ex_get_node`` and ``ex_get_volume`` methods to Gandi driver.
+  (GITHUB-534)
+  [ZuluPro]
+
 Storage
 ~~~~~~~
 


[4/7] libcloud git commit: Added Gandi ex_get_volume with test

Posted by to...@apache.org.
Added Gandi ex_get_volume with test

Closes #534

Signed-off-by: Tomaz Muraus <to...@tomaz.me>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/cec4b497
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/cec4b497
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/cec4b497

Branch: refs/heads/trunk
Commit: cec4b497e0875251f76787a04729b7256d806a2d
Parents: 915bc1a
Author: ZuluPro <mo...@hotmail.com>
Authored: Tue Jun 2 13:45:20 2015 -0400
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:32:16 2015 +0800

----------------------------------------------------------------------
 libcloud/compute/drivers/gandi.py   | 13 +++++++++++++
 libcloud/test/compute/test_gandi.py |  4 ++++
 2 files changed, 17 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/cec4b497/libcloud/compute/drivers/gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gandi.py b/libcloud/compute/drivers/gandi.py
index ba6e89b..844850a 100644
--- a/libcloud/compute/drivers/gandi.py
+++ b/libcloud/compute/drivers/gandi.py
@@ -461,6 +461,19 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         res = self.connection.request('hosting.disk.list', {})
         return self._to_volumes(res.object)
 
+    def ex_get_volume(self, volume_id):
+        """
+        Return a Volume object based on a volume ID.
+
+        :param  volume_id: The ID of the volume
+        :type   volume_id: ``int``
+
+        :return:  A StorageVolume object for the volume
+        :rtype:   :class:`StorageVolume`
+        """
+        res = self.connection.request('hosting.disk.info', volume_id)
+        return self._to_volume(res.object)
+
     def create_volume(self, size, name, location=None, snapshot=None):
         """
         Create a volume (disk).

http://git-wip-us.apache.org/repos/asf/libcloud/blob/cec4b497/libcloud/test/compute/test_gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_gandi.py b/libcloud/test/compute/test_gandi.py
index ae01e6d..1cdbcf2 100644
--- a/libcloud/test/compute/test_gandi.py
+++ b/libcloud/test/compute/test_gandi.py
@@ -175,6 +175,10 @@ class GandiTests(unittest.TestCase):
         node = self.driver.ex_get_node(34951)
         self.assertEqual(node.name, "test2")
 
+    def test_ex_get_volume(self):
+        volume = self.driver.ex_get_volume(1263)
+        self.assertEqual(volume.name, "libcloud")
+
 
 class GandiRatingTests(unittest.TestCase):
 


[2/7] libcloud git commit: Added Gandi keypair management

Posted by to...@apache.org.
Added Gandi keypair management

Closes #534

Signed-off-by: Tomaz Muraus <to...@tomaz.me>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/3fe88d07
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/3fe88d07
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/3fe88d07

Branch: refs/heads/trunk
Commit: 3fe88d073351555909b71818483735a09854a53d
Parents: 562e4d2
Author: ZuluPro <mo...@hotmail.com>
Authored: Wed May 27 18:26:34 2015 -0400
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:31:58 2015 +0800

----------------------------------------------------------------------
 libcloud/compute/drivers/gandi.py               | 59 +++++++++++++++++---
 .../test/compute/fixtures/gandi/ssh_delete.xml  |  8 +++
 .../test/compute/fixtures/gandi/ssh_info.xml    | 25 +++++++++
 .../test/compute/fixtures/gandi/ssh_list.xml    | 23 ++++++++
 libcloud/test/compute/test_gandi.py             | 33 +++++++++++
 5 files changed, 141 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/3fe88d07/libcloud/compute/drivers/gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gandi.py b/libcloud/compute/drivers/gandi.py
index 7a54ada..420d25d 100644
--- a/libcloud/compute/drivers/gandi.py
+++ b/libcloud/compute/drivers/gandi.py
@@ -215,12 +215,15 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         :keyword    inet_family: version of ip to use, default 4 (optional)
         :type       inet_family: ``int``
 
+        :keyword    keypairs: IDs of keypairs or Keypairs object
+        :type       keypairs: ``int`` or :class:`.KeyPair`
+
         :rtype: :class:`Node`
         """
 
-        if kwargs.get('login') is None or kwargs.get('password') is None:
-            raise GandiException(
-                1020, 'login and password must be defined for node creation')
+        if not kwargs.get('login') and not kwargs.get('keypairs'):
+            raise GandiException(1020, "Login and password or ssh keypair "
+                                 "must be defined for node creation")
 
         location = kwargs.get('location')
         if location and isinstance(location, NodeLocation):
@@ -234,6 +237,12 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
             raise GandiException(
                 1022, 'size must be a subclass of NodeSize')
 
+        keypairs = kwargs.get('keypairs', [])
+        keypair_ids = [
+            k if isinstance(k, int) else k.extra['id']
+            for k in keypairs
+        ]
+
         # If size name is in INSTANCE_TYPE we use new rating model
         instance = INSTANCE_TYPES.get(size.id)
         cores = instance['cpu'] if instance else int(size.id)
@@ -248,14 +257,20 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         vm_spec = {
             'datacenter_id': dc_id,
             'hostname': kwargs['name'],
-            'login': kwargs['login'],
-            'password': kwargs['password'],  # TODO : use NodeAuthPassword
             'memory': int(size.ram),
             'cores': cores,
             'bandwidth': int(size.bandwidth),
             'ip_version': kwargs.get('inet_family', 4),
         }
 
+        if kwargs.get('login') and kwargs.get('password'):
+            vm_spec.update({
+                'login': kwargs['login'],
+                'password': kwargs['password'],  # TODO : use NodeAuthPassword
+            })
+        if keypair_ids:
+            vm_spec['keys'] = keypair_ids
+
         # Call create_from helper api. Return 3 operations : disk_create,
         # iface_create,vm_create
         (op_disk, op_iface, op_vm) = self.connection.request(
@@ -535,7 +550,6 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         :param      node: Node which should be used
         :type       node: :class:`Node`
 
-
         :param      iface: Network interface which should be used
         :type       iface: :class:`GandiNetworkInterface`
 
@@ -554,7 +568,6 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         :param      node: Node which should be used
         :type       node: :class:`Node`
 
-
         :param      iface: Network interface which should be used
         :type       iface: :class:`GandiNetworkInterface`
 
@@ -652,3 +665,35 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         filter_params = {'name': name}
         kps = self.connection.request('hosting.ssh.list', filter_params).object
         return self._to_key_pair(kps[0])
+
+    def import_key_pair_from_string(self, name, key_material):
+        """
+        Create a new key pair object.
+
+        :param name: Key pair name.
+        :type name: ``str``
+
+        :param key_material: Public key material.
+        :type key_material: ``str``
+
+        :return: Imported key pair object.
+        :rtype: :class:`.KeyPair`
+        """
+        params = {'name': name, 'value': key_material}
+        kp = self.connection.request('hosting.ssh.create', params).object
+        return self._to_key_pair(kp)
+
+    def delete_key_pair(self, key_pair):
+        """
+        Delete an existing key pair.
+
+        :param key_pair: Key pair object or ID.
+        :type key_pair: :class.KeyPair` or ``int``
+
+        :return:   True of False based on success of Keypair deletion
+        :rtype:    ``bool``
+        """
+        key_id = key_pair if isinstance(key_pair, int) \
+            else key_pair.extra['id']
+        success = self.connection.request('hosting.ssh.delete', key_id).object
+        return success

http://git-wip-us.apache.org/repos/asf/libcloud/blob/3fe88d07/libcloud/test/compute/fixtures/gandi/ssh_delete.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gandi/ssh_delete.xml b/libcloud/test/compute/fixtures/gandi/ssh_delete.xml
new file mode 100644
index 0000000..6dbecc1
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gandi/ssh_delete.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><boolean>1</boolean></value>
+</param>
+</params>
+</methodResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/3fe88d07/libcloud/test/compute/fixtures/gandi/ssh_info.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gandi/ssh_info.xml b/libcloud/test/compute/fixtures/gandi/ssh_info.xml
new file mode 100644
index 0000000..b48bace
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gandi/ssh_info.xml
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><struct>
+<member>
+<name>fingerprint</name>
+<value><string>a6:1f:b8:b4:19:91:99:d8:af:ab:d6:17:72:8b:d1:6c</string></value>
+</member>
+<member>
+<name>name</name>
+<value><string>testkey</string></value>
+</member>
+<member>
+<name>value</name>
+<value><string>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaCXFxl0cPZa+PkXSaux/9Sfn4J81eNJ4f/ZkjdIlmLJVYFUKbpC16eEwXYEfw/QBAZFPODCDQOFAZdgajO572y9scp09F7L7Rhwrw7DYu8STMIBz0XBIO8eOUyu5hVRpxaZGDih9B99e1hITTGFg+BveAmrdB8CPtygKo/fUmaamrocZBrD1betaLTC0i6/DVz7YAbR0CleZLlaBogqVhqmS0TB4J67aG2vvq1MjyOixQY5Ab4aXo4Dz1jd7oqCGCKCO9oKAG0ok94foxkfnCmfRrnfWzOA7SFWjUs65SOrGYZghspDcbJ9vA4ZkUuWJXPPvLVgsI8aHwkezJPD8Th root@testhost</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>10</int></value>
+</member>
+</struct></value>
+</param>
+</params>
+</methodResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/3fe88d07/libcloud/test/compute/fixtures/gandi/ssh_list.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gandi/ssh_list.xml b/libcloud/test/compute/fixtures/gandi/ssh_list.xml
new file mode 100644
index 0000000..003e546
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gandi/ssh_list.xml
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<methodResponse>
+<params>
+<param>
+<value><array><data>
+<value><struct>
+<member>
+<name>fingerprint</name>
+<value><string>a6:1f:b8:b4:19:91:99:d8:af:ab:d6:17:72:8b:d1:6c</string></value>
+</member>
+<member>
+<name>id</name>
+<value><int>10</int></value>
+</member>
+<member>
+<name>name</name>
+<value><string>testkey</string></value>
+</member>
+</struct></value>
+</data></array></value>
+</param>
+</params>
+</methodResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/3fe88d07/libcloud/test/compute/test_gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_gandi.py b/libcloud/test/compute/test_gandi.py
index e4a11e8..5336820 100644
--- a/libcloud/test/compute/test_gandi.py
+++ b/libcloud/test/compute/test_gandi.py
@@ -154,6 +154,23 @@ class GandiTests(unittest.TestCase):
         disks = self.driver.list_volumes()
         self.assertTrue(self.driver.ex_update_disk(disks[0], new_size=4096))
 
+    def test_list_key_pairs(self):
+        keys = self.driver.list_key_pairs()
+        self.assertGreater(len(keys), 0)
+
+    def test_get_key_pair(self):
+        key = self.driver.get_key_pair(10)
+        self.assertEqual(key.name, 'testkey')
+
+    def test_import_key_pair_from_string(self):
+        key = self.driver.import_key_pair_from_string('testkey', '12345')
+        self.assertEqual(key.name, 'testkey')
+        self.assertEqual(key.extra['id'], 10)
+
+    def test_delete_key_pair(self):
+        response = self.driver.delete_key_pair(10)
+        self.assertTrue(response)
+
 
 class GandiRatingTests(unittest.TestCase):
 
@@ -285,6 +302,22 @@ class GandiMockHttp(BaseGandiMockHttp):
         body = self.fixtures.load('disk_delete.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _xmlrpc__hosting_ssh_info(self, method, url, body, headers):
+        body = self.fixtures.load('ssh_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__hosting_ssh_list(self, method, url, body, headers):
+        body = self.fixtures.load('ssh_list.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__hosting_ssh_create(self, method, url, body, headers):
+        body = self.fixtures.load('ssh_info.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _xmlrpc__hosting_ssh_delete(self, method, url, body, headers):
+        body = self.fixtures.load('ssh_delete.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
 
 class GandiMockRatingHttp(BaseGandiMockHttp):
 


[3/7] libcloud git commit: Added Gandi ex_get_node with test & added docstring

Posted by to...@apache.org.
Added Gandi ex_get_node with test & added docstring

Closes #534

Signed-off-by: Tomaz Muraus <to...@tomaz.me>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/915bc1ae
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/915bc1ae
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/915bc1ae

Branch: refs/heads/trunk
Commit: 915bc1aee86a1e41caa0ce98b8c29ae6b53b0f18
Parents: 3fe88d0
Author: ZuluPro <mo...@hotmail.com>
Authored: Tue Jun 2 13:30:10 2015 -0400
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:32:08 2015 +0800

----------------------------------------------------------------------
 libcloud/compute/drivers/gandi.py   | 115 ++++++++++++++++++++++++++++++-
 libcloud/test/compute/test_gandi.py |   4 ++
 2 files changed, 118 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/915bc1ae/libcloud/compute/drivers/gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gandi.py b/libcloud/compute/drivers/gandi.py
index 420d25d..ba6e89b 100644
--- a/libcloud/compute/drivers/gandi.py
+++ b/libcloud/compute/drivers/gandi.py
@@ -145,6 +145,12 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         return [self._to_volume(d) for d in disks]
 
     def list_nodes(self):
+        """
+        Return a list of nodes in the current zone or all zones.
+
+        :return:  List of Node objects
+        :rtype:   ``list`` of :class:`Node`
+        """
         vms = self.connection.request('hosting.vm.list').object
         ips = self.connection.request('hosting.ip.list').object
         for vm in vms:
@@ -158,7 +164,37 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         nodes = self._to_nodes(vms)
         return nodes
 
+    def ex_get_node(self, node_id):
+        """
+        Return a Node object based on a node id.
+
+        :param  name: The ID of the node
+        :type   name: ``int``
+
+        :return:  A Node object for the node
+        :rtype:   :class:`Node`
+        """
+        vm = self.connection.request('hosting.vm.info', int(node_id)).object
+        ips = self.connection.request('hosting.ip.list').object
+        vm['ips'] = []
+        for ip in ips:
+            if vm['ifaces_id'][0] == ip['iface_id']:
+                ip = ip.get('ip', None)
+                if ip:
+                    vm['ips'].append(ip)
+        node = self._to_node(vm)
+        return node
+
     def reboot_node(self, node):
+        """
+        Reboot a node.
+
+        :param  node: Node to be rebooted
+        :type   node: :class:`Node`
+
+        :return:  True if successful, False if not
+        :rtype:   ``bool``
+        """
         op = self.connection.request('hosting.vm.reboot', int(node.id))
         self._wait_operation(op.object['id'])
         vm = self._node_info(int(node.id))
@@ -167,6 +203,15 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         return False
 
     def destroy_node(self, node):
+        """
+        Destroy a node.
+
+        :param  node: Node object to destroy
+        :type   node: :class:`Node`
+
+        :return:  True if successful
+        :rtype:   ``bool``
+        """
         vm = self._node_info(node.id)
         if vm['state'] == 'running':
             # Send vm_stop and wait for accomplish
@@ -216,7 +261,7 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         :type       inet_family: ``int``
 
         :keyword    keypairs: IDs of keypairs or Keypairs object
-        :type       keypairs: ``int`` or :class:`.KeyPair`
+        :type       keypairs: list of ``int`` or :class:`.KeyPair`
 
         :rtype: :class:`Node`
         """
@@ -300,6 +345,15 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         )
 
     def list_images(self, location=None):
+        """
+        Return a list of image objects.
+
+        :keyword    location: Which data center to filter a images in.
+        :type       location: :class:`NodeLocation`
+
+        :return:  List of GCENodeImage objects
+        :rtype:   ``list`` of :class:`GCENodeImage`
+        """
         try:
             if location:
                 filtering = {'datacenter_id': int(location.id)}
@@ -338,6 +392,15 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
                 for name, instance in INSTANCE_TYPES.items()]
 
     def list_sizes(self, location=None):
+        """
+        Return a list of sizes (machineTypes) in a zone.
+
+        :keyword  location: Which data center to filter a sizes in.
+        :type     location: :class:`NodeLocation` or ``None``
+
+        :return:  List of NodeSize objects
+        :rtype:   ``list`` of :class:`NodeSize`
+        """
         account = self.connection.request('hosting.account.info').object
         if account.get('rating_enabled'):
             # This account use new rating model
@@ -379,18 +442,44 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         )
 
     def list_locations(self):
+        """
+        Return a list of locations (datacenters).
+
+        :return: List of NodeLocation objects
+        :rtype: ``list`` of :class:`NodeLocation`
+        """
         res = self.connection.request('hosting.datacenter.list')
         return [self._to_loc(l) for l in res.object]
 
     def list_volumes(self):
         """
+        Return a list of volumes.
 
+        :return: A list of volume objects.
         :rtype: ``list`` of :class:`StorageVolume`
         """
         res = self.connection.request('hosting.disk.list', {})
         return self._to_volumes(res.object)
 
     def create_volume(self, size, name, location=None, snapshot=None):
+        """
+        Create a volume (disk).
+
+        :param  size: Size of volume to create (in GB).
+        :type   size: ``int``
+
+        :param  name: Name of volume to create
+        :type   name: ``str``
+
+        :keyword  location: Location (zone) to create the volume in
+        :type     location: :class:`NodeLocation` or ``None``
+
+        :keyword  snapshot: Snapshot to create image from
+        :type     snapshot: :class:`Snapshot`
+
+        :return:  Storage Volume object
+        :rtype:   :class:`StorageVolume`
+        """
         disk_param = {
             'name': name,
             'size': int(size),
@@ -407,6 +496,21 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         return None
 
     def attach_volume(self, node, volume, device=None):
+        """
+        Attach a volume to a node.
+
+        :param  node: The node to attach the volume to
+        :type   node: :class:`Node`
+
+        :param  volume: The volume to attach.
+        :type   volume: :class:`StorageVolume`
+
+        :keyword  device: Not used in this cloud.
+        :type     device: ``None``
+
+        :return:  True if successful
+        :rtype:   ``bool``
+        """
         op = self.connection.request('hosting.vm.disk_attach',
                                      int(node.id), int(volume.id))
         if self._wait_operation(op.object['id']):
@@ -432,6 +536,15 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver):
         return False
 
     def destroy_volume(self, volume):
+        """
+        Destroy a volume.
+
+        :param  volume: Volume object to destroy
+        :type   volume: :class:`StorageVolume`
+
+        :return:  True if successful
+        :rtype:   ``bool``
+        """
         op = self.connection.request('hosting.disk.delete', int(volume.id))
         if self._wait_operation(op.object['id']):
             return True

http://git-wip-us.apache.org/repos/asf/libcloud/blob/915bc1ae/libcloud/test/compute/test_gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_gandi.py b/libcloud/test/compute/test_gandi.py
index 5336820..ae01e6d 100644
--- a/libcloud/test/compute/test_gandi.py
+++ b/libcloud/test/compute/test_gandi.py
@@ -171,6 +171,10 @@ class GandiTests(unittest.TestCase):
         response = self.driver.delete_key_pair(10)
         self.assertTrue(response)
 
+    def test_ex_get_node(self):
+        node = self.driver.ex_get_node(34951)
+        self.assertEqual(node.name, "test2")
+
 
 class GandiRatingTests(unittest.TestCase):
 


[7/7] libcloud git commit: Re-generate supported providers table.

Posted by to...@apache.org.
Re-generate supported providers table.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/78b95fd9
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/78b95fd9
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/78b95fd9

Branch: refs/heads/trunk
Commit: 78b95fd9d01248b61e809ab3aa186e33b87a54e1
Parents: e42b751
Author: Tomaz Muraus <to...@tomaz.me>
Authored: Sat Jun 13 20:33:08 2015 +0800
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:33:08 2015 +0800

----------------------------------------------------------------------
 docs/compute/_supported_methods_key_pair_management.rst | 2 +-
 docs/compute/_supported_providers.rst                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/78b95fd9/docs/compute/_supported_methods_key_pair_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_key_pair_management.rst b/docs/compute/_supported_methods_key_pair_management.rst
index 6ef22ad..646bdc6 100644
--- a/docs/compute/_supported_methods_key_pair_management.rst
+++ b/docs/compute/_supported_methods_key_pair_management.rst
@@ -35,7 +35,7 @@ Provider                              list key pairs get key pair create key pai
 `ElasticHosts (sjc-c)`_               no             no           no              no                            no                          no             
 `Eucalyptus`_                         yes            yes          yes             yes                           no                          yes            
 `Exoscale`_                           yes            yes          yes             yes                           no                          yes            
-`Gandi`_                              no             no           no              no                            no                          no             
+`Gandi`_                              yes            yes          no              yes                           no                          yes            
 `Google Compute Engine`_              no             no           no              no                            no                          no             
 `GoGrid`_                             no             no           no              no                            no                          no             
 `HostVirtual`_                        no             no           no              no                            no                          no             

http://git-wip-us.apache.org/repos/asf/libcloud/blob/78b95fd9/docs/compute/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_providers.rst b/docs/compute/_supported_providers.rst
index d75156e..16e28f8 100644
--- a/docs/compute/_supported_providers.rst
+++ b/docs/compute/_supported_providers.rst
@@ -35,7 +35,7 @@ Provider                              Documentation
 `ElasticHosts (sjc-c)`_                                                             ELASTICHOSTS_US3    :mod:`libcloud.compute.drivers.elastichosts`   :class:`ElasticHostsUS3NodeDriver`  
 `Eucalyptus`_                                                                       EUCALYPTUS          :mod:`libcloud.compute.drivers.ec2`            :class:`EucNodeDriver`              
 `Exoscale`_                           :doc:`Click </compute/drivers/exoscale>`      EXOSCALE            :mod:`libcloud.compute.drivers.exoscale`       :class:`ExoscaleNodeDriver`         
-`Gandi`_                                                                            GANDI               :mod:`libcloud.compute.drivers.gandi`          :class:`GandiNodeDriver`            
+`Gandi`_                              :doc:`Click </compute/drivers/gandi>`         GANDI               :mod:`libcloud.compute.drivers.gandi`          :class:`GandiNodeDriver`            
 `Google Compute Engine`_              :doc:`Click </compute/drivers/gce>`           GCE                 :mod:`libcloud.compute.drivers.gce`            :class:`GCENodeDriver`              
 `GoGrid`_                                                                           GOGRID              :mod:`libcloud.compute.drivers.gogrid`         :class:`GoGridNodeDriver`           
 `HostVirtual`_                                                                      HOSTVIRTUAL         :mod:`libcloud.compute.drivers.hostvirtual`    :class:`HostVirtualNodeDriver`      


[5/7] libcloud git commit: Added Gandi Computer Driver Documentation

Posted by to...@apache.org.
Added Gandi Computer Driver Documentation

Closes #534

Signed-off-by: Tomaz Muraus <to...@tomaz.me>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/3c5522f5
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/3c5522f5
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/3c5522f5

Branch: refs/heads/trunk
Commit: 3c5522f5141b2422b2e4cbabd474f7caf27d4433
Parents: cec4b49
Author: ZuluPro <mo...@hotmail.com>
Authored: Wed Jun 3 03:06:36 2015 -0400
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sat Jun 13 20:32:20 2015 +0800

----------------------------------------------------------------------
 docs/compute/drivers/gandi.rst             | 36 +++++++++++++++++++++++++
 docs/examples/compute/gandi/create_node.py | 12 +++++++++
 libcloud/test/compute/test_gandi.py        |  2 +-
 3 files changed, 49 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/3c5522f5/docs/compute/drivers/gandi.rst
----------------------------------------------------------------------
diff --git a/docs/compute/drivers/gandi.rst b/docs/compute/drivers/gandi.rst
new file mode 100644
index 0000000..01d2a7a
--- /dev/null
+++ b/docs/compute/drivers/gandi.rst
@@ -0,0 +1,36 @@
+Gandi Computer Driver Documentation
+===================================
+
+`Gandi SAS`_ is a registrar, web hosting and private and `public cloud`_
+provider based in France with data centers in France, Luxembourg and USA.
+
+.. figure:: /_static/images/provider_logos/gandi.png
+    :align: center
+    :width: 300
+    :target: https://www.gandi.net/
+
+Instantiating a driver
+----------------------
+
+When you instantiate a driver you need to pass the API key and activate
+the API platforms. See this `Gandi's documentation`_ for how to do it.
+
+Examples
+--------
+
+Create instance
+~~~~~~~~~~~~~~~
+
+.. literalinclude:: /examples/compute/gandi/create_node.py
+
+
+.. _`Gandi SAS`: https://www.gandi.net/
+.. _`public cloud`: https://www.gandi.net/hebergement/serveur
+.. _`Gandi's documentation`: https://wiki.gandi.net/en/xml-api/activate
+
+API Docs
+--------
+
+.. autoclass:: libcloud.compute.drivers.gandi.GandiNodeDriver
+    :members:
+    :inherited-members:

http://git-wip-us.apache.org/repos/asf/libcloud/blob/3c5522f5/docs/examples/compute/gandi/create_node.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/gandi/create_node.py b/docs/examples/compute/gandi/create_node.py
new file mode 100644
index 0000000..213f9eb
--- /dev/null
+++ b/docs/examples/compute/gandi/create_node.py
@@ -0,0 +1,12 @@
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+Gandi = get_driver(Provider.GANDI)
+driver = Gandi('api_key')
+
+image = [i for i in driver.list_images() if 'Debian 8 64' in i.name][0]
+size = [s for s in driver.list_sizes() if s.name == 'Medium instance'][0]
+location = [l for l in driver.list_locations() if l.name == 'Equinix Paris'][0]
+
+node = driver.create_node(name='yournode', size=size, image=image,
+                          location=location, login="youruser", password="pass")

http://git-wip-us.apache.org/repos/asf/libcloud/blob/3c5522f5/libcloud/test/compute/test_gandi.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_gandi.py b/libcloud/test/compute/test_gandi.py
index 1cdbcf2..0c00c15 100644
--- a/libcloud/test/compute/test_gandi.py
+++ b/libcloud/test/compute/test_gandi.py
@@ -156,7 +156,7 @@ class GandiTests(unittest.TestCase):
 
     def test_list_key_pairs(self):
         keys = self.driver.list_key_pairs()
-        self.assertGreater(len(keys), 0)
+        self.assertTrue(len(keys) > 0)
 
     def test_get_key_pair(self):
         key = self.driver.get_key_pair(10)