Author: tomaz
Date: Wed Aug 22 04:33:49 2012
New Revision: 1375895
URL: http://svn.apache.org/viewvc?rev=1375895&view=rev
Log:
Add new methods for managing storage volumes and other extenstion methods
to the IBM SCE driver. Contributed by Sengor Kusturica, part of LIBCLOUD-242.
Added:
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/allocate_address.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/attach_volume.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/create_volume.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/delete_address.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/destroy_volume.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/detach_volume.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_addresses.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_storage_offerings.xml
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_volumes.xml
Modified:
libcloud/trunk/CHANGES
libcloud/trunk/libcloud/compute/drivers/ibm_sce.py
libcloud/trunk/libcloud/test/compute/test_ibm_sce.py
Modified: libcloud/trunk/CHANGES
URL:
http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1375895&r1=1375894&r2=1375895&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Wed Aug 22 04:33:49 2012
@@ -19,6 +19,10 @@ Changes with Apache Libcloud in developm
LIBCLOUD-243
[Nick Bailey]
+ - Add new methods for managing storage volumes and other extenstion methods
+ to the IBM SCE driver. ; LIBCLOUD-242
+ [Sengor Kusturica]
+
*) Storage
- Add the following new methods to the CloudFiles driver:
Modified: libcloud/trunk/libcloud/compute/drivers/ibm_sce.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/ibm_sce.py?rev=1375895&r1=1375894&r2=1375895&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/ibm_sce.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/ibm_sce.py Wed Aug 22 04:33:49 2012
@@ -17,20 +17,22 @@
Driver for IBM SmartCloud Enterprise
Formerly known as:
-- IBM Developer Cloud.
+- IBM Developer Cloud
+- IBM Smart Business Development and Test on the IBM Cloud
- IBM SmartBusiness Cloud
"""
import base64
+import time
from libcloud.utils.py3 import urlencode
from libcloud.utils.py3 import b
from libcloud.common.base import XmlResponse, ConnectionUserAndKey
-from libcloud.common.types import InvalidCredsError
+from libcloud.common.types import InvalidCredsError, LibcloudError
from libcloud.compute.types import NodeState, Provider
from libcloud.compute.base import NodeDriver, Node, NodeImage, \
- NodeSize, NodeLocation, NodeAuthSSHKey
+ NodeSize, NodeLocation, NodeAuthSSHKey, StorageVolume
HOST = 'www-147.ibm.com'
REST_BASE = '/computecloud/enterprise/api/rest/20100331'
@@ -51,7 +53,7 @@ class IBMResponse(XmlResponse):
class IBMConnection(ConnectionUserAndKey):
"""
- Connection class for the IBM Developer Cloud driver
+ Connection class for the IBM SmartCloud Enterprise driver
"""
host = HOST
@@ -69,6 +71,77 @@ class IBMConnection(ConnectionUserAndKey
return urlencode(data)
+class IBMNodeLocation(NodeLocation):
+ """
+ Extends the base LibCloud NodeLocation to contain additional attributes
+ """
+ def __init__(self, id, name, country, driver, extra=None):
+ self.id = str(id)
+ self.name = name
+ self.country = country
+ self.driver = driver
+ self.extra = extra or {}
+
+ def __repr__(self):
+ return ('<IBMNodeLocation: id=%s, name=%s, country=%s, '
+ 'driver=%s, extra=%s>' % self.id, self.name, self.country,
+ self.driver.name, self.extra)
+
+
+class VolumeState(object):
+ """
+ The SCE specific states for a storage volume
+ """
+ NEW = '0'
+ CREATING = '1'
+ DELETING = '2'
+ DELETED = '3'
+ DETACHED = '4'
+ ATTACHED = '5'
+ FAILED = '6'
+ DELETE_PENDING = '7'
+ BEING_CLONED = '8'
+ CLONING = '9'
+ ATTACHING = '10'
+ DETACHING = '11'
+ ATTACHIED = '12'
+ IMPORTING = '13'
+ TRANSFER_RETRYING = '14'
+
+
+class VolumeOffering(object):
+ """
+ An SCE specific storage volume offering class.
+ The volume offering ID is needed to create a volume.
+ Volume offering IDs are different for each data center.
+ """
+ def __init__(self, id, name, location, extra=None):
+ self.id = id
+ self.location = location
+ self.name = name
+ self.extra = extra or {}
+
+ def __repr__(self):
+ return ('<VolumeOffering: id=%s, location=%s, name=%s, extra=%s>' %
+ self.id, self.location, self.name, self.extra)
+
+
+class Address(object):
+ """
+ A reserved IP address that can be attached to an instance.
+ Properties: id, ip, state, options(location, type, created_time, state,
hostname, instance_ids, vlan, owner,
+ mode, offering_id)
+ """
+ def __init__(self, id, ip, state, options):
+ self.id = id
+ self.ip = ip
+ self.state = state
+ self.options = options
+
+ def __repr__(self):
+ return ('<Address: id=%s, ip=%s, state=%s, options=%s>' %
+ self.id, self.ip, self.state, self.options)
+
class IBMNodeDriver(NodeDriver):
"""
Node driver for IBM SmartCloud Enterprise
@@ -94,12 +167,14 @@ class IBMNodeDriver(NodeDriver):
12: NodeState.PENDING, # Deprovision Pending
13: NodeState.PENDING, # Restart Pending
14: NodeState.PENDING, # Attaching
- 15: NodeState.PENDING, # Detaching
+ 15: NodeState.PENDING, # Detaching
}
def create_node(self, **kwargs):
"""
- Creates a node in the IBM Developer Cloud.
+ Creates a node in the IBM SmartCloud Enterprise.
+
+ See L{NodeDriver.create_node} for more keyword args.
@inherits: L{NodeDriver.create_node}
@@ -131,8 +206,9 @@ class IBMNodeDriver(NodeDriver):
data.update({'publicKey': kwargs['auth'].pubkey})
if 'ex_configurationData' in kwargs:
configurationData = kwargs['ex_configurationData']
- for key in configurationData.keys():
- data.update({key: configurationData.get(key)})
+ if configurationData:
+ for key in configurationData.keys():
+ data.update({key: configurationData.get(key)})
# Send request!
resp = self.connection.request(
@@ -142,12 +218,164 @@ class IBMNodeDriver(NodeDriver):
data=data).object
return self._to_nodes(resp)[0]
+ def create_volume(self, size, name, location, **kwargs):
+ """
+ Create a new block storage volume (virtual disk)
+
+ @param size: Size of volume in gigabytes (required).
+ Find out the possible sizes from the
+ offerings/storage REST interface
+ @type size: C{int}
+
+ @keyword name: Name of the volume to be created (required)
+ @type name: C{str}
+
+ @keyword location: Which data center to create a volume in. If
+ empty, it will fail for IBM SmartCloud Enterprise
+ (required)
+ @type location: L{NodeLocation}
+
+ @keyword snapshot: Not supported for IBM SmartCloud Enterprise
+ @type snapshot: C{str}
+
+ @keyword kwargs.format: Either RAW or EXT3 for IBM SmartCloud
+ Enterprise (optional)
+ @type kwargs.format: C{str}
+
+ @keyword kwargs.offering_id: The storage offering ID for IBM
+ SmartCloud Enterprise
+ Find this from the REST interface
+ storage/offerings. (optional)
+ @type kwargs.offering_id: C{str}
+
+ @keyword kwargs.source_disk_id: If cloning a volume, the storage
+ disk to make a copy from (optional)
+ @type kwargs.source_disk_id: C{str}
+
+ @keyword kwargs.storage_area_id: The id of the storage availability
+ area to create the volume in
+ (optional)
+ @type kwargs.storage_area_id: C{str}
+
+ @keyword kwargs.target_location_id: If cloning a volume, the
+ storage disk to make a copy
+ from (optional)
+ @type kwargs.target_location_id: C{str}
+
+ @return: The newly created L{StorageVolume}.
+ """
+ data = {}
+ data.update({'name': name})
+ data.update({'size': size})
+ data.update({'location': location})
+ if (('format' in kwargs) and (kwargs['format'] is not None)):
+ data.update({'format': kwargs['format']})
+ if (('offering_id' in kwargs) and (kwargs['offering_id'] is not None)):
+ data.update({'offeringID': kwargs['offering_id']})
+ if (('storage_area_id' in kwargs) and (kwargs['storage_area_id'] is
not None)):
+ data.update({'storageAreaID': kwargs['storage_area_id']})
+ if 'source_disk_id' in kwargs:
+ data.update({'sourceDiskID': kwargs['source_disk_id']})
+ data.update({'type': 'clone'})
+ if 'target_location_id' in kwargs:
+ data.update({'targetLocationID': kwargs['target_location_id']})
+ resp = self.connection.request(action=REST_BASE + '/storage',
+ headers={'Content-Type': 'application/x-www-form-urlencoded'},
+ method='POST',
+ data=data).object
+ return self._to_volumes(resp)[0]
+
+ def create_image(self, name, description=None, **kwargs):
+ """
+ Create a new node image from an existing volume or image.
+
+ @param name: Name of the image to be created (required)
+ @type name: C{str}
+
+ @param description: Description of the image to be created
(optional)
+ @type description: L{str}
+
+ @keyword kwarge.image_id: The ID of the source image if cloning
the image
+ @type kwargs.image_id: C{str}
+
+ @keyword kwargs.volume_id: The ID of the storage volume if
importing the image
+ @type kwargs.volume_id: C{str}
+
+ @return: The newly created L{NodeImage}.
+ """
+ data = {}
+ data.update({'name': name})
+ if description is not None:
+ data.update({'description': description})
+ if (('image_id' in kwargs) and (kwargs['image_id'] is not None)):
+ data.update({'imageId': kwargs['image_id']})
+ if (('volume_id' in kwargs) and (kwargs['volume_id'] is not None)):
+ data.update({'volumeId': kwargs['volume_id']})
+ resp = self.connection.request(action=REST_BASE + '/offerings/image',
+ headers={'Content-Type': 'application/x-www-form-urlencoded'},
+ method='POST',
+ data=data).object
+ return self._to_images(resp)[0]
+
def destroy_node(self, node):
url = REST_BASE + '/instances/%s' % (node.id)
status = int(self.connection.request(action=url,
method='DELETE').status)
return status == 200
+ def destroy_volume(self, volume):
+ """
+ Destroys a storage volume.
+
+ @param volume: Volume to be destroyed
+ @type volume: L{StorageVolume}
+
+ @return: C{bool}
+ """
+ url = REST_BASE + '/storage/%s' % (volume.id)
+ status = int(self.connection.request(action=url,
+ method='DELETE').status)
+ return status == 200
+
+ def attach_volume(self, node, volume):
+ """
+ Attaches volume to node.
+
+ @param node: Node to attach volume to
+ @type node: L{Node}
+
+ @param volume: Volume to attach
+ @type volume: L{StorageVolume}
+
+ @return: C{bool}
+ """
+ url = REST_BASE + '/instances/%s' % (node.id)
+ headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+ data = {'storageID': volume.id, 'type': 'attach'}
+ resp = self.connection.request(action=url,
+ method='PUT',
+ headers=headers,
+ data=data)
+ return int(resp.status) == 200
+
+ def detach_volume(self, node, volume):
+ """
+ Detaches a volume from a node.
+
+ @param volume: Volume to be detached
+ @type volume: L{StorageVolume}
+
+ @returns C{bool}
+ """
+ url = REST_BASE + '/instances/%s' % (node.id)
+ headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+ data = {'storageID': volume.id, 'type': 'detach'}
+ resp = self.connection.request(action=url,
+ method='PUT',
+ headers=headers,
+ data=data)
+ return int(resp.status) == 200
+
def reboot_node(self, node):
url = REST_BASE + '/instances/%s' % (node.id)
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
@@ -167,10 +395,21 @@ class IBMNodeDriver(NodeDriver):
return self._to_images(
self.connection.request(REST_BASE + '/offerings/image').object)
+ def list_volumes(self):
+ """
+ List storage volumes.
+
+ @return: C{list} of L{StorageVolume} objects
+ """
+ return self._to_volumes(
+ self.connection.request(REST_BASE + '/storage').object)
+
def list_sizes(self, location=None):
"""
- Returns a generic list of sizes. See list_images() for a
- list of supported sizes for specific images.
+ Returns a generic list of sizes. See list_images() for a list of
supported
+ sizes for specific images. In particular, you need to have a size that
+ matches the architecture (32-bit vs 64-bit) of the virtual machine
image
+ operating system.
@inherits: L{NodeDriver.list_sizes}
"""
@@ -195,9 +434,124 @@ class IBMNodeDriver(NodeDriver):
None, None, None, None, self.connection.driver)]
def list_locations(self):
+ """
+ List the data center locations
+ """
return self._to_locations(
self.connection.request(REST_BASE + '/locations').object)
+ def ex_list_storage_offerings(self):
+ """
+ List the storage center offerings
+ """
+ return self._to_volume_offerings(
+ self.connection.request(REST_BASE + '/offerings/storage').object)
+
+ def ex_allocate_address(self, location_id, offering_id, vlan_id=None):
+ """
+ Allocate a new reserved IP address
+
+ @param location_id: Target data center
+ @type location_id: L{str}
+ @param offering_id: Offering ID for address to create
+ @type offering_id: L{str}
+ @param vlan_id: ID of target VLAN
+ @type vlan_id: L{str}
+ @return: L{Address} object
+ """
+ url = REST_BASE + '/addresses'
+ headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+ data = {'location': location_id, 'offeringID': offering_id}
+ if vlan_id is not None:
+ data.update({'vlanID': vlan_id})
+ resp = self.connection.request(action=url,
+ method='POST',
+ headers=headers,
+ data=data).object
+ return self._to_addresses(resp)[0]
+
+ def ex_list_addresses(self, resource_id=None):
+ """
+ List the reserved IP addresses
+
+ @param resource_id: If this is supplied only a single address
will be returned (optional)
+ @type resource_id: L{str}
+ """
+ url = REST_BASE + '/addresses'
+ if resource_id:
+ url += '/' + resource_id
+ return self._to_addresses(self.connection.request(url).object)
+
+ def ex_copy_to(self, image, volume):
+ """
+ Copies a node image to a storage volume
+
+ @param image: source image to copy
+ @type image: L{NodeImage}
+
+ @param volume: Target storage volume to copy to
+ @type volume: L{StorageVolume}
+
+ @return: C{bool} The success of the operation
+ """
+ url = REST_BASE + '/storage/%s' % (volume.id)
+ headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+ data = {'imageId': image.id}
+ resp = self.connection.request(action=url,
+ method='PUT',
+ headers=headers,
+ data=data)
+ return int(resp.status) == 200
+
+ def ex_delete_address(self, resource_id):
+ """
+ Delete a reserved IP address
+
+ @param resource_id: The address to delete (required)
+ @type resource_id: L{str}
+ """
+ url = REST_BASE + '/addresses/' + resource_id
+ status = int(self.connection.request(action=url,
+ method='DELETE').status)
+ return status == 200
+
+ def ex_wait_storage_state(self, volume, state=VolumeState.DETACHED,
+ wait_period=60, timeout=1200):
+ """
+ Block until storage volume state changes to the given value
+
+ @param volume: Storage volume.
+ @type node: C{StorageVolume}
+
+ @param state: The target state to wait for
+ @type state: C{int}
+
+ @param wait_period: How many seconds to between each loop
+ iteration (default is 3)
+ @type wait_period: C{int}
+
+ @param timeout: How many seconds to wait before timing out
+ (default is 1200)
+ @type timeout: C{int}
+
+ @return: C{StorageVolume}
+ """
+ start = time.time()
+ end = start + timeout
+
+ while time.time() < end:
+ volumes = self.list_volumes()
+ volumes = list([v for v in volumes if v.uuid == volume.uuid])
+
+ if (len(volumes) == 1 and volumes[0].extra['state'] == state):
+ return volumes[0]
+ else:
+ time.sleep(wait_period)
+ continue
+
+ raise LibcloudError(value='Timed out after %d seconds' % (timeout),
+ driver=self)
+
def _to_nodes(self, object):
return [self._to_node(instance) for instance in
object.findall('Instance')]
@@ -210,16 +564,16 @@ class IBMNodeDriver(NodeDriver):
public_ips.append(ip)
return Node(
- id=instance.findtext('ID'),
- name=instance.findtext('Name'),
- state=self.NODE_STATE_MAP[int(instance.findtext('Status'))],
- public_ips=public_ips,
- private_ips=[],
- driver=self.connection.driver
+ id=instance.findtext('ID'),
+ name=instance.findtext('Name'),
+
state=self.NODE_STATE_MAP[int(instance.findtext('Status'))],
+ public_ips=public_ips,
+ private_ips=[],
+ driver=self.connection.driver
)
def _to_images(self, object):
- #Converts data retrieved from SCE /offerings/image REST call to a NodeImage
+ # Converts data retrieved from SCE /offerings/image REST call to a
NodeImage
return [self._to_image(image) for image in object.findall('Image')]
def _to_image(self, image):
@@ -248,7 +602,7 @@ class IBMNodeDriver(NodeDriver):
'platform': platform,
'description': description,
'documentation': documentation,
- 'supportedInstanceTypes': nodeSizes
+ 'node_sizes': nodeSizes
}
)
@@ -259,11 +613,31 @@ class IBMNodeDriver(NodeDriver):
def _to_location(self, location):
# Converts an SCE Location object to a Libcloud NodeLocation object
name_text = location.findtext('Name')
+ description = location.findtext('Description')
+ state = location.findtext('State')
(nameVal, separator, countryVal) = name_text.partition(',')
- return NodeLocation(id=location.findtext('ID'),
- name=nameVal,
- country=countryVal.strip(),
- driver=self.connection.driver)
+ capabiltyElements = location.findall('Capabilities/Capability')
+ capabilities = {}
+ for elem in capabiltyElements:
+ capabilityID = elem.attrib['id']
+ entryElements = elem.findall('Entry')
+ entries = []
+ for entryElem in entryElements:
+ key = entryElem.attrib['key']
+ valueElements = elem.findall('Value')
+ values = []
+ for valueElem in valueElements:
+ values.append(valueElem.text)
+ entry = {'key': key, 'values': values}
+ entries.append(entry)
+ capabilities[capabilityID] = entries
+ extra = {'description': description, 'state': state,
+ 'capabilities': capabilities}
+ return IBMNodeLocation(id=location.findtext('ID'),
+ name=nameVal,
+ country=countryVal.strip(),
+ driver=self.connection.driver,
+ extra=extra)
def _to_node_sizes(self, object):
# Converts SCE SupportedInstanceTypes object to
@@ -280,3 +654,61 @@ class IBMNodeDriver(NodeDriver):
None,
object.findtext('Price/Rate'),
self.connection.driver)
+
+ def _to_volumes(self, object):
+ return [self._to_volume(iType) for iType in
+ object.findall('Volume')]
+
+ def _to_volume(self, object):
+ # Converts an SCE Volume to a Libcloud StorageVolume
+ extra = {'state': object.findtext('State'),
+ 'location': object.findtext('Location'),
+ 'instanceID': object.findtext('instanceID'),
+ 'owner': object.findtext('Owner'),
+ 'format': object.findtext('Format'),
+ 'createdTime': object.findtext('CreatedTime'),
+ 'storageAreaID': object.findtext('StorageArea/ID')}
+ return StorageVolume(object.findtext('ID'),
+ object.findtext('Name'),
+ object.findtext('Size'),
+ self.connection.driver,
+ extra)
+
+ def _to_volume_offerings(self, object):
+ return [self._to_volume_offering(iType) for iType in
+ object.findall('Offerings')]
+
+ def _to_volume_offering(self, object):
+ # Converts an SCE DescribeVolumeOfferingsResponse/Offerings XML object
+ # to an SCE VolumeOffering
+ extra = {'label': object.findtext('Label'),
+ 'supported_sizes': object.findtext('SupportedSizes'),
+ 'formats': object.findall('SupportedFormats/Format/ID'),
+ 'price': object.findall('Price')}
+ return VolumeOffering(object.findtext('ID'),
+ object.findtext('Name'),
+ object.findtext('Location'),
+ extra)
+
+ def _to_addresses(self, object):
+ # Converts an SCE DescribeAddressesResponse XML object to a list of
+ # Address objects
+ return [self._to_address(iType) for iType in
+ object.findall('Address')]
+
+ def _to_address(self, object):
+ # Converts an SCE DescribeAddressesResponse/Address XML object to
+ # an Address object
+ extra = {'location': object.findtext('Location'),
+ 'type': object.findtext('Label'),
+ 'created_time': object.findtext('SupportedSizes'),
+ 'hostname': object.findtext('Hostname'),
+ 'instance_ids': object.findtext('InstanceID'),
+ 'vlan': object.findtext('VLAN'),
+ 'owner': object.findtext('owner'),
+ 'mode': object.findtext('Mode'),
+ 'offering_id': object.findtext('OfferingID')}
+ return Address(object.findtext('ID'),
+ object.findtext('IP'),
+ object.findtext('State'),
+ extra)
Added:
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/allocate_address.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/allocate_address.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/allocate_address.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/allocate_address.xml
Wed Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:AllocateAddressResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"><Address><Type>RESERVED</Type><IP></IP><Hostname></Hostname><Location>141</Location><ID>292795</ID><OfferingID>20001223</OfferingID><Mode>PRIMARY</Mode><State>0</State><owner>[email protected]</owner></Address></ns2:AllocateAddressResponse>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/attach_volume.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/attach_volume.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/attach_volume.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/attach_volume.xml Wed
Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:AttachStorageResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"/>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/create_volume.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/create_volume.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/create_volume.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/create_volume.xml Wed
Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:CreateVolumeResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"><Volume><ID>39293</ID><Location>141</Location><OfferingID>20001208</OfferingID><Owner>[email protected]</Owner><Name>test-volume</Name><Format>raw</Format><Size>256</Size><State>0</State><ProductCodes/><CreatedTime>2012-08-20T12:25:02.792Z</CreatedTime><StorageArea><ID></ID><Name></Name><Description></Description></StorageArea><IOPrice
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.00</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>CNT</UnitOfMeasure></IOPrice><CloneStatus>0</CloneStatus><PlatformVersion>2</PlatformVersion><SourceDiskId>0</SourceDiskId></Volume></ns2:CreateVolumeResponse>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/delete_address.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/delete_address.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/delete_address.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/delete_address.xml
Wed Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:ReleaseAddressResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"/>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/destroy_volume.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/destroy_volume.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/destroy_volume.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/destroy_volume.xml
Wed Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:DeleteVolumeResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"/>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/detach_volume.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/detach_volume.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/detach_volume.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/detach_volume.xml Wed
Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:DetachStorageResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"/>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_addresses.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_addresses.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_addresses.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_addresses.xml
Wed Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:DescribeAddressesResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"><Address><Type>RESERVED</Type><IP>170.225.160.218</IP><Hostname>vhost0218</Hostname><Location>141</Location><ID>292795</ID><OfferingID>20001223</OfferingID><Mode>PRIMARY</Mode><State>2</State><owner>[email protected]</owner></Address></ns2:DescribeAddressesResponse>
\ No newline at end of file
Added:
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_storage_offerings.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_storage_offerings.xml?rev=1375895&view=auto
==============================================================================
---
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_storage_offerings.xml
(added)
+++
libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_storage_offerings.xml
Wed Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:DescribeVolumeOfferingsResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"><Offerings><ID>20001208</ID><Location>61</Location><Name>Small</Name><Label>256
GiB</Label><Capacity>256</Capacity><SupportedSizes>256</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001208</ID><Location>82</Location><Name>Small</Name><Label>256
GiB</Label><Capacity>256</Capacity><SupportedSizes>256</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011
-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001209</ID><Location>61</Location><Name>Medium</Name><Label>512
GiB</Label><Capacity>512</Capacity><SupportedSizes>512</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001209</ID><Location>82</Location><Name>Medium</Name><Label>512
GiB</Label><Capacity>512</Capacity><SupportedSizes>512</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCod
e="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001208</ID><Location>41</Location><Name>Small</Name><Label>256
GiB</Label><Capacity>256</Capacity><SupportedSizes>256</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001209</ID><Location>41</Location><Name>Medium</Name><Label>512
GiB</Label><Capacity>512</Capacity><SupportedSizes>512</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></Supporte
dFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001208</ID><Location>121</Location><Name>Small</Name><Label>256
GiB</Label><Capacity>256</Capacity><SupportedSizes>256</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001209</ID><Location>121</Location><Name>Medium</Name><Label>512
GiB</Label><Capacity>512</Capacity><SupportedSizes>512</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>ra
w</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001210</ID><Location>61</Location><Name>Large</Name><Label>2048
GiB</Label><Capacity>2048</Capacity><SupportedSizes>2048</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001210</ID><Location>82</Location><Name>Large</Name><Label>2048
GiB</Label><Capacity>2048</Capacity><SupportedSizes>2048</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Forma
t><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001210</ID><Location>41</Location><Name>Large</Name><Label>2048
GiB</Label><Capacity>2048</Capacity><SupportedSizes>2048</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001210</ID><Location>121</Location><Name>Large</Name><Label>2048
GiB</Label><Capacity>2048</Capacity><SupportedSizes>2048</SupportedSizes><SupportedFormats><Format><ID>EXT
3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001208</ID><Location>101</Location><Name>Small</Name><Label>256
GiB</Label><Capacity>256</Capacity><SupportedSizes>256</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001209</ID><Location>101</Location><Name>Medium</Name><Label>512
GiB</Label><Capacity>512</Capacity><SupportedSizes>512</SupportedSizes><Supp
ortedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001208</ID><Location>141</Location><Name>Small</Name><Label>256
GiB</Label><Capacity>256</Capacity><SupportedSizes>256</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001209</ID><Location>141</Location><Name>Medium</Name><Label>512
GiB</Label><Capacity>512</Capacity><SupportedSiz
es>512</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001210</ID><Location>101</Location><Name>Large</Name><Label>2048
GiB</Label><Capacity>2048</Capacity><SupportedSizes>2048</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings><Offerings><ID>20001210</ID><Location>141</Location><Name>Large</Name><Label>2048
GiB</Label><Capac
ity>2048</Capacity><SupportedSizes>2048</SupportedSizes><SupportedFormats><Format><ID>EXT3</ID><Label>ext3</Label></Format><Format><ID>RAW</ID><Label>raw</Label></Format></SupportedFormats><Price
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.0000</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>UHR</UnitOfMeasure></Price></Offerings></ns2:DescribeVolumeOfferingsResponse>
\ No newline at end of file
Added: libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_volumes.xml
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_volumes.xml?rev=1375895&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_volumes.xml
(added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/ibm_sce/list_volumes.xml Wed
Aug 22 04:33:49 2012
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><ns2:DescribeVolumesResponse
xmlns:ns2="http://www.ibm.com/xmlns/b2b/cloud/api/2010-03-31"><Volume><ID>39281</ID><Location>141</Location><OfferingID>20001210</OfferingID><InstanceID>0</InstanceID><Owner>[email protected]</Owner><Name>libcloudvol</Name><Format>raw</Format><Size>2048</Size><State>4</State><ProductCodes/><CreatedTime>2012-08-19T13:46:50.000Z</CreatedTime><StorageArea><ID></ID><Name></Name><Description></Description></StorageArea><IOPrice
CountryCode="ABC"><EffectiveDate>2011-08-12T00:00:00.000Z</EffectiveDate><CurrencyCode>USD</CurrencyCode><Rate>0.00</Rate><PricePerQuantity>1</PricePerQuantity><UnitOfMeasure>CNT</UnitOfMeasure></IOPrice><CloneStatus>0</CloneStatus><PlatformVersion>2</PlatformVersion><SourceDiskId>0</SourceDiskId></Volume></ns2:DescribeVolumesResponse>
\ No newline at end of file
Modified: libcloud/trunk/libcloud/test/compute/test_ibm_sce.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/test_ibm_sce.py?rev=1375895&r1=1375894&r2=1375895&view=diff
==============================================================================
--- libcloud/trunk/libcloud/test/compute/test_ibm_sce.py (original)
+++ libcloud/trunk/libcloud/test/compute/test_ibm_sce.py Wed Aug 22 04:33:49
2012
@@ -26,7 +26,7 @@ from libcloud.test.secrets import IBM_PA
class IBMTests(unittest.TestCase, TestCaseMixin):
"""
- Tests the IBM Developer Cloud driver.
+ Tests the IBM SmartCloud Enterprise driver.
"""
def setUp(self):
@@ -117,7 +117,7 @@ class IBMTests(unittest.TestCase, TestCa
self.fail('test should have thrown')
def test_destroy_node(self):
- # Delete existant node
+ # Delete existent node
nodes = self.driver.list_nodes() # retrieves 3 nodes
self.assertEquals(len(nodes), 3)
IBMMockHttp.type = 'DELETE'
@@ -155,6 +155,71 @@ class IBMTests(unittest.TestCase, TestCa
else:
self.fail('test should have thrown')
+ def test_list_volumes(self):
+ ret = self.driver.list_volumes()
+ self.assertEqual(len(ret), 1)
+ self.assertEqual(ret[0].name, 'libcloudvol')
+ self.assertEqual(ret[0].extra['location'], '141')
+ self.assertEqual(ret[0].size, '2048')
+ self.assertEqual(ret[0].id, '39281')
+
+ def test_attach_volume(self):
+ vols = self.driver.list_volumes()
+ nodes = self.driver.list_nodes()
+ IBMMockHttp.type = 'ATTACH'
+ ret = self.driver.attach_volume(nodes[0], vols[0])
+ self.assertTrue(ret)
+
+ def test_create_volume(self):
+ IBMMockHttp.type = 'CREATE'
+ ret = self.driver.create_volume('256',
+ 'test-volume',
+ location='141',
+ format='RAW',
+ offering_id='20001208')
+ self.assertEqual(ret.id, '39293')
+ self.assertEqual(ret.size, '256')
+ self.assertEqual(ret.name, 'test-volume')
+ self.assertEqual(ret.extra['location'], '141')
+
+ def test_destroy_volume(self):
+ vols = self.driver.list_volumes()
+ IBMMockHttp.type = 'DESTROY'
+ ret = self.driver.destroy_volume(vols[0])
+ self.assertTrue(ret)
+
+ def test_detach_volume(self):
+ nodes = self.driver.list_nodes()
+ vols = self.driver.list_volumes()
+ IBMMockHttp.type = 'DETACH'
+ ret = self.driver.detach_volume(nodes[0], vols[0])
+ self.assertTrue(ret)
+
+ def test_ex_allocate_address(self):
+ IBMMockHttp.type = 'ALLOCATE'
+ ret = self.driver.ex_allocate_address('141', '20001223')
+ self.assertEqual(ret.id, '292795')
+ self.assertEqual(ret.state, '0')
+ self.assertEqual(ret.options['location'], '141')
+
+ def test_ex_delete_address(self):
+ IBMMockHttp.type = 'DELETE'
+ ret = self.driver.ex_delete_address('292795')
+ self.assertTrue(ret)
+
+ def test_ex_list_addresses(self):
+ ret = self.driver.ex_list_addresses()
+ self.assertEqual(ret[0].ip, '170.225.160.218')
+ self.assertEqual(ret[0].options['location'], '141')
+ self.assertEqual(ret[0].id, '292795')
+ self.assertEqual(ret[0].state, '2')
+
+ def test_ex_list_storage_offerings(self):
+ ret = self.driver.ex_list_storage_offerings()
+ self.assertEqual(ret[0].name, 'Small')
+ self.assertEqual(ret[0].location, '61')
+ self.assertEqual(ret[0].id, '20001208')
+
class IBMMockHttp(MockHttp):
fixtures = ComputeFileFixtures('ibm_sce')
@@ -198,6 +263,42 @@ class IBMMockHttp(MockHttp):
def
_computecloud_enterprise_api_rest_20100331_instances_CREATE_INVALID(self,
method, url, body, headers):
return (412, 'Error 412: No DataCenter with id: 3', {}, 'Precondition
Failed')
+ def _computecloud_enterprise_api_rest_20100331_storage(self, method, url,
body, headers):
+ body = self.fixtures.load('list_volumes.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def
_computecloud_enterprise_api_rest_20100331_instances_26557_ATTACH(self, method,
url, body, headers):
+ body = self.fixtures.load('attach_volume.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_storage_CREATE(self,
method, url, body, headers):
+ body = self.fixtures.load('create_volume.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_storage_39281_DESTROY(self,
method, url, body, headers):
+ body = self.fixtures.load('destroy_volume.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def
_computecloud_enterprise_api_rest_20100331_instances_26557_DETACH(self, method,
url, body, headers):
+ body = self.fixtures.load('detach_volume.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_addresses_ALLOCATE(self,
method, url, body, headers):
+ body = self.fixtures.load('allocate_address.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def
_computecloud_enterprise_api_rest_20100331_addresses_292795_DELETE(self,
method, url, body, headers):
+ body = self.fixtures.load('delete_address.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_addresses(self, method,
url, body, headers):
+ body = self.fixtures.load('list_addresses.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_offerings_storage(self,
method, url, body, headers):
+ body = self.fixtures.load('list_storage_offerings.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
# This is only to accomodate the response tests built into test\__init__.py
def _computecloud_enterprise_api_rest_20100331_instances_26557(self,
method, url, body, headers):
if method == 'DELETE':