[pkg-eucalyptus-commits] [SCM] managing cloud instances for Eucalyptus branch, master, updated. 3.0.0-alpha3-257-g1da8e3a
Garrett Holmstrom
gholms at fedoraproject.org
Sun Jun 16 02:30:05 UTC 2013
The following commit has been merged in the master branch:
commit 3fac2e1c8e64c7168e79e8f2e81fe38512961944
Author: Garrett Holmstrom <gholms at fedoraproject.org>
Date: Wed Feb 13 15:13:36 2013 -0800
Add walrus redirect handling and bucket name validation
diff --git a/euca2ools/commands/walrus/__init__.py b/euca2ools/commands/walrus/__init__.py
index f1c66c4..6b16d1b 100644
--- a/euca2ools/commands/walrus/__init__.py
+++ b/euca2ools/commands/walrus/__init__.py
@@ -34,6 +34,8 @@ import requestbuilder.auth
import requestbuilder.request
import requestbuilder.service
from requestbuilder.xmlparse import parse_aws_xml
+import string
+import urlparse
from .. import Euca2oolsRequest
class Walrus(requestbuilder.service.BaseService):
@@ -50,3 +52,72 @@ class WalrusRequest(Euca2oolsRequest):
SERVICE_CLASS = Walrus
ARGS = [Arg('-U', '--url', dest='url', metavar='URL', route_to=SERVICE,
help='storage service endpoint URL')]
+
+ def __init__(self, **kwargs):
+ Euca2oolsRequest.__init__(self, **kwargs)
+ self.redirects_left = 3
+
+ def handle_server_error(self, err):
+ if 300 <= err.status_code < 400 and 'Endpoint' in err.elements:
+ # When S3 does an inter-region redirect it doesn't supply the new
+ # location in the usual header, but rather supplies a new endpoint
+ # in the error's XML. This forces us to handle it manually.
+ self.log.debug('-- response content --\n',
+ extra={'append': True})
+ self.log.debug(self.response.text, extra={'append': True})
+ self.log.debug('-- end of response content --')
+ self.log.info('result: redirect')
+ if self.redirects_left > 0:
+ self.redirects_left -= 1
+ parsed = list(urlparse.urlparse(self.service.endpoint))
+ parsed[1] = err.elements['Endpoint']
+ new_url = urlparse.urlunparse(parsed)
+ self.log.debug('redirecting to %s (%i redirects remaining)',
+ new_url, self.redirects_left)
+ self.service.endpoint = new_url
+ return self.send()
+ else:
+ self.log.warn('too many redirects; giving up')
+ raise
+
+
+def validate_generic_bucket_name(bucket):
+ if len(bucket) == 0:
+ raise ValueError('name is too short')
+ if len(bucket) > 255:
+ raise ValueError('name is too long')
+ for char in bucket:
+ if char not in string.ascii_letters + string.digits + '.-_':
+ raise ValueError('invalid character \'{0}\''.format(char))
+
+
+def validate_dns_bucket_name(bucket):
+ if len(bucket) < 3:
+ raise ValueError('name is too short')
+ if len(bucket) > 63:
+ raise ValueError('name is too long')
+ if bucket.startswith('.'):
+ raise ValueError('name may not start with \'.\'')
+ if bucket.endswith('.'):
+ raise ValueError('name may not end with \'.\'')
+ labels = bucket.split('.')
+ for label in labels:
+ if len(label) == 0:
+ raise ValueError('name may not contain \'..\'')
+ for char in label:
+ if char not in string.ascii_lowercase + string.digits + '-':
+ raise ValueError('invalid character \'{0}\''.format(char))
+ if label[0] not in string.ascii_lowercase + string.digits:
+ raise ValueError(('character \'{0}\' may not begin part of a '
+ 'bucket name').format(char))
+ if label[-1] not in string.ascii_lowercase + string.digits:
+ raise ValueError(('character \'{0}\' may not end part of a '
+ 'bucket name').format(char))
+ if len(labels) == 4:
+ try:
+ bucket_as_digits = map(int, bucket.split('.'))
+ except ValueError:
+ # This is actually the case we want
+ pass
+ else:
+ raise ValueError('name must not be formatted like an IP address')
--
managing cloud instances for Eucalyptus
More information about the pkg-eucalyptus-commits
mailing list