From 99714e88e832ecc8298152394a01162615167e4e Mon Sep 17 00:00:00 2001 From: Aymeric Barantal Date: Wed, 21 Sep 2011 11:25:42 +0200 Subject: [PATCH 3/7] ex_ methods ex_list_interfaces, ex_list_disk, ex_attach_[iface|disk] also detach --- libcloud/common/gandi.py | 87 ++++++++++++++++++++++++++++++++++ libcloud/compute/drivers/gandi.py | 94 ++++++++++++++++++++++++++++++++++++- 2 files changed, 180 insertions(+), 1 deletions(-) diff --git a/libcloud/common/gandi.py b/libcloud/common/gandi.py index 4f93b03..359f81e 100644 --- a/libcloud/common/gandi.py +++ b/libcloud/common/gandi.py @@ -17,6 +17,7 @@ Gandi driver base classes """ import time +import hashlib import xmlrpclib import libcloud @@ -145,3 +146,89 @@ class BaseGandiDriver(object): time.sleep(check_interval) return False + + +class BaseObject(object): + """Base class for objects not conventional""" + + uuid_prefix = '' + + def __init__(self, id, state, driver): + self.id = str(id) if id else None + self.state = state + self.driver = driver + self.uuid = self.get_uuid() + + def get_uuid(self): + """Unique hash for this object + + @return: C{string} + + The hash is a function of an SHA1 hash of prefix, the object's ID and + its driver which means that it should be unique between all + interfaces. + TODO : to review + >>> from libcloud.compute.drivers.dummy import DummyNodeDriver + >>> driver = DummyNodeDriver(0) + >>> vif = driver.create_interface() + >>> vif.get_uuid() + 'd3748461511d8b9b0e0bfa0d4d3383a619a2bb9f' + + Note, for example, that this example will always produce the + same UUID! + """ + return hashlib.sha1("%s:%s:%d" % \ + (self.uuid_prefix, self.id, self.driver.type)).hexdigest() + + +class IPAddress(BaseObject): + """ + Provide a common interface for ip addresses + """ + + uuid_prefix = 'inet:' + + def __init__(self, id, state, inet, driver, version=4, extra=None): + BaseObject.__init__(self, id, state, driver) + self.inet = inet + self.version = version + self.extra = extra or {} + + def __repr__(self): + return (('') + % (self.id, self.inet, self.state, self.driver.name)) + + +class NetworkInterface(BaseObject): + """ + Provide a common interface for network interfaces + """ + + uuid_prefix = 'if:' + + def __init__(self, id, state, mac_address, driver, + ips=None, node_id=None, extra=None): + BaseObject.__init__(self, id, state, driver) + self.mac = mac_address + self.ips = ips or {} + self.node_id = node_id + self.extra = extra or {} + + def __repr__(self): + return (('') + % (self.id, self.mac, self.state, self.driver.name)) + + +class Disk(BaseObject): + """ + Gandi disk component + """ + def __init__(self, id, state, name, driver, size, extra=None): + BaseObject.__init__(self, id, state, driver) + self.name = name + self.size = size + self.extra = extra or {} + + def __repr__(self): + return (('') + % (self.id, self.name, self.state, self.size, self.driver.name)) diff --git a/libcloud/compute/drivers/gandi.py b/libcloud/compute/drivers/gandi.py index 6661c92..a9b1ab7 100644 --- a/libcloud/compute/drivers/gandi.py +++ b/libcloud/compute/drivers/gandi.py @@ -15,11 +15,13 @@ """ Gandi driver for compute """ -from libcloud.common.gandi import BaseGandiDriver, GandiException +from libcloud.common.gandi import BaseGandiDriver, GandiException, \ + NetworkInterface, IPAddress, Disk from libcloud.compute.types import NodeState from libcloud.compute.base import Node, NodeDriver from libcloud.compute.base import NodeSize, NodeImage, NodeLocation + NODE_STATE_MAP = { 'running': NodeState.RUNNING, 'halted': NodeState.TERMINATED, @@ -258,3 +260,93 @@ class GandiNodeDriver(BaseGandiDriver, NodeDriver): def list_locations(self): res = self.connection.request("datacenter.list") return [self._to_loc(l) for l in res] + + def _to_iface(self, iface): + ips = [] + for ip in iface.get('ips'): + new_ip = IPAddress( + ip['id'], + NODE_STATE_MAP.get( + ip['state'], + NodeState.UNKNOWN + ), + ip['ip'], + self.connection.driver, + version=ip.get('version'), + extra={'reverse': ip['reverse']} + ) + ips.append(new_ip) + return NetworkInterface( + iface['id'], + NODE_STATE_MAP.get( + iface['state'], + NodeState.UNKNOWN + ), + mac_address=None, + driver=self.connection.driver, + ips=ips, + node_id=iface.get('vm_id'), + extra={'bandwidth': iface['bandwidth']}, + ) + + def _to_ifaces(self, ifaces): + return [self._to_iface(i) for i in ifaces] + + def ex_list_interfaces(self): + """Specific method to list network interfaces""" + ifaces = self.connection.request('iface.list') + ips = self.connection.request('ip.list') + for iface in ifaces: + iface['ips'] = filter(lambda i: i['iface_id'] == iface['id'], ips) + return self._to_ifaces(ifaces) + + def _to_disk(self, element): + disk = Disk( + id=element['id'], + state=NODE_STATE_MAP.get( + element['state'], + NodeState.UNKNOWN + ), + name=element['name'], + driver=self.connection.driver, + size=element['size'], + extra={'can_snapshot': element['can_snapshot']} + ) + return disk + + def _to_disks(self, elements): + return [self._to_disk(el) for el in elements] + + def ex_list_disks(self): + """Specific method to list all disk""" + res = self.connection.request('disk.list', {}) + disks = [] + return self._to_disks(res) + + def ex_attach_disk(self, disk, node): + """Specific method to attach a disk to a node""" + op = self.connection.request('vm.disk_attach', int(node.id), int(disk.id)) + if self._wait_operation(op['id']): + return True + return False + + def ex_detach_disk(self, disk, node): + """Specific method to detach a disk from a node""" + op = self.connection.request('vm.disk_detach', int(node.id), int(disk.id)) + if self._wait_operation(op['id']): + return True + return False + + def ex_attach_interface(self, iface, node): + """Specific method to attach an interface to a node""" + op = self.connection.request('vm.iface_attach', int(node.id), int(iface.id)) + if self._wait_operation(op['id']): + return True + return False + + def ex_detach_interface(self, iface, node): + """Specific method to detach an interface from a node""" + op = self.connection.request('vm.iface_detach', int(node.id), int(iface.id)) + if self._wait_operation(op['id']): + return True + return False -- 1.7.6.1