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:12 UTC
[2/7] libcloud git commit: Added Gandi keypair management
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):