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 [3/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/loadbalancer/drivers/rackspace.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/loadbalancer/drivers/rackspace.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/loadbalancer/drivers/rackspace.py (original)
+++ libcloud/branches/0.11.x/libcloud/loadbalancer/drivers/rackspace.py Sun Nov 18 01:22:54 2012
@@ -27,13 +27,12 @@ from libcloud.loadbalancer.base import D
from libcloud.common.types import LibcloudError
from libcloud.common.base import JsonResponse, PollingConnection
from libcloud.loadbalancer.types import State, MemberCondition
-from libcloud.common.openstack import OpenStackBaseConnection, OpenStackDriverMixin
-from libcloud.common.rackspace import (
- AUTH_URL_US, AUTH_URL_UK)
+from libcloud.common.openstack import OpenStackBaseConnection,\
+ OpenStackDriverMixin
+from libcloud.common.rackspace import (AUTH_URL_US, AUTH_URL_UK)
class RackspaceResponse(JsonResponse):
-
def parse_body(self):
if not self.body:
return None
@@ -51,7 +50,7 @@ class RackspaceHealthMonitor(object):
@type type: C{str}
@param delay: minimum seconds to wait before executing the health
- monitor. (Must be between 1 and 3600)
+ monitor. (Must be between 1 and 3600)
@type delay: C{int}
@param timeout: maximum seconds to wait when establishing a
@@ -105,8 +104,8 @@ class RackspaceHTTPHealthMonitor(Rackspa
def __init__(self, type, delay, timeout, attempts_before_deactivation,
path, body_regex, status_regex):
- super(RackspaceHTTPHealthMonitor, self).__init__(type, delay, timeout,
- attempts_before_deactivation)
+ super(RackspaceHTTPHealthMonitor, self).__init__(
+ type, delay, timeout, attempts_before_deactivation)
self.path = path
self.body_regex = body_regex
self.status_regex = status_regex
@@ -209,7 +208,7 @@ class RackspaceAccessRule(object):
self.address = address
def _to_dict(self):
- type_string = \
+ type_string =\
RackspaceAccessRuleType._RULE_TYPE_STRING_MAP[self.rule_type]
as_dict = {
@@ -249,8 +248,9 @@ class RackspaceConnection(OpenStackBaseC
if method == 'GET':
self._add_cache_busting_to_params(params)
- return super(RackspaceConnection, self).request(action=action,
- params=params, data=data, method=method, headers=headers)
+ return super(RackspaceConnection, self).request(
+ action=action, params=params,
+ data=data, method=method, headers=headers)
def get_poll_request_kwargs(self, response, context, request_kwargs):
return {'action': request_kwargs['action'],
@@ -274,16 +274,18 @@ class RackspaceConnection(OpenStackBaseC
if self._auth_version == "1.1":
ep = self.service_catalog.get_endpoint(name="cloudServers")
- return self._construct_loadbalancer_endpoint_from_servers_endpoint(ep)
+ return self._construct_loadbalancer_endpoint_from_servers_endpoint(
+ ep)
elif "2.0" in self._auth_version:
ep = self.service_catalog.get_endpoint(name="cloudServers",
- service_type="compute",
- region=None)
+ service_type="compute",
+ region=None)
- return self._construct_loadbalancer_endpoint_from_servers_endpoint(ep)
+ return self._construct_loadbalancer_endpoint_from_servers_endpoint(
+ ep)
else:
- raise LibcloudError("Auth version %s not supported" % \
- self._auth_version)
+ raise LibcloudError(
+ "Auth version %s not supported" % self._auth_version)
def _construct_loadbalancer_endpoint_from_servers_endpoint(self, ep):
if 'publicURL' in ep:
@@ -301,6 +303,7 @@ class RackspaceLBDriver(Driver, OpenStac
connectionCls = RackspaceConnection
api_name = 'rackspace_lb'
name = 'Rackspace LB'
+ website = 'http://www.rackspace.com/'
LB_STATE_MAP = {
'ACTIVE': State.RUNNING,
@@ -343,19 +346,22 @@ class RackspaceLBDriver(Driver, OpenStac
def list_protocols(self):
return self._to_protocols(
- self.connection.request('/loadbalancers/protocols').object)
+ self.connection.request('/loadbalancers/protocols').object)
def ex_list_protocols_with_default_ports(self):
"""
- @rtype: C{list} of tuples of protocols (C{str}) with default ports
- (C{int}).
+ List protocols with default ports.
+
+ @rtype: C{list} of C{tuple}
@return: A list of protocols with default ports included.
"""
return self._to_protocols_with_default_ports(
- self.connection.request('/loadbalancers/protocols').object)
+ self.connection.request('/loadbalancers/protocols').object)
def list_balancers(self, ex_member_address=None):
"""
+ @inherits: L{Driver.list_balancers}
+
@param ex_member_address: Optional IP address of the attachment member.
If provided, only the load balancers which
have this member attached will be returned.
@@ -367,8 +373,7 @@ class RackspaceLBDriver(Driver, OpenStac
params['nodeaddress'] = ex_member_address
return self._to_balancers(
- self.connection.request('/loadbalancers', params=params)
- .object)
+ self.connection.request('/loadbalancers', params=params).object)
def create_balancer(self, name, members, protocol='http',
port=80, algorithm=DEFAULT_ALGORITHM):
@@ -380,25 +385,27 @@ class RackspaceLBDriver(Driver, OpenStac
"""
Creates a new load balancer instance
- @keyword name: Name of the new load balancer (required)
- @type name: C{str}
+ @param name: Name of the new load balancer (required)
+ @type name: C{str}
- @keyword members: C{list} ofL{Member}s to attach to balancer
- @type: C{list} of L{Member}s
+ @param members: C{list} ofL{Member}s to attach to balancer
+ @type members: C{list} of L{Member}
- @keyword protocol: Loadbalancer protocol, defaults to http.
- @type: C{str}
+ @param protocol: Loadbalancer protocol, defaults to http.
+ @type protocol: C{str}
- @keyword port: Port the load balancer should listen on, defaults to 80
- @type port: C{str}
+ @param port: Port the load balancer should listen on, defaults to 80
+ @type port: C{str}
- @keyword algorithm: Load balancing algorithm, defaults to
+ @param algorithm: Load balancing algorithm, defaults to
LBAlgorithm.ROUND_ROBIN
- @type algorithm: C{LBAlgorithm}
+ @type algorithm: L{Algorithm}
- @keyword vip: Virtual ip type of PUBLIC, SERVICENET, or ID of a virtual
+ @param vip: Virtual ip type of PUBLIC, SERVICENET, or ID of a virtual
ip
- @type vip: C{str}
+ @type vip: C{str}
+
+ @rtype: L{LoadBalancer}
"""
balancer_attrs = self._kwargs_to_mutable_attrs(
name=name,
@@ -409,7 +416,7 @@ class RackspaceLBDriver(Driver, OpenStac
balancer_attrs.update({
'nodes': [self._member_attributes(member) for member in members],
- })
+ })
balancer_object = {"loadBalancer": balancer_attrs}
resp = self.connection.request('/loadbalancers',
@@ -427,8 +434,8 @@ class RackspaceLBDriver(Driver, OpenStac
# If the condition is not specified on the member, then it should be
# set to ENABLED by default
if 'condition' not in member_attributes:
- member_attributes['condition'] = \
- self.CONDITION_LB_MEMBER_MAP[MemberCondition.ENABLED]
+ member_attributes['condition'] =\
+ self.CONDITION_LB_MEMBER_MAP[MemberCondition.ENABLED]
return member_attributes
@@ -443,15 +450,15 @@ class RackspaceLBDriver(Driver, OpenStac
Destroys a list of Balancers (the API supports up to 10).
@param balancers: A list of Balancers to destroy.
- @type balancers: C{list}
+ @type balancers: C{list} of L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the destroy request was accepted.
+ @rtype: C{bool}
"""
ids = [('id', balancer.id) for balancer in balancers]
resp = self.connection.request('/loadbalancers',
- method='DELETE',
- params=ids)
+ method='DELETE',
+ params=ids)
return resp.status == httplib.ACCEPTED
@@ -466,26 +473,28 @@ class RackspaceLBDriver(Driver, OpenStac
uri = '/loadbalancers/%s/nodes' % (balancer.id)
resp = self.connection.request(uri, method='POST',
- data=json.dumps(member_object))
- return self._to_members(resp.object)[0]
+ data=json.dumps(member_object))
+ return self._to_members(resp.object, balancer)[0]
def ex_balancer_attach_members(self, balancer, members):
"""
Attaches a list of members to a load balancer.
@param balancer: The Balancer to which members will be attached.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param members: A list of Members to attach.
- @type members: C{list}
+ @type members: C{list} of L{Member}
+
+ @rtype: C{list} of L{Member}
"""
member_objects = {"nodes": [self._member_attributes(member) for member
in members]}
uri = '/loadbalancers/%s/nodes' % (balancer.id)
resp = self.connection.request(uri, method='POST',
- data=json.dumps(member_objects))
- return self._to_members(resp.object)
+ data=json.dumps(member_objects))
+ return self._to_members(resp.object, balancer)
def balancer_detach_member(self, balancer, member):
# Loadbalancer always needs to have at least 1 member.
@@ -503,13 +512,13 @@ class RackspaceLBDriver(Driver, OpenStac
balancer is in a RUNNING state again.
@param balancer: The Balancer to detach members from.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param members: A list of Members to detach.
- @type members: C{list}
+ @type members: C{list} of L{Member}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
accepted = self.ex_balancer_detach_members_no_poll(balancer, members)
@@ -525,13 +534,13 @@ class RackspaceLBDriver(Driver, OpenStac
This method returns immediately.
@param balancer: The Balancer to detach members from.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param members: A list of Members to detach.
- @type members: C{list}
+ @type members: C{list} of L{Member}
- @rtype: C{bool}
@return: Returns whether the detach request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/nodes' % (balancer.id)
ids = [('id', member.id) for member in members]
@@ -541,23 +550,28 @@ class RackspaceLBDriver(Driver, OpenStac
def balancer_list_members(self, balancer):
uri = '/loadbalancers/%s/nodes' % (balancer.id)
- return self._to_members(
- self.connection.request(uri).object)
+ data = self.connection.request(uri).object
+ return self._to_members(data, balancer)
def update_balancer(self, balancer, **kwargs):
attrs = self._kwargs_to_mutable_attrs(**kwargs)
resp = self.connection.async_request(
- action='/loadbalancers/%s' % balancer.id,
- method='PUT',
- data=json.dumps(attrs))
+ action='/loadbalancers/%s' % balancer.id,
+ method='PUT',
+ data=json.dumps(attrs))
return self._to_balancer(resp.object["loadBalancer"])
def ex_update_balancer_no_poll(self, balancer, **kwargs):
+ """
+ Update balancer no poll.
+
+ @inherits: L{Driver.update_balancer}
+ """
attrs = self._kwargs_to_mutable_attrs(**kwargs)
resp = self.connection.request(
- action='/loadbalancers/%s' % balancer.id,
- method='PUT',
- data=json.dumps(attrs))
+ action='/loadbalancers/%s' % balancer.id,
+ method='PUT',
+ data=json.dumps(attrs))
return resp.status == httplib.ACCEPTED
def ex_balancer_update_member(self, balancer, member, **kwargs):
@@ -568,17 +582,20 @@ class RackspaceLBDriver(Driver, OpenStac
again.
@param balancer: Balancer to update the member on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
+
+ @param member: Member which should be used
+ @type member: L{Member}
- @param **kwargs: New attributes. Should contain either 'weight'
+ @keyword **kwargs: New attributes. Should contain either 'weight'
or 'condition'. 'condition' can be set to 'ENABLED', 'DISABLED'.
or 'DRAINING'. 'weight' can be set to a positive integer between
1 and 100, with a higher weight indicating that the node will receive
more traffic (assuming the Balancer is using a weighted algorithm).
@type **kwargs: C{dict}
- @rtype: C{Member}
@return: Updated Member.
+ @rtype: L{Member}
"""
accepted = self.ex_balancer_update_member_no_poll(
balancer, member, **kwargs)
@@ -603,17 +620,20 @@ class RackspaceLBDriver(Driver, OpenStac
include 'weight' or 'condition'. This method returns immediately.
@param balancer: Balancer to update the member on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @param **kwargs: New attributes. Should contain either 'weight'
+ @param member: Member which should be used
+ @type member: L{Member}
+
+ @keyword **kwargs: New attributes. Should contain either 'weight'
or 'condition'. 'condition' can be set to 'ENABLED', 'DISABLED'.
or 'DRAINING'. 'weight' can be set to a positive integer between
1 and 100, with a higher weight indicating that the node will receive
more traffic (assuming the Balancer is using a weighted algorithm).
@type **kwargs: C{dict}
- @rtype: C{bool}
@return: Returns whether the update request was accepted.
+ @rtype: C{bool}
"""
resp = self.connection.request(
action='/loadbalancers/%s/nodes/%s' % (balancer.id, member.id),
@@ -627,17 +647,35 @@ class RackspaceLBDriver(Driver, OpenStac
"""
Lists algorithms supported by the API. Returned as strings because
this list may change in the future.
+
+ @rtype: C{list} of C{str}
"""
response = self.connection.request('/loadbalancers/algorithms')
return [a["name"].upper() for a in response.object["algorithms"]]
def ex_get_balancer_error_page(self, balancer):
+ """
+ List error page configured for the specified load balancer.
+
+ @param balancer: Balancer which should be used
+ @type balancer: L{LoadBalancer}
+
+ @rtype: C{str}
+ """
uri = '/loadbalancers/%s/errorpage' % (balancer.id)
resp = self.connection.request(uri)
return resp.object["errorpage"]["content"]
def ex_balancer_access_list(self, balancer):
+ """
+ List the access list.
+
+ @param balancer: Balancer which should be used
+ @type balancer: L{LoadBalancer}
+
+ @rtype: C{list} of L{RackspaceAccessRule}
+ """
uri = '/loadbalancers/%s/accesslist' % (balancer.id)
resp = self.connection.request(uri)
@@ -663,16 +701,16 @@ class RackspaceLBDriver(Driver, OpenStac
again.
@param balancer: Balancer to update.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param health_monitor: Health Monitor for the balancer.
- @type health_monitor: C{RackspaceHealthMonitor}
+ @type health_monitor: L{RackspaceHealthMonitor}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
- accepted = self.ex_update_balancer_health_monitor_no_poll(balancer,
- health_monitor)
+ accepted = self.ex_update_balancer_health_monitor_no_poll(
+ balancer, health_monitor)
if not accepted:
msg = 'Update health monitor request not accepted'
raise LibcloudError(msg, driver=self)
@@ -685,19 +723,18 @@ class RackspaceLBDriver(Driver, OpenStac
Sets a Balancer's health monitor. This method returns immediately.
@param balancer: Balancer to update health monitor on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param health_monitor: Health Monitor for the balancer.
- @type health_monitor: C{RackspaceHealthMonitor}
+ @type health_monitor: L{RackspaceHealthMonitor}
- @rtype: C{bool}
@return: Returns whether the update request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/healthmonitor' % (balancer.id)
- resp = self.connection.request(uri,
- method='PUT',
- data=json.dumps(health_monitor._to_dict()))
+ resp = self.connection.request(
+ uri, method='PUT', data=json.dumps(health_monitor._to_dict()))
return resp.status == httplib.ACCEPTED
@@ -708,10 +745,10 @@ class RackspaceLBDriver(Driver, OpenStac
state again.
@param balancer: Balancer to disable health monitor on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_disable_balancer_health_monitor_no_poll(balancer):
msg = 'Disable health monitor request not accepted'
@@ -725,15 +762,15 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to disable health monitor on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the disable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/healthmonitor' % (balancer.id)
resp = self.connection.request(uri,
- method='DELETE')
+ method='DELETE')
return resp.status == httplib.ACCEPTED
@@ -745,13 +782,13 @@ class RackspaceLBDriver(Driver, OpenStac
RUNNING state again.
@param balancer: Balancer to update connection throttle on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param connection_throttle: Connection Throttle for the balancer.
- @type connection_throttle: C{RackspaceConnectionThrottle}
+ @type connection_throttle: L{RackspaceConnectionThrottle}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
accepted = self.ex_update_balancer_connection_throttle_no_poll(
balancer, connection_throttle)
@@ -769,16 +806,17 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to update connection throttle on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param connection_throttle: Connection Throttle for the balancer.
- @type connection_throttle: C{RackspaceConnectionThrottle}
+ @type connection_throttle: L{RackspaceConnectionThrottle}
- @rtype: C{bool}
@return: Returns whether the update request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/connectionthrottle' % (balancer.id)
- resp = self.connection.request(uri, method='PUT',
+ resp = self.connection.request(
+ uri, method='PUT',
data=json.dumps(connection_throttle._to_dict()))
return resp.status == httplib.ACCEPTED
@@ -790,10 +828,10 @@ class RackspaceLBDriver(Driver, OpenStac
state again.
@param balancer: Balancer to disable connection throttle on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_disable_balancer_connection_throttle_no_poll(balancer):
msg = 'Disable connection throttle request not accepted'
@@ -807,10 +845,10 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to disable connection throttle on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the disable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/connectionthrottle' % (balancer.id)
resp = self.connection.request(uri, method='DELETE')
@@ -824,10 +862,10 @@ class RackspaceLBDriver(Driver, OpenStac
state again.
@param balancer: Balancer to enable connection logging on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_enable_balancer_connection_logging_no_poll(balancer):
msg = 'Enable connection logging request not accepted'
@@ -841,19 +879,17 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to enable connection logging on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the enable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/connectionlogging' % (balancer.id)
- resp = self.connection.request(uri, method='PUT',
- data=json.dumps({
- 'connectionLogging': {
- 'enabled': True
- }
- }))
+ resp = self.connection.request(
+ uri, method='PUT',
+ data=json.dumps({'connectionLogging': {'enabled': True}})
+ )
return resp.status == httplib.ACCEPTED
@@ -864,10 +900,10 @@ class RackspaceLBDriver(Driver, OpenStac
state again.
@param balancer: Balancer to disable connection logging on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_disable_balancer_connection_logging_no_poll(balancer):
msg = 'Disable connection logging request not accepted'
@@ -881,18 +917,16 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to disable connection logging on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the disable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/connectionlogging' % (balancer.id)
- resp = self.connection.request(uri, method='PUT',
- data=json.dumps({
- 'connectionLogging': {
- 'enabled': False
- }
- }))
+ resp = self.connection.request(
+ uri, method='PUT',
+ data=json.dumps({'connectionLogging': {'enabled': False}})
+ )
return resp.status == httplib.ACCEPTED
@@ -903,10 +937,10 @@ class RackspaceLBDriver(Driver, OpenStac
has been processed and the balancer is in a RUNNING state again.
@param balancer: Balancer to enable session persistence on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_enable_balancer_session_persistence_no_poll(balancer):
msg = 'Enable session persistence request not accepted'
@@ -920,18 +954,17 @@ class RackspaceLBDriver(Driver, OpenStac
type to 'HTTP_COOKIE'. This method returns immediately.
@param balancer: Balancer to enable session persistence on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the enable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/sessionpersistence' % (balancer.id)
- resp = self.connection.request(uri, method='PUT',
- data=json.dumps({
- 'sessionPersistence': {
- 'persistenceType': 'HTTP_COOKIE'
- }
- }))
+ resp = self.connection.request(
+ uri, method='PUT',
+ data=json.dumps(
+ {'sessionPersistence': {'persistenceType': 'HTTP_COOKIE'}})
+ )
return resp.status == httplib.ACCEPTED
@@ -942,10 +975,10 @@ class RackspaceLBDriver(Driver, OpenStac
state again.
@param balancer: Balancer to disable session persistence on.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_disable_balancer_session_persistence_no_poll(balancer):
msg = 'Disable session persistence request not accepted'
@@ -959,10 +992,10 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to disable session persistence for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the disable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/sessionpersistence' % (balancer.id)
resp = self.connection.request(uri, method='DELETE')
@@ -976,13 +1009,13 @@ class RackspaceLBDriver(Driver, OpenStac
RUNNING state again.
@param balancer: Balancer to update the custom error page for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param page_content: HTML content for the custom error page.
- @type page_content: C{string}
+ @type page_content: C{str}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
accepted = self.ex_update_balancer_error_page_no_poll(balancer,
page_content)
@@ -998,21 +1031,19 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to update the custom error page for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param page_content: HTML content for the custom error page.
- @type page_content: C{string}
+ @type page_content: C{str}
- @rtype: C{bool}
@return: Returns whether the update request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/errorpage' % (balancer.id)
- resp = self.connection.request(uri, method='PUT',
- data=json.dumps({
- 'errorpage': {
- 'content': page_content
- }
- }))
+ resp = self.connection.request(
+ uri, method='PUT',
+ data=json.dumps({'errorpage': {'content': page_content}})
+ )
return resp.status == httplib.ACCEPTED
@@ -1024,10 +1055,10 @@ class RackspaceLBDriver(Driver, OpenStac
again.
@param balancer: Balancer to disable the custom error page for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
if not self.ex_disable_balancer_custom_error_page_no_poll(balancer):
msg = 'Disable custom error page request not accepted'
@@ -1041,10 +1072,10 @@ class RackspaceLBDriver(Driver, OpenStac
the Rackspace-provided default. This method returns immediately.
@param balancer: Balancer to disable the custom error page for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @rtype: C{bool}
@return: Returns whether the disable request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/errorpage' % (balancer.id)
resp = self.connection.request(uri, method='DELETE')
@@ -1060,13 +1091,13 @@ class RackspaceLBDriver(Driver, OpenStac
RUNNING state again.
@param balancer: Balancer to create the access rule for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param rule: Access Rule to add to the balancer.
- @type rule: C{RackspaceAccessRule}
+ @type rule: L{RackspaceAccessRule}
- @rtype: C{RackspaceAccessRule}
@return: The created access rule.
+ @rtype: L{RackspaceAccessRule}
"""
accepted = self.ex_create_balancer_access_rule_no_poll(balancer, rule)
if not accepted:
@@ -1089,19 +1120,19 @@ class RackspaceLBDriver(Driver, OpenStac
immediately.
@param balancer: Balancer to create the access rule for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param rule: Access Rule to add to the balancer.
- @type rule: C{RackspaceAccessRule}
+ @type rule: L{RackspaceAccessRule}
- @rtype: C{bool}
@return: Returns whether the create request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/accesslist' % (balancer.id)
- resp = self.connection.request(uri, method='POST',
- data=json.dumps({
- 'networkItem': rule._to_dict()
- }))
+ resp = self.connection.request(
+ uri, method='POST',
+ data=json.dumps({'networkItem': rule._to_dict()})
+ )
return resp.status == httplib.ACCEPTED
@@ -1112,15 +1143,16 @@ class RackspaceLBDriver(Driver, OpenStac
in a RUNNING state again.
@param balancer: Balancer to create the access rule for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @param rules: List of C{RackspaceAccessRule} to add to the balancer.
- @type rules: C{list}
+ @param rules: List of L{RackspaceAccessRule} to add to the balancer.
+ @type rules: C{list} of L{RackspaceAccessRule}
- @rtype: C{RackspaceAccessRule}
@return: The created access rules.
+ @rtype: L{RackspaceAccessRule}
"""
- accepted = self.ex_create_balancer_access_rules_no_poll(balancer, rules)
+ accepted = self.ex_create_balancer_access_rules_no_poll(balancer,
+ rules)
if not accepted:
msg = 'Create access rules not accepted'
raise LibcloudError(msg, driver=self)
@@ -1147,8 +1179,8 @@ class RackspaceLBDriver(Driver, OpenStac
enforces rule type and address uniqueness.
"""
for r in access_list:
- if rule_to_find.rule_type == r.rule_type and \
- rule_to_find.address == r.address:
+ if rule_to_find.rule_type == r.rule_type and\
+ rule_to_find.address == r.address:
return r
return None
@@ -1159,19 +1191,20 @@ class RackspaceLBDriver(Driver, OpenStac
returns immediately.
@param balancer: Balancer to create the access rule for.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @param rules: List of C{RackspaceAccessRule} to add to the balancer.
- @type rules: C{list}
+ @param rules: List of L{RackspaceAccessRule} to add to the balancer.
+ @type rules: C{list} of L{RackspaceAccessRule}
- @rtype: C{bool}
@return: Returns whether the create request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/accesslist' % (balancer.id)
- resp = self.connection.request(uri, method='POST',
- data=json.dumps({
- 'accessList' : [rule._to_dict() for rule in rules]
- }))
+ resp = self.connection.request(
+ uri, method='POST',
+ data=json.dumps({'accessList':
+ [rule._to_dict() for rule in rules]})
+ )
return resp.status == httplib.ACCEPTED
@@ -1182,13 +1215,13 @@ class RackspaceLBDriver(Driver, OpenStac
is in a RUNNING state again.
@param balancer: Balancer to remove the access rule from.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param rule: Access Rule to remove from the balancer.
- @type rule: C{RackspaceAccessRule}
+ @type rule: L{RackspaceAccessRule}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
accepted = self.ex_destroy_balancer_access_rule_no_poll(balancer, rule)
if not accepted:
@@ -1203,13 +1236,13 @@ class RackspaceLBDriver(Driver, OpenStac
returns immediately.
@param balancer: Balancer to remove the access rule from.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
@param rule: Access Rule to remove from the balancer.
- @type rule: C{RackspaceAccessRule}
+ @type rule: L{RackspaceAccessRule}
- @rtype: C{bool}
@return: Returns whether the destroy request was accepted.
+ @rtype: C{bool}
"""
uri = '/loadbalancers/%s/accesslist/%s' % (balancer.id, rule.id)
resp = self.connection.request(uri, method='DELETE')
@@ -1223,14 +1256,14 @@ class RackspaceLBDriver(Driver, OpenStac
balancer is in a RUNNING state again.
@param balancer: Balancer to remove the access rules from.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @param rules: List of C{RackspaceAccessRule} objects to remove from the
- balancer.
- @type rules: C{list}
+ @param rules: List of L{RackspaceAccessRule} objects to remove from the
+ balancer.
+ @type rules: C{list} of L{RackspaceAccessRule}
- @rtype: C{Balancer}
@return: Updated Balancer.
+ @rtype: L{LoadBalancer}
"""
accepted = self.ex_destroy_balancer_access_rules_no_poll(
balancer, rules)
@@ -1247,21 +1280,21 @@ class RackspaceLBDriver(Driver, OpenStac
method returns immediately.
@param balancer: Balancer to remove the access rules from.
- @type balancer: C{Balancer}
+ @type balancer: L{LoadBalancer}
- @param rules: List of C{RackspaceAccessRule} objects to remove from the
- balancer.
- @type rules: C{list}
+ @param rules: List of L{RackspaceAccessRule} objects to remove from the
+ balancer.
+ @type rules: C{list} of L{RackspaceAccessRule}
- @rtype: C{bool}
@return: Returns whether the destroy request was accepted.
+ @rtype: C{bool}
"""
ids = [('id', rule.id) for rule in rules]
uri = '/loadbalancers/%s/accesslist' % balancer.id
resp = self.connection.request(uri,
- method='DELETE',
- params=ids)
+ method='DELETE',
+ params=ids)
return resp.status == httplib.ACCEPTED
@@ -1307,8 +1340,8 @@ class RackspaceLBDriver(Driver, OpenStac
if 'protocol' in el:
extra['protocol'] = el['protocol']
- if 'algorithm' in el and el["algorithm"] in \
- self._VALUE_TO_ALGORITHM_MAP:
+ if 'algorithm' in el and \
+ el["algorithm"] in self._VALUE_TO_ALGORITHM_MAP:
extra["algorithm"] = self._value_to_algorithm(el["algorithm"])
if 'healthMonitor' in el:
@@ -1321,8 +1354,8 @@ class RackspaceLBDriver(Driver, OpenStac
if 'sessionPersistence' in el:
persistence = el["sessionPersistence"]
- extra["sessionPersistenceType"] = \
- persistence.get("persistenceType")
+ extra["sessionPersistenceType"] =\
+ persistence.get("persistenceType")
if 'connectionLogging' in el:
logging = el["connectionLogging"]
@@ -1338,38 +1371,39 @@ class RackspaceLBDriver(Driver, OpenStac
extra['updated'] = self._iso_to_datetime(el['updated']['time'])
if 'accessList' in el:
- extra['accessList'] = [self._to_access_rule(rule) \
+ extra['accessList'] = [self._to_access_rule(rule)
for rule in el['accessList']]
return LoadBalancer(id=el["id"],
- name=el["name"],
- state=self.LB_STATE_MAP.get(
- el["status"], State.UNKNOWN),
- ip=ip,
- port=port,
- driver=self.connection.driver,
- extra=extra)
+ name=el["name"],
+ state=self.LB_STATE_MAP.get(
+ el["status"], State.UNKNOWN),
+ ip=ip,
+ port=port,
+ driver=self.connection.driver,
+ extra=extra)
- def _to_members(self, object):
- return [self._to_member(el) for el in object["nodes"]]
+ def _to_members(self, object, balancer=None):
+ return [self._to_member(el, balancer) for el in object["nodes"]]
- def _to_member(self, el):
+ def _to_member(self, el, balancer=None):
extra = {}
if 'weight' in el:
extra['weight'] = el["weight"]
- if 'condition' in el and el['condition'] in \
- self.LB_MEMBER_CONDITION_MAP:
- extra['condition'] = \
- self.LB_MEMBER_CONDITION_MAP.get(el["condition"])
+ if 'condition' in el and\
+ el['condition'] in self.LB_MEMBER_CONDITION_MAP:
+ extra['condition'] =\
+ self.LB_MEMBER_CONDITION_MAP.get(el["condition"])
if 'status' in el:
extra['status'] = el["status"]
lbmember = Member(id=el["id"],
- ip=el["address"],
- port=el["port"],
- extra=extra)
+ ip=el["address"],
+ port=el["port"],
+ balancer=balancer,
+ extra=extra)
return lbmember
def _protocol_to_value(self, protocol):
@@ -1394,7 +1428,7 @@ class RackspaceLBDriver(Driver, OpenStac
update_attrs['algorithm'] = algorithm_value
if "protocol" in attrs:
- update_attrs['protocol'] = \
+ update_attrs['protocol'] =\
self._protocol_to_value(attrs['protocol'])
if "port" in attrs:
@@ -1411,7 +1445,7 @@ class RackspaceLBDriver(Driver, OpenStac
def _kwargs_to_mutable_member_attrs(self, **attrs):
update_attrs = {}
if 'condition' in attrs:
- update_attrs['condition'] = \
+ update_attrs['condition'] =\
self.CONDITION_LB_MEMBER_MAP.get(attrs['condition'])
if 'weight' in attrs:
@@ -1425,17 +1459,17 @@ class RackspaceLBDriver(Driver, OpenStac
type = health_monitor_data.get("type")
delay = health_monitor_data.get("delay")
timeout = health_monitor_data.get("timeout")
- attempts_before_deactivation = \
- health_monitor_data.get("attemptsBeforeDeactivation")
+ attempts_before_deactivation =\
+ health_monitor_data.get("attemptsBeforeDeactivation")
if type == "CONNECT":
- return RackspaceHealthMonitor(type=type, delay=delay,
- timeout=timeout,
+ return RackspaceHealthMonitor(
+ type=type, delay=delay, timeout=timeout,
attempts_before_deactivation=attempts_before_deactivation)
if type == "HTTP" or type == "HTTPS":
- return RackspaceHTTPHealthMonitor(type=type, delay=delay,
- timeout=timeout,
+ return RackspaceHTTPHealthMonitor(
+ type=type, delay=delay, timeout=timeout,
attempts_before_deactivation=attempts_before_deactivation,
path=health_monitor_data.get("path"),
status_regex=health_monitor_data.get("statusRegex"),
@@ -1451,13 +1485,15 @@ class RackspaceLBDriver(Driver, OpenStac
max_connection_rate = connection_throttle_data.get("maxConnectionRate")
rate_interval = connection_throttle_data.get("rateInterval")
- return RackspaceConnectionThrottle(min_connections=min_connections,
+ return RackspaceConnectionThrottle(
+ min_connections=min_connections,
max_connections=max_connections,
max_connection_rate=max_connection_rate,
rate_interval_seconds=rate_interval)
def _to_access_rule(self, el):
- return RackspaceAccessRule(id=el.get("id"),
+ return RackspaceAccessRule(
+ id=el.get("id"),
rule_type=self._to_access_rule_type(el.get("type")),
address=el.get("address"))
Modified: libcloud/branches/0.11.x/libcloud/loadbalancer/providers.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/loadbalancer/providers.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/loadbalancer/providers.py (original)
+++ libcloud/branches/0.11.x/libcloud/loadbalancer/providers.py Sun Nov 18 01:22:54 2012
@@ -17,10 +17,10 @@ from libcloud.utils.misc import get_driv
from libcloud.loadbalancer.types import Provider
__all__ = [
- "Provider",
- "DRIVERS",
- "get_driver",
- ]
+ "Provider",
+ "DRIVERS",
+ "get_driver",
+]
DRIVERS = {
Provider.RACKSPACE_US:
Modified: libcloud/branches/0.11.x/libcloud/loadbalancer/types.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/loadbalancer/types.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/loadbalancer/types.py (original)
+++ libcloud/branches/0.11.x/libcloud/loadbalancer/types.py Sun Nov 18 01:22:54 2012
@@ -14,11 +14,11 @@
# limitations under the License.
__all__ = [
- "Provider",
- "State",
- "LibcloudLBError",
- "LibcloudLBImmutableError",
- ]
+ "Provider",
+ "State",
+ "LibcloudLBError",
+ "LibcloudLBImmutableError",
+]
from libcloud.common.types import LibcloudError
@@ -53,9 +53,10 @@ class State(object):
ERROR = 3
DELETED = 4
+
class MemberCondition(object):
"""
- Each member of a load balancer can have an associated condition
+ Each member of a load balancer can have an associated condition
which determines its role within the load balancer.
"""
ENABLED = 0
Modified: libcloud/branches/0.11.x/libcloud/security.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/security.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/security.py (original)
+++ libcloud/branches/0.11.x/libcloud/security.py Sun Nov 18 01:22:54 2012
@@ -48,7 +48,9 @@ CA_CERTS_UNAVAILABLE_WARNING_MSG = (
)
CA_CERTS_UNAVAILABLE_ERROR_MSG = (
- 'No CA Certificates were found in CA_CERTS_PATH. '
+ 'No CA Certificates were found in CA_CERTS_PATH. For information on' + \
+ ' how to get required certificate files, please visit ' + \
+ ' http://libcloud.apache.org/docs/ssl-certificate-validation.html'
)
VERIFY_SSL_DISABLED_MSG = (
Modified: libcloud/branches/0.11.x/libcloud/storage/base.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/base.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/base.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/base.py Sun Nov 18 01:22:54 2012
@@ -35,6 +35,7 @@ from libcloud.storage.types import Objec
CHUNK_SIZE = 8096
+
class Object(object):
"""
Represents an object (BLOB).
@@ -43,26 +44,26 @@ class Object(object):
def __init__(self, name, size, hash, extra, meta_data, container,
driver):
"""
- @type name: C{str}
@param name: Object name (must be unique per container).
+ @type name: C{str}
- @type size: C{int}
@param size: Object size in bytes.
+ @type size: C{int}
- @type hash: C{string}
@param hash Object hash.
+ @type hash: C{str}
- @type container: C{Container}
@param container: Object container.
+ @type container: L{Container}
- @type extra: C{dict}
@param extra: Extra attributes.
+ @type extra: C{dict}
- @type meta_data: C{dict}
@param meta_data: Optional object meta data.
+ @type meta_data: C{dict}
- @type driver: C{StorageDriver}
@param driver: StorageDriver instance.
+ @type driver: L{StorageDriver}
"""
self.name = name
@@ -95,6 +96,7 @@ class Object(object):
return ('<Object: name=%s, size=%s, hash=%s, provider=%s ...>' %
(self.name, self.size, self.hash, self.driver.name))
+
class Container(object):
"""
Represents a container (bucket) which can hold multiple objects.
@@ -102,14 +104,14 @@ class Container(object):
def __init__(self, name, extra, driver):
"""
- @type name: C{str}
@param name: Container name (must be unique).
+ @type name: C{str}
- @type extra: C{dict}
@param extra: Extra attributes.
+ @type extra: C{dict}
- @type driver: C{StorageDriver}
@param driver: StorageDriver instance.
+ @type driver: L{StorageDriver}
"""
self.name = name
@@ -156,6 +158,7 @@ class Container(object):
return ('<Container: name=%s, provider=%s>'
% (self.name, self.driver.name))
+
class StorageDriver(BaseDriver):
"""
A base StorageDriver to derive from.
@@ -166,15 +169,18 @@ class StorageDriver(BaseDriver):
hash_type = 'md5'
supports_chunked_encoding = False
- def __init__(self, key, secret=None, secure=True, host=None, port=None, **kwargs):
- super(StorageDriver, self).__init__(key=key, secret=secret, secure=secure,
- host=host, port=port, **kwargs)
+ def __init__(self, key, secret=None, secure=True, host=None, port=None,
+ **kwargs):
+ super(StorageDriver, self).__init__(key=key, secret=secret,
+ secure=secure, host=host,
+ port=port, **kwargs)
def list_containers(self):
"""
Return a list of containers.
@return: A list of Container instances.
+ @rtype: C{list} of L{Container}
"""
raise NotImplementedError(
'list_containers not implemented for this driver')
@@ -183,10 +189,11 @@ class StorageDriver(BaseDriver):
"""
Return a list of objects for the given container.
- @type container: C{Container}
@param container: Container instance
+ @type container: L{Container}
@return: A list of Object instances.
+ @rtype: C{list} of L{Object}
"""
raise NotImplementedError(
'list_objects not implemented for this driver')
@@ -195,10 +202,11 @@ class StorageDriver(BaseDriver):
"""
Return a container instance.
- @type container_name: C{str}
@param container_name: Container name.
+ @type container_name: C{str}
- @return: C{Container} instance.
+ @return: L{Container} instance.
+ @rtype: L{Container}
"""
raise NotImplementedError(
'get_object not implemented for this driver')
@@ -207,10 +215,11 @@ class StorageDriver(BaseDriver):
"""
Return a container CDN URL.
- @type container: C{Container}
@param container: Container instance
+ @type container: L{Container}
@return: A CDN URL for this container.
+ @rtype: C{str}
"""
raise NotImplementedError(
'get_container_cdn_url not implemented for this driver')
@@ -219,58 +228,78 @@ class StorageDriver(BaseDriver):
"""
Return an object instance.
- @type container_name: C{str}
@param container_name: Container name.
+ @type container_name: C{str}
- @type object_name: C{str}
@param object_name: Object name.
+ @type object_name: C{str}
- @return: C{Object} instance.
+ @return: L{Object} instance.
+ @rtype: L{Object}
"""
raise NotImplementedError(
'get_object not implemented for this driver')
def get_object_cdn_url(self, obj):
"""
- Return a container CDN URL.
+ Return a object CDN URL.
- @type obj: C{Object}
@param obj: Object instance
+ @type obj: L{Object}
@return: A CDN URL for this object.
+ @rtype: C{str}
"""
raise NotImplementedError(
'get_object_cdn_url not implemented for this driver')
def enable_container_cdn(self, container):
+ """
+ Enable container CDN.
+
+ @param container: Container instance
+ @type container: L{Container}
+
+ @rtype: C{bool}
+ """
raise NotImplementedError(
'enable_container_cdn not implemented for this driver')
def enable_object_cdn(self, obj):
+ """
+ Enable object CDN.
+
+ @param obj: Object instance
+ @type obj: L{Object}
+
+ @rtype: C{bool}
+ """
raise NotImplementedError(
'enable_object_cdn not implemented for this driver')
- def download_object(self, obj, destination_path, overwrite_existing=False, delete_on_failure=True):
+ def download_object(self, obj, destination_path, overwrite_existing=False,
+ delete_on_failure=True):
"""
Download an object to the specified destination path.
- @type obj: C{Object}
@param obj: Object instance.
+ @type obj: L{Object}
- @type destination_path: C{str}
@param destination_path: Full path to a file or a directory where the
incoming file will be saved.
+ @type destination_path: C{str}
+ @param overwrite_existing: True to overwrite an existing file,
+ defaults to False.
@type overwrite_existing: C{bool}
- @param overwrite_existing: True to overwrite an existing file, defaults to False.
- @type delete_on_failure: C{bool}
@param delete_on_failure: True to delete a partially downloaded file if
the download was not successful (hash mismatch / file size).
+ @type delete_on_failure: C{bool}
- @rtype: C{bool}
@return: True if an object has been successfully downloaded, False
otherwise.
+ @rtype: C{bool}
"""
raise NotImplementedError(
'download_object not implemented for this driver')
@@ -279,11 +308,13 @@ class StorageDriver(BaseDriver):
"""
Return a generator which yields object data.
- @type obj: C{Object}
@param obj: Object instance
+ @type obj: L{Object}
- @type chunk_size: C{int}
@param chunk_size: Optional chunk size (in bytes).
+ @type chunk_size: C{int}
+
+ @rtype: C{object}
"""
raise NotImplementedError(
'download_object_as_stream not implemented for this driver')
@@ -293,17 +324,22 @@ class StorageDriver(BaseDriver):
"""
Upload an object currently located on a disk.
- @type file_path: C{str}
@param file_path: Path to the object on disk.
+ @type file_path: C{str}
- @type container: C{Container}
@param container: Destination container.
+ @type container: L{Container}
- @type object_name: C{str}
@param object_name: Object name.
+ @type object_name: C{str}
+
+ @param verify_hash: Verify hast
+ @type verify_hash: C{bool}
- @type extra: C{dict}
@param extra: (optional) Extra attributes (driver specific).
+ @type extra: C{dict}
+
+ @rtype: C{object}
"""
raise NotImplementedError(
'upload_object not implemented for this driver')
@@ -320,9 +356,9 @@ class StorageDriver(BaseDriver):
Otherwise if a provider doesn't support it, iterator will be exhausted
so a total size for data to be uploaded can be determined.
- Note: Exhausting the iterator means that the whole data must be buffered
- in memory which might result in memory exhausting when uploading a very
- large object.
+ Note: Exhausting the iterator means that the whole data must be
+ buffered in memory which might result in memory exhausting when
+ uploading a very large object.
If a file is located on a disk you are advised to use upload_object
function which uses fs.stat function to determine the file size and it
@@ -331,17 +367,18 @@ class StorageDriver(BaseDriver):
@type iterator: C{object}
@param iterator: An object which implements the iterator interface.
- @type container: C{Container}
+ @type container: L{Container}
@param container: Destination container.
@type object_name: C{str}
@param object_name: Object name.
@type extra: C{dict}
- @param extra: (optional) Extra attributes (driver specific).
+ @param extra: (optional) Extra attributes (driver specific). Note:
+ This dictionary must contain a 'content_type' key which represents
+ a content type of the stored object.
- Note: This dictionary must contain a 'content_type' key which represents
- a content type of the stored object.
+ @rtype: C{object}
"""
raise NotImplementedError(
'upload_object_via_stream not implemented for this driver')
@@ -350,10 +387,11 @@ class StorageDriver(BaseDriver):
"""
Delete an object.
- @type obj: C{Object}
+ @type obj: L{Object}
@param obj: Object instance.
@return: C{bool} True on success.
+ @rtype: C{bool}
"""
raise NotImplementedError(
'delete_object not implemented for this driver')
@@ -366,6 +404,7 @@ class StorageDriver(BaseDriver):
@param container_name: Container name.
@return: C{Container} instance on success.
+ @rtype: L{Container}
"""
raise NotImplementedError(
'create_container not implemented for this driver')
@@ -374,11 +413,11 @@ class StorageDriver(BaseDriver):
"""
Delete a container.
- @type container: C{Container}
+ @type container: L{Container}
@param container: Container instance
- @rtype: C{bool}
@return: True on success, False otherwise.
+ @rtype: C{bool}
"""
raise NotImplementedError(
'delete_container not implemented for this driver')
@@ -392,20 +431,22 @@ class StorageDriver(BaseDriver):
@param obj: Object instance.
@type callback: C{Function}
- @param callback: Function which is called with the passed callback_kwargs
+ @param callback: Function which is called with the passed
+ callback_kwargs
@type callback_kwargs: C{dict}
- @param callback_kwargs: Keyword arguments which are passed to the callback.
+ @param callback_kwargs: Keyword arguments which are passed to the
+ callback.
- @typed response: C{Response}
+ @typed response: L{Response}
@param response: Response instance.
@type success_status_code: C{int}
@param success_status_code: Status code which represents a successful
transfer (defaults to httplib.OK)
- @rtype: C{bool}
@return: True on success, False otherwise.
+ @rtype: C{bool}
"""
success_status_code = success_status_code or httplib.OK
@@ -425,27 +466,29 @@ class StorageDriver(BaseDriver):
"""
Save object to the provided path.
- @type response: C{RawResponse}
+ @type response: L{RawResponse}
@param response: RawResponse instance.
- @type obj: C{Object}
+ @type obj: L{Object}
@param obj: Object instance.
- @type destination_path: C{Str}
+ @type destination_path: C{str}
@param destination_path: Destination directory.
@type delete_on_failure: C{bool}
@param delete_on_failure: True to delete partially downloaded object if
the download fails.
+
@type overwrite_existing: C{bool}
@param overwrite_existing: True to overwrite a local path if it already
exists.
@type chunk_size: C{int}
- @param chunk_size: Optional chunk size (defaults to L{libcloud.storage.base.CHUNK_SIZE}, 8kb)
+ @param chunk_size: Optional chunk size
+ (defaults to L{libcloud.storage.base.CHUNK_SIZE}, 8kb)
- @rtype: C{bool}
@return: True on success, False otherwise.
+ @rtype: C{bool}
"""
chunk_size = chunk_size or CHUNK_SIZE
@@ -513,7 +556,7 @@ class StorageDriver(BaseDriver):
raise OSError('File %s does not exist' % (file_path))
if iterator is not None and not hasattr(iterator, 'next') and not \
- hasattr(iterator, '__next__'):
+ hasattr(iterator, '__next__'):
raise AttributeError('iterator object must implement next() ' +
'method.')
@@ -536,9 +579,10 @@ class StorageDriver(BaseDriver):
headers['Transfer-Encoding'] = 'chunked'
upload_func_kwargs['chunked'] = True
else:
- # Chunked transfer encoding is not supported. Need to buffer all
- # the data in memory so we can determine file size.
- iterator = libcloud.utils.files.read_in_chunks(iterator=iterator)
+ # Chunked transfer encoding is not supported. Need to buffer
+ # all the data in memory so we can determine file size.
+ iterator = libcloud.utils.files.read_in_chunks(
+ iterator=iterator)
data = libcloud.utils.files.exhaust_iterator(iterator=iterator)
file_size = len(data)
@@ -556,14 +600,15 @@ class StorageDriver(BaseDriver):
headers=headers, raw=True)
upload_func_kwargs['response'] = response
- success, data_hash, bytes_transferred = upload_func(**upload_func_kwargs)
+ success, data_hash, bytes_transferred = upload_func(
+ **upload_func_kwargs)
if not success:
- raise LibcloudError(value='Object upload failed, Perhaps a timeout?',
- driver=self)
+ raise LibcloudError(
+ value='Object upload failed, Perhaps a timeout?', driver=self)
- result_dict = { 'response': response, 'data_hash': data_hash,
- 'bytes_transferred': bytes_transferred }
+ result_dict = {'response': response, 'data_hash': data_hash,
+ 'bytes_transferred': bytes_transferred}
return result_dict
def _upload_data(self, response, data, calculate_hash=True):
@@ -647,7 +692,7 @@ class StorageDriver(BaseDriver):
try:
chunk = next(generator)
except StopIteration:
- # Special case when StopIteration is thrown on the first iteration -
+ # Special case when StopIteration is thrown on the first iteration
# create a 0-byte long object
chunk = ''
if chunked:
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/atmos.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/atmos.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/atmos.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/atmos.py Sun Nov 18 01:22:54 2012
@@ -37,9 +37,8 @@ from libcloud.common.types import LazyLi
from libcloud.storage.base import Object, Container, StorageDriver, CHUNK_SIZE
from libcloud.storage.types import ContainerAlreadyExistsError, \
- ContainerDoesNotExistError, \
- ContainerIsNotEmptyError, \
- ObjectDoesNotExistError
+ ContainerDoesNotExistError, ContainerIsNotEmptyError, \
+ ObjectDoesNotExistError
def collapse(s):
@@ -125,6 +124,8 @@ class AtmosDriver(StorageDriver):
path = None
api_name = 'atmos'
supports_chunked_encoding = True
+ website = 'http://atmosonline.com/'
+ name = 'atmos'
DEFAULT_CDN_TTL = 60 * 60 * 24 * 7 # 1 week
@@ -218,7 +219,8 @@ class AtmosDriver(StorageDriver):
extra = extra or {}
object_name_cleaned = self._clean_object_name(object_name)
- request_path = self._namespace_path(container.name) + '/' + object_name_cleaned
+ request_path = self._namespace_path(container.name) + '/' +\
+ object_name_cleaned
content_type = extra.get('content_type', None)
try:
@@ -229,13 +231,14 @@ class AtmosDriver(StorageDriver):
raise
method = 'POST'
- 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=method,
- headers={}, file_path=file_path)
+ 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=method,
+ headers={}, file_path=file_path)
bytes_transferred = result_dict['bytes_transferred']
@@ -342,7 +345,7 @@ class AtmosDriver(StorageDriver):
meta_data, container, self)
def download_object(self, obj, destination_path, overwrite_existing=False,
- delete_on_failure=True):
+ delete_on_failure=True):
path = self._namespace_path(obj.container.name + '/' + obj.name)
response = self.connection.request(path, method='GET', raw=True)
@@ -370,7 +373,8 @@ class AtmosDriver(StorageDriver):
success_status_code=httplib.OK)
def delete_object(self, obj):
- path = self._namespace_path(obj.container.name) + '/' + self._clean_object_name(obj.name)
+ path = self._namespace_path(obj.container.name) + '/' +\
+ self._clean_object_name(obj.name)
try:
self.connection.request(path, method='DELETE')
except AtmosError:
@@ -388,6 +392,20 @@ class AtmosDriver(StorageDriver):
return True
def get_object_cdn_url(self, obj, expiry=None, use_object=False):
+ """
+ Return a object CDN URL.
+
+ @param obj: Object instance
+ @type obj: L{Object}
+
+ @param expiry: Expiry
+ @type expiry: C{str}
+
+ @param use_object: Use object
+ @type use_object: C{bool}
+
+ @rtype: C{str}
+ """
if use_object:
path = '/rest/objects' + obj.meta_data['object_id']
else:
@@ -459,6 +477,6 @@ class AtmosDriver(StorageDriver):
objects = []
for entry in entries:
metadata = {'object_id': entry['id']}
- objects.append(Object(entry['name'], 0, '', {}, metadata, container,
- self))
+ objects.append(Object(entry['name'], 0, '', {}, metadata,
+ container, self))
return objects, None, True
Modified: libcloud/branches/0.11.x/libcloud/storage/drivers/cloudfiles.py
URL: http://svn.apache.org/viewvc/libcloud/branches/0.11.x/libcloud/storage/drivers/cloudfiles.py?rev=1410809&r1=1410808&r2=1410809&view=diff
==============================================================================
--- libcloud/branches/0.11.x/libcloud/storage/drivers/cloudfiles.py (original)
+++ libcloud/branches/0.11.x/libcloud/storage/drivers/cloudfiles.py Sun Nov 18 01:22:54 2012
@@ -13,9 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from hashlib import sha1
+import hmac
import os
+from time import time
from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import urlencode
try:
import simplejson as json
@@ -53,8 +57,7 @@ API_VERSION = 'v1.0'
class CloudFilesResponse(Response):
-
- valid_response_codes = [ httplib.NOT_FOUND, httplib.CONFLICT ]
+ valid_response_codes = [httplib.NOT_FOUND, httplib.CONFLICT]
def success(self):
i = int(self.status)
@@ -114,11 +117,12 @@ class CloudFilesConnection(OpenStackBase
# First, we parse out both files and cdn endpoints
# for each auth version
if '2.0' in self._auth_version:
- eps = self.service_catalog.get_endpoints(service_type='object-store',
- name='cloudFiles')
+ eps = self.service_catalog.get_endpoints(
+ service_type='object-store',
+ name='cloudFiles')
cdn_eps = self.service_catalog.get_endpoints(
- service_type='object-store',
- name='cloudFilesCDN')
+ service_type='object-store',
+ name='cloudFilesCDN')
elif ('1.1' in self._auth_version) or ('1.0' in self._auth_version):
eps = self.service_catalog.get_endpoints(name='cloudFiles')
cdn_eps = self.service_catalog.get_endpoints(name='cloudFilesCDN')
@@ -176,6 +180,7 @@ class CloudFilesSwiftConnection(CloudFil
"""
Connection class for the Cloudfiles Swift endpoint.
"""
+
def __init__(self, *args, **kwargs):
self.region_name = kwargs.pop('ex_region_name', None)
super(CloudFilesSwiftConnection, self).__init__(*args, **kwargs)
@@ -183,12 +188,12 @@ class CloudFilesSwiftConnection(CloudFil
def get_endpoint(self, *args, **kwargs):
if '2.0' in self._auth_version:
endpoint = self.service_catalog.get_endpoint(
- service_type='object-store',
- name='swift',
- region=self.region_name)
+ service_type='object-store',
+ name='swift',
+ region=self.region_name)
elif ('1.1' in self._auth_version) or ('1.0' in self._auth_version):
- endpoint = self.service_catalog.get_endpoint(name='swift',
- region=self.region_name)
+ endpoint = self.service_catalog.get_endpoint(
+ name='swift', region=self.region_name)
if 'publicURL' in endpoint:
return endpoint['publicURL']
@@ -204,6 +209,7 @@ class CloudFilesStorageDriver(StorageDri
class.
"""
name = 'CloudFiles'
+ website = 'http://www.rackspace.com/'
connectionCls = CloudFilesConnection
hash_type = 'md5'
@@ -224,12 +230,12 @@ class CloudFilesStorageDriver(StorageDri
raise LibcloudError('Unexpected status code: %s' % (response.status))
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):
response = self.connection.request('/%s' % (container_name),
- method='HEAD')
+ method='HEAD')
if response.status == httplib.NO_CONTENT:
container = self._headers_to_container(
@@ -244,8 +250,8 @@ class CloudFilesStorageDriver(StorageDri
container = self.get_container(container_name)
response = self.connection.request('/%s/%s' % (container_name,
object_name),
- method='HEAD')
- if response.status in [ httplib.OK, httplib.NO_CONTENT ]:
+ method='HEAD')
+ if response.status in [httplib.OK, httplib.NO_CONTENT]:
obj = self._headers_to_object(
object_name, container, response.headers)
return obj
@@ -275,6 +281,12 @@ class CloudFilesStorageDriver(StorageDri
return '%s/%s' % (container_cdn_url, obj.name)
def enable_container_cdn(self, container, ex_ttl=None):
+ """
+ @inherits: L{StorageDriver.enable_container_cdn}
+
+ @param ex_ttl: cache time to live
+ @type ex_ttl: C{int}
+ """
container_name = container.name
headers = {'X-CDN-Enabled': 'True'}
@@ -286,7 +298,7 @@ class CloudFilesStorageDriver(StorageDri
headers=headers,
cdn_request=True)
- return response.status in [ httplib.CREATED, httplib.ACCEPTED ]
+ return response.status in [httplib.CREATED, httplib.ACCEPTED]
def create_container(self, container_name):
container_name = self._clean_container_name(container_name)
@@ -296,9 +308,9 @@ class CloudFilesStorageDriver(StorageDri
if response.status == httplib.CREATED:
# Accepted mean that container is not yet created but it will be
# eventually
- extra = { 'object_count': 0 }
+ extra = {'object_count': 0}
container = Container(name=container_name,
- extra=extra, driver=self)
+ extra=extra, driver=self)
return container
elif response.status == httplib.ACCEPTED:
@@ -331,14 +343,14 @@ class CloudFilesStorageDriver(StorageDri
object_name),
method='GET', raw=True)
- 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},
- success_status_code=httplib.OK)
+ 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},
+ success_status_code=httplib.OK)
def download_object_as_stream(self, obj, chunk_size=None):
container_name = obj.container.name
@@ -361,7 +373,7 @@ class CloudFilesStorageDriver(StorageDri
Note: This will override file with a same name if it already exists.
"""
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,
@@ -375,7 +387,7 @@ class CloudFilesStorageDriver(StorageDri
iterator = iter(iterator)
upload_func = self._stream_data
- upload_func_kwargs = { 'iterator': iterator }
+ upload_func_kwargs = {'iterator': iterator}
return self._put_object(container=container, object_name=object_name,
upload_func=upload_func,
@@ -398,6 +410,11 @@ class CloudFilesStorageDriver(StorageDri
raise LibcloudError('Unexpected status code: %s' % (response.status))
def ex_get_meta_data(self):
+ """
+ Get meta data
+
+ @rtype: C{dict}
+ """
response = self.connection.request('', method='HEAD')
if response.status == httplib.NO_CONTENT:
@@ -407,10 +424,13 @@ class CloudFilesStorageDriver(StorageDri
'x-account-object-count', 'unknown')
bytes_used = response.headers.get(
'x-account-bytes-used', 'unknown')
+ temp_url_key = response.headers.get(
+ 'x-account-meta-temp-url-key', None)
- 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),
+ 'temp_url_key': temp_url_key}
raise LibcloudError('Unexpected status code: %s' % (response.status))
@@ -420,7 +440,7 @@ class CloudFilesStorageDriver(StorageDri
object_size = os.path.getsize(file_path)
if object_size < chunk_size:
return self.upload_object(file_path, container, object_name,
- extra=extra, verify_hash=verify_hash)
+ extra=extra, verify_hash=verify_hash)
iter_chunk_reader = FileChunkReader(file_path, chunk_size)
@@ -440,9 +460,14 @@ class CloudFilesStorageDriver(StorageDri
"""
Enable serving a static website.
+ @param container: Container instance
+ @type container: L{Container}
+
@param index_file: Name of the object which becomes an index page for
every sub-directory in this container.
@type index_file: C{str}
+
+ @rtype: C{bool}
"""
container_name = container.name
headers = {'X-Container-Meta-Web-Index': index_file}
@@ -452,15 +477,20 @@ class CloudFilesStorageDriver(StorageDri
headers=headers,
cdn_request=False)
- return response.status in [ httplib.CREATED, httplib.ACCEPTED ]
+ return response.status in [httplib.CREATED, httplib.ACCEPTED]
def ex_set_error_page(self, container, file_name='error.html'):
"""
Set a custom error page which is displayed if file is not found and
serving of a static website is enabled.
+ @param container: Container instance
+ @type container: L{Container}
+
@param file_name: Name of the object which becomes the error page.
@type file_name: C{str}
+
+ @rtype: C{bool}
"""
container_name = container.name
headers = {'X-Container-Meta-Web-Error': file_name}
@@ -470,11 +500,73 @@ class CloudFilesStorageDriver(StorageDri
headers=headers,
cdn_request=False)
- return response.status in [ httplib.CREATED, httplib.ACCEPTED ]
+ return response.status in [httplib.CREATED, httplib.ACCEPTED]
+
+ def ex_set_account_metadata_temp_url_key(self, key):
+ """
+ Set the metadata header X-Account-Meta-Temp-URL-Key on your Cloud
+ Files account.
+
+ @param key: X-Account-Meta-Temp-URL-Key
+ @type key: C{str}
+
+ @rtype: C{bool}
+ """
+ headers = {'X-Account-Meta-Temp-URL-Key': key}
+
+ response = self.connection.request('',
+ method='POST',
+ headers=headers,
+ cdn_request=False)
+
+ return response.status in [httplib.OK, httplib.NO_CONTENT,
+ httplib.CREATED, httplib.ACCEPTED]
+
+ def ex_get_object_temp_url(self, obj, method='GET', timeout=60):
+ """
+ Create a temporary URL to allow others to retrieve or put objects
+ in your Cloud Files account for as long or as short a time as you
+ wish. This method is specifically for allowing users to retrieve
+ or update an object.
+
+ @param obj: The object that you wish to make temporarily public
+ @type obj: L{Object}
+
+ @param method: Which method you would like to allow, 'PUT' or 'GET'
+ @type method: C{str}
+
+ @param timeout: Time (in seconds) after which you want the TempURL
+ to expire.
+ @type timeout: C{int}
+
+ @rtype: C{bool}
+ """
+ self.connection._populate_hosts_and_request_paths()
+ expires = int(time() + timeout)
+ path = '%s/%s/%s' % (self.connection.request_path,
+ obj.container.name, obj.name)
+ try:
+ key = self.ex_get_meta_data()['temp_url_key']
+ assert key is not None
+ except Exception:
+ raise KeyError('You must first set the ' +
+ 'X-Account-Meta-Temp-URL-Key header on your ' +
+ 'Cloud Files account using ' +
+ 'ex_set_account_metadata_temp_url_key before ' +
+ 'you can use this method.')
+ hmac_body = '%s\n%s\n%s' % (method, expires, path)
+ sig = hmac.new(b(key), b(hmac_body), sha1).hexdigest()
+ params = urlencode({'temp_url_sig': sig,
+ 'temp_url_expires': expires})
+
+ temp_url = 'https://%s/%s/%s?%s' %\
+ (self.connection.host + self.connection.request_path,
+ obj.container.name, obj.name, params)
+
+ return temp_url
def _upload_object_part(self, container, object_name, part_number,
iterator, verify_hash=True):
-
upload_func = self._stream_data
upload_func_kwargs = {'iterator': iterator}
part_name = object_name + '/%08d' % part_number
@@ -497,8 +589,9 @@ class CloudFilesStorageDriver(StorageDri
request_path = '/%s/%s' % (container_name_cleaned, object_name_cleaned)
headers = {'X-Auth-Token': self.connection.auth_token,
- 'X-Object-Manifest': '%s/%s/' % \
- (container_name_cleaned, object_name_cleaned)}
+ 'X-Object-Manifest': '%s/%s/' %
+ (container_name_cleaned,
+ object_name_cleaned)}
data = ''
response = self.connection.request(request_path,
@@ -516,8 +609,8 @@ class CloudFilesStorageDriver(StorageDri
if object_hash != data_hash:
raise ObjectHashMismatchError(
value=('MD5 hash checksum does not match (expected=%s, ' +
- 'actual=%s)') % \
- (data_hash, object_hash),
+ 'actual=%s)') %
+ (data_hash, object_hash),
object_name=object_name, driver=self)
obj = Object(name=object_name, size=0, hash=object_hash, extra=None,
@@ -533,14 +626,14 @@ class CloudFilesStorageDriver(StorageDri
params['marker'] = last_key
response = self.connection.request('/%s' % (container.name),
- params=params)
+ params=params)
if response.status == httplib.NO_CONTENT:
# Empty or inexistent container
return [], None, True
elif response.status == httplib.OK:
objects = self._to_object_list(json.loads(response.body),
- container)
+ container)
# TODO: Is this really needed?
if len(objects) == 0:
@@ -566,14 +659,11 @@ class CloudFilesStorageDriver(StorageDri
headers[key] = value
request_path = '/%s/%s' % (container_name_cleaned, object_name_cleaned)
- 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'].response
bytes_transferred = result_dict['bytes_transferred']
@@ -616,9 +706,9 @@ class CloudFilesStorageDriver(StorageDri
container_name=name, driver=self)
if len(name) > 256:
- raise InvalidContainerNameError(value='Container name cannot be'
- ' longer than 256 bytes',
- container_name=name, driver=self)
+ raise InvalidContainerNameError(
+ value='Container name cannot be longer than 256 bytes',
+ container_name=name, driver=self)
return name
@@ -631,8 +721,8 @@ class CloudFilesStorageDriver(StorageDri
containers = []
for container in response:
- extra = { 'object_count': int(container['count']),
- 'size': int(container['bytes'])}
+ extra = {'object_count': int(container['count']),
+ 'size': int(container['bytes'])}
containers.append(Container(name=container['name'], extra=extra,
driver=self))
@@ -645,8 +735,8 @@ class CloudFilesStorageDriver(StorageDri
name = obj['name']
size = int(obj['bytes'])
hash = obj['hash']
- extra = { 'content_type': obj['content_type'],
- 'last_modified': obj['last_modified'] }
+ extra = {'content_type': obj['content_type'],
+ 'last_modified': obj['last_modified']}
objects.append(Object(
name=name, size=size, hash=hash, extra=extra,
meta_data=None, container=container, driver=self))
@@ -657,8 +747,8 @@ class CloudFilesStorageDriver(StorageDri
size = int(headers.get('x-container-bytes-used', 0))
object_count = int(headers.get('x-container-object-count', 0))
- extra = { 'object_count': object_count,
- 'size': size }
+ extra = {'object_count': object_count,
+ 'size': size}
container = Container(name=name, extra=extra, driver=self)
return container
@@ -707,8 +797,8 @@ class CloudFilesSwiftStorageDriver(Cloud
super(CloudFilesSwiftStorageDriver, self).__init__(*args, **kwargs)
def openstack_connection_kwargs(self):
- rv = super(CloudFilesSwiftStorageDriver, self). \
- openstack_connection_kwargs()
+ rv = super(CloudFilesSwiftStorageDriver,
+ self).openstack_connection_kwargs()
rv['ex_region_name'] = self._ex_region_name
return rv
@@ -752,6 +842,7 @@ class FileChunkReader(object):
def __next__(self):
return self.next()
+
class ChunkStreamReader(object):
def __init__(self, file_path, start_block, end_block, chunk_size):
self.fd = open(file_path, 'rb')
@@ -771,11 +862,10 @@ class ChunkStreamReader(object):
raise StopIteration
block_size = self.chunk_size
- if self.bytes_read + block_size > \
- self.end_block - self.start_block:
- block_size = self.end_block - self.start_block - \
- self.bytes_read
- self.stop_iteration = True
+ if self.bytes_read + block_size >\
+ self.end_block - self.start_block:
+ block_size = self.end_block - self.start_block - self.bytes_read
+ self.stop_iteration = True
block = self.fd.read(block_size)
self.bytes_read += block_size