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 2012/11/18 02:23:01 UTC
svn commit: r1410809 [4/4] - in /libcloud/branches/0.11.x: ./ libcloud/
libcloud/common/ libcloud/compute/ libcloud/compute/drivers/ libcloud/data/
libcloud/dns/ libcloud/dns/drivers/ libcloud/loadbalancer/
libcloud/loadbalancer/drivers/ libcloud/stora...
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/dummy.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/dummy.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/dummy.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/dummy.py Sun Nov 18 01:22:54 2012
@@ -53,6 +53,7 @@ class DummyFileObject(file):
def __len__(self):
return self._yield_count * self._chunk_len
+
class DummyIterator(object):
def __init__(self, data=None):
self.hash = hashlib.md5()
@@ -91,8 +92,16 @@ class DummyStorageDriver(StorageDriver):
"""
name = 'Dummy Storage Provider'
+ website = 'http://example.com'
def __init__(self, api_key, api_secret):
+ """
+ @param api_key: API key or username to used (required)
+ @type api_key: C{str}
+ @param api_secret: Secret password to be used (required)
+ @type api_secret: C{str}
+ @rtype: C{None}
+ """
self._containers = {}
def get_meta_data(self):
@@ -106,11 +115,13 @@ class DummyStorageDriver(StorageDriver):
... object_name='test object', iterator=DummyFileObject(5, 10), extra={})
>>> driver.get_meta_data()
{'object_count': 1, 'container_count': 2, 'bytes_used': 50}
+
+ @rtype: C{dict}
"""
container_count = len(self._containers)
- object_count = sum([ len(self._containers[container]['objects']) for
- container in self._containers ])
+ object_count = sum([len(self._containers[container]['objects']) for
+ container in self._containers])
bytes_used = 0
for container in self._containers:
@@ -118,9 +129,9 @@ class DummyStorageDriver(StorageDriver):
for _, obj in objects.items():
bytes_used += obj.size
- return { 'container_count': int(container_count),
- 'object_count': int(object_count),
- 'bytes_used': int(bytes_used) }
+ return {'container_count': int(container_count),
+ 'object_count': int(object_count),
+ 'bytes_used': int(bytes_used)}
def list_containers(self):
"""
@@ -142,6 +153,8 @@ class DummyStorageDriver(StorageDriver):
>>> container_list=driver.list_containers()
>>> sorted([container.name for container in container_list])
['test container 1', 'test container 2']
+
+ @inherits: L{StorageDriver.list_containers}
"""
return [container['container'] for container in
@@ -165,6 +178,8 @@ class DummyStorageDriver(StorageDriver):
'test container 1'
>>> driver.get_container('test container 1')
<Container: name=test container 1, provider=Dummy Storage Provider>
+
+ @inherits: L{StorageDriver.get_container}
"""
if container_name not in self._containers:
@@ -186,6 +201,8 @@ class DummyStorageDriver(StorageDriver):
'test container 1'
>>> container.get_cdn_url()
'http://www.test.com/container/test_container_1'
+
+ @inherits: L{StorageDriver.get_container_cdn_url}
"""
if container.name not in self._containers:
@@ -195,54 +212,57 @@ class DummyStorageDriver(StorageDriver):
return self._containers[container.name]['cdn_url']
def get_object(self, container_name, object_name):
- """
- >>> driver = DummyStorageDriver('key', 'secret')
- >>> driver.get_object('unknown', 'unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
- Traceback (most recent call last):
- ContainerDoesNotExistError:
- >>> container = driver.create_container(container_name='test container 1')
- >>> container
- <Container: name=test container 1, provider=Dummy Storage Provider>
- >>> driver.get_object(
- ... 'test container 1', 'unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
- Traceback (most recent call last):
- ObjectDoesNotExistError:
- >>> obj = container.upload_object_via_stream(object_name='test object',
- ... iterator=DummyFileObject(5, 10), extra={})
- >>> obj
- <Object: name=test object, size=50, hash=None, provider=Dummy Storage Provider ...>
- """
-
- self.get_container(container_name)
- container_objects = self._containers[container_name]['objects']
- if object_name not in container_objects:
+ """
+ >>> driver = DummyStorageDriver('key', 'secret')
+ >>> driver.get_object('unknown', 'unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ContainerDoesNotExistError:
+ >>> container = driver.create_container(container_name='test container 1')
+ >>> container
+ <Container: name=test container 1, provider=Dummy Storage Provider>
+ >>> driver.get_object(
+ ... 'test container 1', 'unknown') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ObjectDoesNotExistError:
+ >>> obj = container.upload_object_via_stream(object_name='test object',
+ ... iterator=DummyFileObject(5, 10), extra={})
+ >>> obj
+ <Object: name=test object, size=50, hash=None, provider=Dummy Storage Provider ...>
+
+ @inherits: L{StorageDriver.get_object}
+ """
+
+ self.get_container(container_name)
+ container_objects = self._containers[container_name]['objects']
+ if object_name not in container_objects:
raise ObjectDoesNotExistError(object_name=object_name, value=None,
driver=self)
- return container_objects[object_name]
+ return container_objects[object_name]
def get_object_cdn_url(self, obj):
- """
- >>> driver = DummyStorageDriver('key', 'secret')
- >>> container = driver.create_container(container_name='test container 1')
- >>> container
- <Container: name=test container 1, provider=Dummy Storage Provider>
- >>> obj = container.upload_object_via_stream(object_name='test object 5',
- ... iterator=DummyFileObject(5, 10), extra={})
- >>> obj
- <Object: name=test object 5, size=50, hash=None, provider=Dummy Storage Provider ...>
- >>> obj.get_cdn_url()
- 'http://www.test.com/object/test_object_5'
- """
-
- container_name = obj.container.name
- container_objects = self._containers[container_name]['objects']
- if obj.name not in container_objects:
- raise ObjectDoesNotExistError(object_name=obj.name, value=None,
- driver=self)
+ """
+ >>> driver = DummyStorageDriver('key', 'secret')
+ >>> container = driver.create_container(container_name='test container 1')
+ >>> container
+ <Container: name=test container 1, provider=Dummy Storage Provider>
+ >>> obj = container.upload_object_via_stream(object_name='test object 5',
+ ... iterator=DummyFileObject(5, 10), extra={})
+ >>> obj
+ <Object: name=test object 5, size=50, hash=None, provider=Dummy Storage Provider ...>
+ >>> obj.get_cdn_url()
+ 'http://www.test.com/object/test_object_5'
- return container_objects[obj.name].meta_data['cdn_url']
+ @inherits: L{StorageDriver.get_object_cdn_url}
+ """
+ container_name = obj.container.name
+ container_objects = self._containers[container_name]['objects']
+ if obj.name not in container_objects:
+ raise ObjectDoesNotExistError(object_name=obj.name, value=None,
+ driver=self)
+
+ return container_objects[obj.name].meta_data['cdn_url']
def create_container(self, container_name):
"""
@@ -254,21 +274,23 @@ class DummyStorageDriver(StorageDriver):
... container_name='test container 1') #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
ContainerAlreadyExistsError:
+
+ @inherits: L{StorageDriver.create_container}
"""
if container_name in self._containers:
raise ContainerAlreadyExistsError(container_name=container_name,
value=None, driver=self)
- extra = { 'object_count': 0 }
+ extra = {'object_count': 0}
container = Container(name=container_name, extra=extra, driver=self)
- self._containers[container_name] = { 'container': container,
- 'objects': {},
- 'cdn_url':
- 'http://www.test.com/container/%s' %
- (container_name.replace(' ', '_'))
- }
+ self._containers[container_name] = {'container': container,
+ 'objects': {},
+ 'cdn_url':
+ 'http://www.test.com/container/%s' %
+ (container_name.replace(' ', '_'))
+ }
return container
def delete_container(self, container):
@@ -294,6 +316,8 @@ class DummyStorageDriver(StorageDriver):
>>> driver.delete_container(container=container)#doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
ContainerIsNotEmptyError:
+
+ @inherits: L{StorageDriver.delete_container}
"""
container_name = container.name
@@ -310,12 +334,12 @@ class DummyStorageDriver(StorageDriver):
return True
def download_object(self, obj, destination_path, overwrite_existing=False,
- delete_on_failure=True):
- kwargs_dict = {'obj': obj,
- 'response': DummyFileObject(),
- 'destination_path': destination_path,
- 'overwrite_existing': overwrite_existing,
- 'delete_on_failure': delete_on_failure}
+ delete_on_failure=True):
+ kwargs_dict = {'obj': obj,
+ 'response': DummyFileObject(),
+ 'destination_path': destination_path,
+ 'overwrite_existing': overwrite_existing,
+ 'delete_on_failure': delete_on_failure}
return self._save_object(**kwargs_dict)
@@ -329,6 +353,8 @@ class DummyStorageDriver(StorageDriver):
>>> stream = container.download_object_as_stream(obj)
>>> stream #doctest: +ELLIPSIS
<...closed...>
+
+ @inherits: L{StorageDriver.download_object_as_stream}
"""
return DummyFileObject()
@@ -349,6 +375,10 @@ class DummyStorageDriver(StorageDriver):
<Object: name=test, size=...>
>>> obj.size == file_size
True
+
+ @inherits: L{StorageDriver.upload_object}
+ @param file_hash: File hash
+ @type file_hash: C{str}
"""
if not os.path.exists(file_path):
@@ -369,6 +399,8 @@ class DummyStorageDriver(StorageDriver):
... object_name='test object', iterator=DummyFileObject(5, 10), extra={})
>>> obj #doctest: +ELLIPSIS
<Object: name=test object, size=50, ...>
+
+ @inherits: L{StorageDriver.upload_object_via_stream}
"""
size = len(iterator)
@@ -392,6 +424,8 @@ class DummyStorageDriver(StorageDriver):
>>> container.delete_object(obj=obj) #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
ObjectDoesNotExistError:
+
+ @inherits: L{StorageDriver.delete_object}
"""
container_name = obj.container.name
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/google_storage.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/google_storage.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/google_storage.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/google_storage.py Sun Nov 18 01:22:54 2012
@@ -128,6 +128,7 @@ class GoogleStorageConnection(Connection
class GoogleStorageDriver(S3StorageDriver):
name = 'Google Storage'
+ website = 'http://cloud.google.com/'
connectionCls = GoogleStorageConnection
hash_type = 'md5'
namespace = NAMESPACE
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/nimbus.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/nimbus.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/nimbus.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/nimbus.py Sun Nov 18 01:22:54 2012
@@ -80,6 +80,7 @@ class NimbusConnection(ConnectionUserAnd
class NimbusStorageDriver(StorageDriver):
name = 'Nimbus'
+ website = 'http://www.nimbusproject.org/'
connectionCls = NimbusConnection
def __init__(self, *args, **kwargs):
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/ninefold.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/ninefold.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/ninefold.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/ninefold.py Sun Nov 18 01:22:54 2012
@@ -16,9 +16,11 @@
from libcloud.storage.providers import Provider
from libcloud.storage.drivers.atmos import AtmosDriver
+
class NinefoldStorageDriver(AtmosDriver):
host = 'api.ninefold.com'
path = '/storage/v1.0'
type = Provider.NINEFOLD
name = 'Ninefold'
+ website = 'http://ninefold.com/'
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/s3.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/s3.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/s3.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/s3.py Sun Nov 18 01:22:54 2012
@@ -56,15 +56,15 @@ NAMESPACE = 'http://s3.amazonaws.com/doc
class S3Response(AWSBaseResponse):
- valid_response_codes = [ httplib.NOT_FOUND, httplib.CONFLICT,
- httplib.BAD_REQUEST ]
+ valid_response_codes = [httplib.NOT_FOUND, httplib.CONFLICT,
+ httplib.BAD_REQUEST]
def success(self):
i = int(self.status)
return i >= 200 and i <= 299 or i in self.valid_response_codes
def parse_error(self):
- if self.status in [ httplib.UNAUTHORIZED, httplib.FORBIDDEN ]:
+ if self.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
raise InvalidCredsError(self.body)
elif self.status == httplib.MOVED_PERMANENTLY:
raise LibcloudError('This bucket is located in a different ' +
@@ -73,9 +73,11 @@ class S3Response(AWSBaseResponse):
raise LibcloudError('Unknown error. Status code: %d' % (self.status),
driver=S3StorageDriver)
+
class S3RawResponse(S3Response, RawResponse):
pass
+
class S3Connection(ConnectionUserAndKey):
"""
Repersents a single connection to the EC2 Endpoint
@@ -92,18 +94,16 @@ class S3Connection(ConnectionUserAndKey)
return params
def pre_connect_hook(self, params, headers):
- params['Signature'] = self._get_aws_auth_param(method=self.method,
- headers=headers,
- params=params,
- expires=params['Expires'],
- secret_key=self.key,
- path=self.action)
+ params['Signature'] = self._get_aws_auth_param(
+ method=self.method, headers=headers, params=params,
+ expires=params['Expires'], secret_key=self.key, path=self.action)
return params, headers
def _get_aws_auth_param(self, method, headers, params, expires,
secret_key, path='/'):
"""
- Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) ) );
+ Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID,
+ UTF-8-Encoding-Of( StringToSign ) ) ) );
StringToSign = HTTP-VERB + "\n" +
Content-MD5 + "\n" +
@@ -112,8 +112,8 @@ class S3Connection(ConnectionUserAndKey)
CanonicalizedAmzHeaders +
CanonicalizedResource;
"""
- special_header_keys = [ 'content-md5', 'content-type', 'date' ]
- special_header_values = { 'date': '' }
+ special_header_keys = ['content-md5', 'content-type', 'date']
+ special_header_values = {'date': ''}
amz_header_values = {}
headers_copy = copy.deepcopy(headers)
@@ -136,7 +136,7 @@ class S3Connection(ConnectionUserAndKey)
keys_sorted = list(special_header_values.keys())
keys_sorted.sort()
- buf = [ method ]
+ buf = [method]
for key in keys_sorted:
value = special_header_values[key]
buf.append(value)
@@ -152,7 +152,7 @@ class S3Connection(ConnectionUserAndKey)
amz_header_string = '\n'.join(amz_header_string)
values_to_sign = []
- for value in [ string_to_sign, amz_header_string, path]:
+ for value in [string_to_sign, amz_header_string, path]:
if value:
values_to_sign.append(value)
@@ -162,8 +162,10 @@ class S3Connection(ConnectionUserAndKey)
)
return b64_hmac.decode('utf-8')
+
class S3StorageDriver(StorageDriver):
name = 'Amazon S3 (standard)'
+ website = 'http://aws.amazon.com/s3/'
connectionCls = S3Connection
hash_type = 'md5'
supports_chunked_encoding = False
@@ -181,7 +183,7 @@ class S3StorageDriver(StorageDriver):
driver=self)
def list_container_objects(self, container):
- value_dict = { 'container': container }
+ value_dict = {'container': container}
return LazyList(get_more=self._get_more, value_dict=value_dict)
def get_container(self, container_name):
@@ -189,7 +191,7 @@ class S3StorageDriver(StorageDriver):
containers = self.list_containers()
try:
- container = [ c for c in containers if c.name == container_name ][0]
+ container = [c for c in containers if c.name == container_name][0]
except IndexError:
raise ContainerDoesNotExistError(value=None, driver=self,
container_name=container_name)
@@ -197,9 +199,9 @@ class S3StorageDriver(StorageDriver):
return container
def get_object(self, container_name, object_name):
- # TODO: Figure out what is going on when the object or container does not exist
- # - it seems that Amazon just keeps the connection open and doesn't return a
- # response.
+ # TODO: Figure out what is going on when the object or container
+ # does not exist- it seems that Amazon just keeps the connection open
+ # and doesn't return a response.
container = self.get_container(container_name=container_name)
response = self.connection.request('/%s/%s' % (container_name,
object_name),
@@ -235,10 +237,10 @@ class S3StorageDriver(StorageDriver):
container = Container(name=container_name, extra=None, driver=self)
return container
elif response.status == httplib.CONFLICT:
- raise InvalidContainerNameError(value='Container with this name ' +
- 'already exists. The name must be unique among '
- 'all the containers in the system',
- container_name=container_name, driver=self)
+ raise InvalidContainerNameError(
+ value='Container with this name already exists. The name must '
+ 'be unique among all the containers in the system',
+ container_name=container_name, driver=self)
elif response.status == httplib.BAD_REQUEST:
raise InvalidContainerNameError(value='Container name contains ' +
'invalid characters.',
@@ -255,10 +257,9 @@ class S3StorageDriver(StorageDriver):
if response.status == httplib.NO_CONTENT:
return True
elif response.status == httplib.CONFLICT:
- raise ContainerIsNotEmptyError(value='Container must be empty' +
- ' before it can be deleted.',
- container_name=container.name,
- driver=self)
+ raise ContainerIsNotEmptyError(
+ value='Container must be empty before it can be deleted.',
+ container_name=container.name, driver=self)
elif response.status == httplib.NOT_FOUND:
raise ContainerDoesNotExistError(value=None,
driver=self,
@@ -278,11 +279,12 @@ class S3StorageDriver(StorageDriver):
return self._get_object(obj=obj, callback=self._save_object,
response=response,
- callback_kwargs={'obj': obj,
- 'response': response.response,
- 'destination_path': destination_path,
- 'overwrite_existing': overwrite_existing,
- 'delete_on_failure': delete_on_failure},
+ callback_kwargs={
+ 'obj': obj,
+ 'response': response.response,
+ 'destination_path': destination_path,
+ 'overwrite_existing': overwrite_existing,
+ 'delete_on_failure': delete_on_failure},
success_status_code=httplib.OK)
def download_object_as_stream(self, obj, chunk_size=None):
@@ -294,14 +296,20 @@ class S3StorageDriver(StorageDriver):
return self._get_object(obj=obj, callback=read_in_chunks,
response=response,
- callback_kwargs={ 'iterator': response.response,
- 'chunk_size': chunk_size},
+ callback_kwargs={'iterator': response.response,
+ 'chunk_size': chunk_size},
success_status_code=httplib.OK)
def upload_object(self, file_path, container, object_name, extra=None,
verify_hash=True, ex_storage_class=None):
+ """
+ @inherits: L{StorageDriver.upload_object}
+
+ @param ex_storage_class: Storage class
+ @type ex_storage_class: C{str}
+ """
upload_func = self._upload_file
- upload_func_kwargs = { 'file_path': file_path }
+ upload_func_kwargs = {'file_path': file_path}
return self._put_object(container=container, object_name=object_name,
upload_func=upload_func,
@@ -312,8 +320,14 @@ class S3StorageDriver(StorageDriver):
def upload_object_via_stream(self, iterator, container, object_name,
extra=None, ex_storage_class=None):
- # Amazon S3 does not support chunked transfer encoding so the whole data
- # is read into memory before uploading the object.
+ """
+ @inherits: L{StorageDriver.upload_object_via_stream}
+
+ @param ex_storage_class: Storage class
+ @type ex_storage_class: C{str}
+ """
+ #Amazon S3 does not support chunked transfer encoding so the whole data
+ #is read into memory before uploading the object.
upload_func = self._upload_data
upload_func_kwargs = {}
@@ -333,7 +347,7 @@ class S3StorageDriver(StorageDriver):
return True
elif response.status == httplib.NOT_FOUND:
raise ObjectDoesNotExistError(value=None, driver=self,
- object_name=obj.name)
+ object_name=obj.name)
return False
@@ -353,9 +367,9 @@ class S3StorageDriver(StorageDriver):
if response.status == httplib.OK:
objects = self._to_objs(obj=response.object,
- xpath='Contents', container=container)
- is_truncated = response.object.findtext(fixxpath(xpath='IsTruncated',
- namespace=self.namespace)).lower()
+ xpath='Contents', container=container)
+ is_truncated = response.object.findtext(fixxpath(
+ xpath='IsTruncated', namespace=self.namespace)).lower()
exhausted = (is_truncated == 'false')
if (len(objects) > 0):
@@ -374,7 +388,8 @@ class S3StorageDriver(StorageDriver):
extra = extra or {}
storage_class = storage_class or 'standard'
if storage_class not in ['standard', 'reduced_redundancy']:
- raise ValueError('Invalid storage class value: %s' % (storage_class))
+ raise ValueError(
+ 'Invalid storage class value: %s' % (storage_class))
headers['x-amz-storage-class'] = storage_class.upper()
@@ -391,16 +406,13 @@ class S3StorageDriver(StorageDriver):
request_path = '/%s/%s' % (container_name_cleaned, object_name_cleaned)
# TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
# here.
- # SIGPIPE is thrown if the provided container does not exist or the user
+ #SIGPIPE is thrown if the provided container does not exist or the user
# does not have correct permission
- result_dict = self._upload_object(object_name=object_name,
- content_type=content_type,
- upload_func=upload_func,
- upload_func_kwargs=upload_func_kwargs,
- request_path=request_path,
- request_method='PUT',
- headers=headers, file_path=file_path,
- iterator=iterator)
+ result_dict = self._upload_object(
+ object_name=object_name, content_type=content_type,
+ upload_func=upload_func, upload_func_kwargs=upload_func_kwargs,
+ request_path=request_path, request_method='PUT',
+ headers=headers, file_path=file_path, iterator=iterator)
response = result_dict['response']
bytes_transferred = result_dict['bytes_transferred']
@@ -420,16 +432,18 @@ class S3StorageDriver(StorageDriver):
return obj
else:
- raise LibcloudError('Unexpected status code, status_code=%s' % (response.status),
- driver=self)
+ raise LibcloudError(
+ 'Unexpected status code, status_code=%s' % (response.status),
+ driver=self)
def _to_containers(self, obj, xpath):
- return [ self._to_container(element) for element in \
- obj.findall(fixxpath(xpath=xpath, namespace=self.namespace))]
+ return [self._to_container(element) for element in
+ obj.findall(fixxpath(
+ xpath=xpath, namespace=self.namespace))]
def _to_objs(self, obj, xpath, container):
- return [ self._to_obj(element, container) for element in \
- obj.findall(fixxpath(xpath=xpath, namespace=self.namespace))]
+ return [self._to_obj(element, container) for element in
+ obj.findall(fixxpath(xpath=xpath, namespace=self.namespace))]
def _to_container(self, element):
extra = {
@@ -437,21 +451,31 @@ class S3StorageDriver(StorageDriver):
namespace=self.namespace)
}
- container = Container(
- name=findtext(element=element, xpath='Name',
- namespace=self.namespace),
- extra=extra,
- driver=self
- )
+ container = Container(name=findtext(element=element, xpath='Name',
+ namespace=self.namespace),
+ extra=extra,
+ driver=self
+ )
return container
def _headers_to_object(self, object_name, container, headers):
- meta_data = { 'content_type': headers['content-type'] }
hash = headers['etag'].replace('"', '')
+ extra = {'content_type': headers['content-type'], 'etag': headers['etag']}
+ meta_data = {}
+
+ if 'last-modified' in headers:
+ extra['last_modified'] = headers['last-modified']
+
+ for key, value in headers.items():
+ if not key.lower().startswith('x-amz-meta-'):
+ continue
+
+ key = key.replace('x-amz-meta-', '')
+ meta_data[key] = value
obj = Object(name=object_name, size=headers['content-length'],
- hash=hash, extra=None,
+ hash=hash, extra=extra,
meta_data=meta_data,
container=container,
driver=self)
@@ -463,8 +487,8 @@ class S3StorageDriver(StorageDriver):
owner_display_name = findtext(element=element,
xpath='Owner/DisplayName',
namespace=self.namespace)
- meta_data = { 'owner': { 'id': owner_id,
- 'display_name':owner_display_name }}
+ meta_data = {'owner': {'id': owner_id,
+ 'display_name': owner_display_name}}
obj = Object(name=findtext(element=element, xpath='Key',
namespace=self.namespace),
@@ -476,45 +500,55 @@ class S3StorageDriver(StorageDriver):
meta_data=meta_data,
container=container,
driver=self
- )
+ )
return obj
+
class S3USWestConnection(S3Connection):
host = S3_US_WEST_HOST
+
class S3USWestStorageDriver(S3StorageDriver):
name = 'Amazon S3 (us-west-1)'
connectionCls = S3USWestConnection
ex_location_name = 'us-west-1'
+
class S3USWestOregonConnection(S3Connection):
host = S3_US_WEST_OREGON_HOST
+
class S3USWestOregonStorageDriver(S3StorageDriver):
name = 'Amazon S3 (us-west-2)'
connectionCls = S3USWestOregonConnection
ex_location_name = 'us-west-2'
+
class S3EUWestConnection(S3Connection):
host = S3_EU_WEST_HOST
+
class S3EUWestStorageDriver(S3StorageDriver):
name = 'Amazon S3 (eu-west-1)'
connectionCls = S3EUWestConnection
ex_location_name = 'EU'
+
class S3APSEConnection(S3Connection):
host = S3_AP_SOUTHEAST_HOST
+
class S3APSEStorageDriver(S3StorageDriver):
name = 'Amazon S3 (ap-southeast-1)'
connectionCls = S3APSEConnection
ex_location_name = 'ap-southeast-1'
+
class S3APNEConnection(S3Connection):
host = S3_AP_NORTHEAST_HOST
+
class S3APNEStorageDriver(S3StorageDriver):
name = 'Amazon S3 (ap-northeast-1)'
connectionCls = S3APNEConnection
Modified: libcloud/branches/0.11.x/libcloud/storage/providers.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/providers.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/providers.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/providers.py Sun Nov 18 01:22:54 2012
@@ -46,5 +46,6 @@ DRIVERS = {
('libcloud.storage.drivers.nimbus', 'NimbusStorageDriver')
}
+
def get_driver(provider):
return get_provider_driver(DRIVERS, provider)
Modified: libcloud/branches/0.11.x/libcloud/storage/types.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/types.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/types.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/types.py Sun Nov 18 01:22:54 2012
@@ -25,6 +25,7 @@ __all__ = ['Provider',
'ObjectHashMismatchError',
'InvalidContainerNameError']
+
class Provider(object):
"""
Defines for each of the supported providers
@@ -56,6 +57,7 @@ class Provider(object):
CLOUDFILES_SWIFT = 11
NIMBUS = 12
+
class ContainerError(LibcloudError):
error_type = 'ContainerError'
@@ -68,6 +70,7 @@ class ContainerError(LibcloudError):
(self.error_type, repr(self.driver),
self.container_name, self.value))
+
class ObjectError(LibcloudError):
error_type = 'ContainerError'
@@ -79,23 +82,31 @@ class ObjectError(LibcloudError):
return self.__repr__()
def __repr__(self):
- return '<%s in %s, value=%s, object = %s>' % (self.error_type, repr(self.driver),
- self.value, self.object_name)
+ return '<%s in %s, value=%s, object = %s>' % (self.error_type,
+ repr(self.driver),
+ self.value,
+ self.object_name)
+
class ContainerAlreadyExistsError(ContainerError):
error_type = 'ContainerAlreadyExistsError'
+
class ContainerDoesNotExistError(ContainerError):
error_type = 'ContainerDoesNotExistError'
+
class ContainerIsNotEmptyError(ContainerError):
error_type = 'ContainerIsNotEmptyError'
+
class ObjectDoesNotExistError(ObjectError):
error_type = 'ObjectDoesNotExistError'
+
class ObjectHashMismatchError(ObjectError):
error_type = 'ObjectHashMismatchError'
+
class InvalidContainerNameError(ContainerError):
error_type = 'InvalidContainerNameError'
Modified: libcloud/branches/0.11.x/libcloud/test/compute/fixtures/openstack/_v2_0__auth.json
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/fixtures/openstack/_v2_0__auth.json?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/fixtures/openstack/_v2_0__auth.json (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/fixtures/openstack/_v2_0__auth.json Sun Nov 18 01:22:54 2012
@@ -71,6 +71,14 @@
"versionInfo": "https://dfw.servers.api.rackspacecloud.com/v2/",
"versionList": "https://dfw.servers.api.rackspacecloud.com/",
"versionId": "2"
+ },
+ {
+ "region": "ORD",
+ "tenantId": "613469",
+ "publicURL": "https://ord.servers.api.rackspacecloud.com/v2/1337",
+ "versionInfo": "https://ord.servers.api.rackspacecloud.com/v2/",
+ "versionList": "https://ord.servers.api.rackspacecloud.com/",
+ "versionId": "2"
}
],
"name": "cloudServersOpenStack",
Modified: libcloud/branches/0.11.x/libcloud/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0.xml
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0.xml?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0.xml (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0.xml Sun Nov 18 01:22:54 2012
@@ -1,4 +1,4 @@
-<Vdc status="1" name="MyOrg" id="urn:vcloud:vdc:3d9ae28c-1de9-4307-8107-9356ff8ba6d0" type="application/vnd.vmware.vcloud.vdc+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<Vdc status="1" name="MyVdc" id="urn:vcloud:vdc:3d9ae28c-1de9-4307-8107-9356ff8ba6d0" type="application/vnd.vmware.vcloud.vdc+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Link rel="up" type="application/vnd.vmware.vcloud.org+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
<Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0/metadata"/>
<Link rel="add" type="application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0/action/uploadVAppTemplate"/>
@@ -9,27 +9,27 @@
<Link rel="add" type="application/vnd.vmware.vcloud.cloneMediaParams+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0/action/cloneMedia"/>
<Link rel="add" type="application/vnd.vmware.vcloud.captureVAppParams+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0/action/captureVApp"/>
<Link rel="add" type="application/vnd.vmware.vcloud.composeVAppParams+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0/action/composeVApp"/>
- <AllocationModel>AllocationVApp</AllocationModel>
+ <AllocationModel>AllocationPool</AllocationModel>
<StorageCapacity>
<Units>MB</Units>
- <Allocated>0</Allocated>
- <Limit>0</Limit>
- <Used>126976</Used>
+ <Allocated>5120000</Allocated>
+ <Limit>5120000</Limit>
+ <Used>1984512</Used>
<Overhead>0</Overhead>
</StorageCapacity>
<ComputeCapacity>
<Cpu>
<Units>MHz</Units>
- <Allocated>0</Allocated>
- <Limit>0</Limit>
- <Used>6000</Used>
+ <Allocated>130000</Allocated>
+ <Limit>160000</Limit>
+ <Used>0</Used>
<Overhead>0</Overhead>
</Cpu>
<Memory>
<Units>MB</Units>
- <Allocated>0</Allocated>
- <Limit>0</Limit>
- <Used>4255</Used>
+ <Allocated>527360</Allocated>
+ <Limit>527360</Limit>
+ <Used>130752</Used>
<Overhead>0</Overhead>
</Memory>
</ComputeCapacity>
Modified: libcloud/branches/0.11.x/libcloud/test/compute/test_ec2.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/test_ec2.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/test_ec2.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/test_ec2.py Sun Nov 18 01:22:54 2012
@@ -139,6 +139,15 @@ class EC2Tests(LibcloudTestCase, TestCas
self.assertTrue(len(locations) > 0)
self.assertTrue(locations[0].availability_zone != None)
+ def test_list_security_groups(self):
+ groups = self.driver.ex_list_security_groups()
+ self.assertEqual(groups, ['WebServers', 'RangedPortsBySource'])
+
+ def test_authorize_security_group(self):
+ resp = self.driver.ex_authorize_security_group('TestGroup', '22', '22',
+ '0.0.0.0/0')
+ self.assertTrue(resp)
+
def test_reboot_node(self):
node = Node('i-4382922a', None, None, None, None, self.driver)
ret = self.driver.reboot_node(node)
@@ -212,6 +221,10 @@ class EC2Tests(LibcloudTestCase, TestCas
self.assertEqual(availability_zone.zone_state, 'available')
self.assertEqual(availability_zone.region_name, 'eu-west-1')
+ def test_ex_describe_all_keypairs(self):
+ keys = self.driver.ex_describe_all_keypairs()
+ self.assertEqual(keys, ['gsg-keypair'])
+
def test_ex_describe_tags(self):
node = Node('i-4382922a', None, None, None, None, self.driver)
tags = self.driver.ex_describe_tags(resource=node)
@@ -358,6 +371,14 @@ class EC2MockHttp(MockHttp):
body = self.fixtures.load('stop_instances.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _DescribeSecurityGroups(self, method, url, body, headers):
+ body = self.fixtures.load('describe_security_groups.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _AuthorizeSecurityGroupIngress(self, method, url, body, headers):
+ body = self.fixtures.load('authorize_security_group_ingress.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _DescribeImages(self, method, url, body, headers):
body = self.fixtures.load('describe_images.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
@@ -378,6 +399,10 @@ class EC2MockHttp(MockHttp):
body = self.fixtures.load('terminate_instances.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _DescribeKeyPairs(self, method, url, body, headers):
+ body = self.fixtures.load('describe_key_pairs.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _DescribeTags(self, method, url, body, headers):
body = self.fixtures.load('describe_tags.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
Modified: libcloud/branches/0.11.x/libcloud/test/compute/test_ibm_sce.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/test_ibm_sce.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/test_ibm_sce.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/test_ibm_sce.py Sun Nov 18 01:22:54 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':
Modified: libcloud/branches/0.11.x/libcloud/test/compute/test_openstack.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/test_openstack.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/test_openstack.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/test_openstack.py Sun Nov 18 01:22:54 2012
@@ -656,8 +656,6 @@ class OpenStack_1_1_Tests(unittest.TestC
for size in sizes:
self.assertTrue(isinstance(size.price, float),
'Wrong size price type')
- self.assertEqual(size.price, 0,
- 'Size price should be zero by default')
def test_list_sizes_with_specified_pricing(self):
Modified: libcloud/branches/0.11.x/libcloud/test/compute/test_rackspacenova.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/test_rackspacenova.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/test_rackspacenova.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/test_rackspacenova.py Sun Nov 18 01:22:54 2012
@@ -19,6 +19,7 @@ from libcloud.utils.py3 import method_ty
from libcloud.utils.py3 import httplib
from libcloud.compute.drivers.rackspacenova import RackspaceNovaBetaNodeDriver, \
RackspaceNovaDfwNodeDriver, \
+ RackspaceNovaOrdNodeDriver, \
RackspaceNovaLonNodeDriver
from libcloud.test.compute.test_openstack import OpenStack_1_1_Tests, OpenStack_1_1_MockHttp
from libcloud.pricing import clear_pricing_data
@@ -48,13 +49,6 @@ class RackspaceNovaLonMockHttp(Rackspace
return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
-class RackspaceNovaLonMockHttp(RackspaceNovaMockHttp):
-
- def _v2_0_tokens(self, method, url, body, headers):
- body = self.auth_fixtures.load('_v2_0__auth_lon.json')
- return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
-
-
class RackspaceNovaBetaTests(OpenStack_1_1_Tests):
driver_klass = RackspaceNovaBetaNodeDriver
@@ -103,10 +97,10 @@ class RackspaceNovaDfwTests(OpenStack_1_
self.assertEqual('https://dfw.servers.api.rackspacecloud.com/v2/1337', self.driver.connection.get_endpoint())
-class RackspaceNovaLonTests(OpenStack_1_1_Tests):
+class RackspaceNovaOrdTests(OpenStack_1_1_Tests):
- driver_klass = RackspaceNovaLonNodeDriver
- driver_type = RackspaceNovaLonNodeDriver
+ driver_klass = RackspaceNovaOrdNodeDriver
+ driver_type = RackspaceNovaOrdNodeDriver
driver_args = RACKSPACE_NOVA_PARAMS + ('1.1',)
driver_kwargs = {'ex_force_auth_version': '2.0'}
@@ -115,8 +109,8 @@ class RackspaceNovaLonTests(OpenStack_1_
return self.driver_type(*self.driver_args, **self.driver_kwargs)
def setUp(self):
- self.driver_klass.connectionCls.conn_classes = (RackspaceNovaLonMockHttp, RackspaceNovaLonMockHttp)
- self.driver_klass.connectionCls.auth_url = "https://lon.auth.api.example.com/v2.0/"
+ self.driver_klass.connectionCls.conn_classes = (RackspaceNovaMockHttp, RackspaceNovaMockHttp)
+ self.driver_klass.connectionCls.auth_url = "https://auth.api.example.com/v2.0/"
self.driver = self.create_driver()
# normally authentication happens lazily, but we force it here
self.driver.connection._populate_hosts_and_request_paths()
@@ -124,7 +118,7 @@ class RackspaceNovaLonTests(OpenStack_1_
self.node = self.driver.list_nodes()[1]
def test_service_catalog(self):
- self.assertEqual('https://lon.servers.api.rackspacecloud.com/v2/1337', self.driver.connection.get_endpoint())
+ self.assertEqual('https://ord.servers.api.rackspacecloud.com/v2/1337', self.driver.connection.get_endpoint())
class RackspaceNovaLonTests(OpenStack_1_1_Tests):
Modified: libcloud/branches/0.11.x/libcloud/test/compute/test_vcloud.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/compute/test_vcloud.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/compute/test_vcloud.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/compute/test_vcloud.py Sun Nov 18 01:22:54 2012
@@ -132,7 +132,8 @@ class VCloud_1_5_Tests(unittest.TestCase
self.assertEqual(node.state, NodeState.RUNNING)
self.assertEqual(node.public_ips, ['65.41.67.2'])
self.assertEqual(node.private_ips, ['65.41.67.2'])
- self.assertEqual(node.extra, {'vms': [{
+ self.assertEqual(node.extra, {'vdc': 'MyVdc',
+ 'vms': [{
'id': 'https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045',
'name': 'testVm',
'state': NodeState.RUNNING,
@@ -145,7 +146,8 @@ class VCloud_1_5_Tests(unittest.TestCase
self.assertEqual(node.state, NodeState.RUNNING)
self.assertEqual(node.public_ips, ['192.168.0.103'])
self.assertEqual(node.private_ips, ['192.168.0.100'])
- self.assertEqual(node.extra, {'vms': [{
+ self.assertEqual(node.extra, {'vdc': 'MyVdc',
+ 'vms': [{
'id': 'https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e046',
'name': 'testVm2',
'state': NodeState.RUNNING,
@@ -218,6 +220,30 @@ class VCloud_1_5_Tests(unittest.TestCase
def test_ex_set_vm_memory(self):
self.driver.ex_set_vm_memory('https://test/api/vApp/vm-test', 1024)
+ def test_vdcs(self):
+ vdcs = self.driver.vdcs
+ self.assertEqual(len(vdcs), 1)
+ self.assertEqual(vdcs[0].id, 'https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0')
+ self.assertEqual(vdcs[0].name, 'MyVdc')
+ self.assertEqual(vdcs[0].allocation_model, 'AllocationPool')
+ self.assertEqual(vdcs[0].storage.limit, 5120000)
+ self.assertEqual(vdcs[0].storage.used, 1984512)
+ self.assertEqual(vdcs[0].storage.units, 'MB')
+ self.assertEqual(vdcs[0].cpu.limit, 160000)
+ self.assertEqual(vdcs[0].cpu.used, 0)
+ self.assertEqual(vdcs[0].cpu.units, 'MHz')
+ self.assertEqual(vdcs[0].memory.limit, 527360)
+ self.assertEqual(vdcs[0].memory.used, 130752)
+ self.assertEqual(vdcs[0].memory.units, 'MB')
+
+ def test_ex_list_nodes(self):
+ self.assertEqual(len(self.driver.ex_list_nodes()), len(self.driver.list_nodes()))
+
+ def test_ex_power_off(self):
+ node = Node('https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6b', 'testNode', NodeState.RUNNING, [], [], self.driver)
+ self.driver.ex_power_off_node(node)
+
+
class TerremarkMockHttp(MockHttp):
@@ -316,8 +342,7 @@ class VCloud_1_5_MockHttp(MockHttp):
return httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED]
def _api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_powerOn(self, method, url, body, headers):
- body = self.fixtures.load('api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_powerOn.xml')
- return httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED]
+ return self._api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6b_power_action_all(method, url, body, headers)
# Clone
def _api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0_action_cloneVApp(self, method, url, body, headers):
@@ -356,8 +381,7 @@ class VCloud_1_5_MockHttp(MockHttp):
return status, body, headers, httplib.responses[status]
def _api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_reset(self, method, url, body, headers):
- body = self.fixtures.load('api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_reset.xml')
- return httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED]
+ return self._api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6b_power_action_all(method, url, body, headers)
def _api_task_b034df55_fe81_4798_bc81_1f0fd0ead450(self, method, url, body, headers):
body = self.fixtures.load('api_task_b034df55_fe81_4798_bc81_1f0fd0ead450.xml')
@@ -432,5 +456,13 @@ class VCloud_1_5_MockHttp(MockHttp):
status = httplib.ACCEPTED
return status, body, headers, httplib.responses[status]
+ def _api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6b_power_action_powerOff(self, method, url, body, headers):
+ return self._api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6b_power_action_all(method, url, body, headers)
+
+ def _api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6b_power_action_all(self, method, url, body, headers):
+ assert method == 'POST'
+ body = self.fixtures.load('api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_all.xml')
+ return httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED]
+
if __name__ == '__main__':
sys.exit(unittest.main())
Modified: libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_brightbox.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_brightbox.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_brightbox.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_brightbox.py Sun Nov 18 01:22:54 2012
@@ -74,6 +74,7 @@ class BrightboxLBTests(unittest.TestCase
members = balancer.list_members()
self.assertEquals(len(members), 1)
+ self.assertEquals(members[0].balancer, balancer)
self.assertEquals('srv-lv426', members[0].id)
def test_balancer_attach_member(self):
Modified: libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_cloudstack.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_cloudstack.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_cloudstack.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_cloudstack.py Sun Nov 18 01:22:54 2012
@@ -68,6 +68,7 @@ class CloudStackLBTests(unittest.TestCas
members = balancer.list_members()
for member in members:
self.assertTrue(isinstance(member, Member))
+ self.assertEquals(member.balancer, balancer)
class CloudStackMockHttp(MockHttpTestCase):
fixtures = LoadBalancerFileFixtures('cloudstack')
Modified: libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_gogrid.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_gogrid.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_gogrid.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_gogrid.py Sun Nov 18 01:22:54 2012
@@ -115,6 +115,7 @@ class GoGridTests(unittest.TestCase):
self.assertEquals(len(members2), 3)
self.assertEquals(expected_members,
set(["%s:%s" % (member.ip, member.port) for member in members1]))
+ self.assertEquals(members1[0].balancer, balancer)
def test_balancer_attach_compute_node(self):
balancer = LoadBalancer(23530, None, None, None, None, self.driver)
Modified: libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_rackspace.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_rackspace.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_rackspace.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/loadbalancer/test_rackspace.py Sun Nov 18 01:22:54 2012
@@ -667,6 +667,7 @@ class RackspaceLBTests(unittest.TestCase
members = balancer.list_members()
self.assertEquals(len(members), 3)
+ self.assertEquals(members[0].balancer, balancer)
self.assertEquals(expected, set(["%s:%s" % (member.ip, member.port) for
member in members]))
Modified: libcloud/branches/0.11.x/libcloud/test/storage/test_cloudfiles.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/storage/test_cloudfiles.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/storage/test_cloudfiles.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/storage/test_cloudfiles.py Sun Nov 18 01:22:54 2012
@@ -12,6 +12,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from hashlib import sha1
+import hmac
import os
import os.path # pylint: disable-msg=W0404
import math
@@ -493,6 +495,7 @@ class CloudFilesTests(unittest.TestCase)
self.assertTrue('object_count' in meta_data)
self.assertTrue('container_count' in meta_data)
self.assertTrue('bytes_used' in meta_data)
+ self.assertTrue('temp_url_key' in meta_data)
@mock.patch('os.path.getsize')
def test_ex_multipart_upload_object_for_small_files(self, getsize_mock):
@@ -615,6 +618,42 @@ class CloudFilesTests(unittest.TestCase)
file_name='error.html')
self.assertTrue(result)
+ def test_ex_set_account_metadata_temp_url_key(self):
+ result = self.driver.ex_set_account_metadata_temp_url_key("a key")
+ self.assertTrue(result)
+
+ @mock.patch("libcloud.storage.drivers.cloudfiles.time")
+ def test_ex_get_object_temp_url(self, time):
+ time.return_value = 0
+ self.driver.ex_get_meta_data = mock.Mock()
+ self.driver.ex_get_meta_data.return_value = {'container_count': 1,
+ 'object_count': 1,
+ 'bytes_used': 1,
+ 'temp_url_key': 'foo'}
+ container = Container(name='foo_bar_container', extra={}, driver=self)
+ obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+ container=container, meta_data=None,
+ driver=self)
+ hmac_body = "%s\n%s\n%s" % ('GET', 60,
+ "/v1/MossoCloudFS/foo_bar_container/foo_bar_object")
+ sig = hmac.new(b('foo'), b(hmac_body), sha1).hexdigest()
+ ret = self.driver.ex_get_object_temp_url(obj, 'GET')
+ temp_url = 'https://storage101.ord1.clouddrive.com/v1/MossoCloudFS/foo_bar_container/foo_bar_object?temp_url_expires=60&temp_url_sig=%s' % (sig)
+
+ self.assertEquals(ret, temp_url)
+
+ def test_ex_get_object_temp_url_no_key_raises_key_error(self):
+ self.driver.ex_get_meta_data = mock.Mock()
+ self.driver.ex_get_meta_data.return_value = {'container_count': 1,
+ 'object_count': 1,
+ 'bytes_used': 1,
+ 'temp_url_key': None}
+ container = Container(name='foo_bar_container', extra={}, driver=self)
+ obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+ container=container, meta_data=None,
+ driver=self)
+ self.assertRaises(KeyError, self.driver.ex_get_object_temp_url, obj, 'GET')
+
def _remove_test_file(self):
file_path = os.path.abspath(__file__) + '.temp'
@@ -674,6 +713,9 @@ class CloudFilesMockHttp(StorageMockHttp
'x-account-object-count': 400,
'x-account-bytes-used': 1234567
})
+ elif method == 'POST':
+ body = ''
+ status_code = httplib.NO_CONTENT
return (status_code, body, headers, httplib.responses[httplib.OK])
def _v1_MossoCloudFS_not_found(self, method, url, body, headers):
Modified: libcloud/branches/0.11.x/libcloud/test/storage/test_s3.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/storage/test_s3.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/storage/test_s3.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/storage/test_s3.py Sun Nov 18 01:22:54 2012
@@ -101,7 +101,9 @@ class S3MockHttp(StorageMockHttp):
body = self.fixtures.load('list_containers.xml')
headers = {'content-type': 'application/zip',
'etag': '"e31208wqsdoj329jd"',
+ 'x-amz-meta-rabbits': 'monkeys',
'content-length': 12345,
+ 'last-modified': 'Thu, 13 Sep 2012 07:13:22 GMT'
}
return (httplib.OK,
@@ -375,6 +377,9 @@ class S3Tests(unittest.TestCase):
self.assertEqual(obj.container.name, 'test2')
self.assertEqual(obj.size, 12345)
self.assertEqual(obj.hash, 'e31208wqsdoj329jd')
+ self.assertEqual(obj.extra['last_modified'], 'Thu, 13 Sep 2012 07:13:22 GMT')
+ self.assertEqual(obj.extra['content_type'], 'application/zip')
+ self.assertEqual(obj.meta_data['rabbits'], 'monkeys')
def test_create_container_invalid_name(self):
# invalid container name
Modified: libcloud/branches/0.11.x/libcloud/test/test_httplib_ssl.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/test/test_httplib_ssl.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/test/test_httplib_ssl.py (original)
+++ libcloud/branches/0.11.x/libcloud/test/test_httplib_ssl.py Sun Nov 18 01:22:54 2012
@@ -53,6 +53,14 @@ class TestHttpLibSSLTests(unittest.TestC
(('organizationalUnitName', 'SSL'),),
(('commonName', 'python.org'),))}
+ cert4 = {'notAfter': 'Feb 16 16:54:50 2013 GMT',
+ 'subject': ((('countryName', 'US'),),
+ (('stateOrProvinceName', 'Delaware'),),
+ (('localityName', 'Wilmington'),),
+ (('organizationName', 'Python Software Foundation'),),
+ (('organizationalUnitName', 'SSL'),),
+ (('commonName', '*.api.joyentcloud.com'),))}
+
self.assertFalse(self.httplib_object._verify_hostname(
hostname='invalid', cert=cert1))
self.assertFalse(self.httplib_object._verify_hostname(
@@ -88,6 +96,11 @@ class TestHttpLibSSLTests(unittest.TestC
self.assertFalse(self.httplib_object._verify_hostname(
hostname='ython.org', cert=cert3))
+ self.assertTrue(self.httplib_object._verify_hostname(
+ hostname='us-east-1.api.joyentcloud.com', cert=cert4))
+ self.assertTrue(self.httplib_object._verify_hostname(
+ hostname='useast-1.api.joyentcloud.com', cert=cert4))
+
def test_get_subject_alt_names(self):
cert1 = {'notAfter': 'Feb 16 16:54:50 2013 GMT',
'subject': ((('countryName', 'US'),),