Hello community, here is the log from the commit of package python-boto for openSUSE:Factory checked in at 2013-05-13 15:24:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-boto (Old) and /work/SRC/openSUSE:Factory/.python-boto.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-boto" Changes: -------- --- /work/SRC/openSUSE:Factory/python-boto/python-boto.changes 2013-05-03 07:35:03.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-boto.new/python-boto.changes 2013-05-13 15:24:04.000000000 +0200 @@ -1,0 +2,7 @@ +Tue May 7 07:13:52 UTC 2013 - dmueller@suse.com + +- update to 2.9.2: + * Fixes to Amazon Redshift + * Documentation updates + +------------------------------------------------------------------- Old: ---- boto-2.9.0.tar.gz New: ---- boto-2.9.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-boto-doc.spec ++++++ --- /var/tmp/diff_new_pack.LPsNKo/_old 2013-05-13 15:24:05.000000000 +0200 +++ /var/tmp/diff_new_pack.LPsNKo/_new 2013-05-13 15:24:05.000000000 +0200 @@ -17,7 +17,7 @@ Name: python-boto-doc -Version: 2.9.0 +Version: 2.9.2 Release: 0 Url: http://code.google.com/p/boto/ Summary: Amazon Web Services Library python-boto.spec: same change ++++++ boto-2.9.0.tar.gz -> boto-2.9.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/PKG-INFO new/boto-2.9.2/PKG-INFO --- old/boto-2.9.0/PKG-INFO 2013-04-18 13:42:13.000000000 +0200 +++ new/boto-2.9.2/PKG-INFO 2013-05-01 03:30:28.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: boto -Version: 2.9.0 +Version: 2.9.2 Summary: Amazon Web Services Library Home-page: https://github.com/boto/boto/ Author: Mitch Garnaat @@ -9,8 +9,8 @@ Description: #### boto #### - boto 2.8.0 - 31-Jan-2013 + boto 2.9.2 + 30-Apr-2013 .. image:: https://secure.travis-ci.org/boto/boto.png?branch=develop :target: https://secure.travis-ci.org/boto/boto diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/README.rst new/boto-2.9.2/README.rst --- old/boto-2.9.0/README.rst 2013-04-18 13:18:21.000000000 +0200 +++ new/boto-2.9.2/README.rst 2013-05-01 03:28:01.000000000 +0200 @@ -1,8 +1,8 @@ #### boto #### -boto 2.8.0 -31-Jan-2013 +boto 2.9.2 +30-Apr-2013 .. image:: https://secure.travis-ci.org/boto/boto.png?branch=develop :target: https://secure.travis-ci.org/boto/boto diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/__init__.py new/boto-2.9.2/boto/__init__.py --- old/boto-2.9.0/boto/__init__.py 2013-04-18 13:40:01.000000000 +0200 +++ new/boto-2.9.2/boto/__init__.py 2013-05-01 03:28:01.000000000 +0200 @@ -36,7 +36,7 @@ import urlparse from boto.exception import InvalidUriError -__version__ = '2.9.0' +__version__ = '2.9.2' Version = __version__ # for backware compatibility UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform) @@ -674,6 +674,48 @@ **kwargs) +def connect_redshift(aws_access_key_id=None, + aws_secret_access_key=None, + **kwargs): + """ + :type aws_access_key_id: string + :param aws_access_key_id: Your AWS Access Key ID + + :type aws_secret_access_key: string + :param aws_secret_access_key: Your AWS Secret Access Key + + :rtype: :class:`boto.redshift.layer1.RedshiftConnection` + :return: A connection to Amazon's Redshift service + """ + from boto.redshift.layer1 import RedshiftConnection + return RedshiftConnection( + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, + **kwargs + ) + + +def connect_support(aws_access_key_id=None, + aws_secret_access_key=None, + **kwargs): + """ + :type aws_access_key_id: string + :param aws_access_key_id: Your AWS Access Key ID + + :type aws_secret_access_key: string + :param aws_secret_access_key: Your AWS Secret Access Key + + :rtype: :class:`boto.support.layer1.SupportConnection` + :return: A connection to Amazon's Support service + """ + from boto.support.layer1 import SupportConnection + return SupportConnection( + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, + **kwargs + ) + + def storage_uri(uri_str, default_scheme='file', debug=0, validate=True, bucket_storage_uri_class=BucketStorageUri, suppress_consec_slashes=True, is_latest=False): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/connection.py new/boto-2.9.2/boto/connection.py --- old/boto-2.9.0/boto/connection.py 2013-04-18 13:18:21.000000000 +0200 +++ new/boto-2.9.2/boto/connection.py 2013-05-01 02:40:31.000000000 +0200 @@ -539,9 +539,11 @@ aws_secret_access_key, security_token) - # allow config file to override default host + # Allow config file to override default host and port. if self.provider.host: self.host = self.provider.host + if self.provider.port: + self.port = self.provider.port self._pool = ConnectionPool() self._connection = (self.server_name(), self.is_secure) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/dynamodb/layer2.py new/boto-2.9.2/boto/dynamodb/layer2.py --- old/boto-2.9.0/boto/dynamodb/layer2.py 2013-04-18 13:18:21.000000000 +0200 +++ new/boto-2.9.2/boto/dynamodb/layer2.py 2013-05-01 02:40:31.000000000 +0200 @@ -681,6 +681,9 @@ :param count: If True, Amazon DynamoDB returns a total number of items for the Query operation, even if the operation has no matching items for the assigned filter. + If count is True, the actual items are not returned and + the count is accessible as the ``count`` attribute of + the returned object. :type exclusive_start_key: list or tuple :param exclusive_start_key: Primary key of the item from @@ -769,6 +772,9 @@ :param count: If True, Amazon DynamoDB returns a total number of items for the Scan operation, even if the operation has no matching items for the assigned filter. + If count is True, the actual items are not returned and + the count is accessible as the ``count`` attribute of + the returned object. :type exclusive_start_key: list or tuple :param exclusive_start_key: Primary key of the item from diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/dynamodb/table.py new/boto-2.9.2/boto/dynamodb/table.py --- old/boto-2.9.0/boto/dynamodb/table.py 2013-04-18 13:18:21.000000000 +0200 +++ new/boto-2.9.2/boto/dynamodb/table.py 2013-05-01 02:40:31.000000000 +0200 @@ -435,6 +435,9 @@ :param count: If True, Amazon DynamoDB returns a total number of items for the Query operation, even if the operation has no matching items for the assigned filter. + If count is True, the actual items are not returned and + the count is accessible as the ``count`` attribute of + the returned object. :type item_class: Class @@ -494,6 +497,9 @@ :param count: If True, Amazon DynamoDB returns a total number of items for the Scan operation, even if the operation has no matching items for the assigned filter. + If count is True, the actual items are not returned and + the count is accessible as the ``count`` attribute of + the returned object. :type exclusive_start_key: list or tuple :param exclusive_start_key: Primary key of the item from diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/dynamodb2/exceptions.py new/boto-2.9.2/boto/dynamodb2/exceptions.py --- old/boto-2.9.0/boto/dynamodb2/exceptions.py 2013-04-18 13:39:58.000000000 +0200 +++ new/boto-2.9.2/boto/dynamodb2/exceptions.py 2013-05-01 02:40:31.000000000 +0200 @@ -46,5 +46,9 @@ pass +class ValidationException(JSONResponseError): + pass + + class ItemCollectionSizeLimitExceededException(JSONResponseError): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/dynamodb2/layer1.py new/boto-2.9.2/boto/dynamodb2/layer1.py --- old/boto-2.9.0/boto/dynamodb2/layer1.py 2013-04-18 13:39:58.000000000 +0200 +++ new/boto-2.9.2/boto/dynamodb2/layer1.py 2013-05-01 02:40:31.000000000 +0200 @@ -19,6 +19,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # +from binascii import crc32 import json import boto @@ -30,9 +31,10 @@ class DynamoDBConnection(AWSQueryConnection): """ - Amazon DynamoDB **Overview** - This is the Amazon DynamoDB API Reference. This guide provides - descriptions and samples of the Amazon DynamoDB API. + Amazon DynamoDB is a fast, highly scalable, highly available, + cost-effective non-relational database service. Amazon DynamoDB + removes traditional scalability limitations on data storage while + maintaining low latency and predictable performance. """ APIVersion = "2012-08-10" DefaultRegionName = "us-east-1" @@ -49,17 +51,23 @@ "ResourceNotFoundException": exceptions.ResourceNotFoundException, "InternalServerError": exceptions.InternalServerError, "ItemCollectionSizeLimitExceededException": exceptions.ItemCollectionSizeLimitExceededException, + "ValidationException": exceptions.ValidationException, } + NumberRetries = 10 + def __init__(self, **kwargs): region = kwargs.pop('region', None) + validate_checksums = kwargs.pop('validate_checksums', True) if not region: region = RegionInfo(self, self.DefaultRegionName, self.DefaultRegionEndpoint) kwargs['host'] = region.endpoint AWSQueryConnection.__init__(self, **kwargs) self.region = region + self._validate_checksums = boto.config.getbool( + 'DynamoDB', 'validate_checksums', validate_checksums) def _required_auth_capability(self): return ['hmac-v4'] @@ -1392,7 +1400,8 @@ method='POST', path='/', auth_path='/', params={}, headers=headers, data=body) response = self._mexe(http_request, sender=None, - override_num_retries=10) + override_num_retries=self.NumberRetries, + retry_handler=self._retry_handler) response_body = response.read() boto.log.debug(response_body) if response.status == 200: @@ -1405,3 +1414,51 @@ raise exception_class(response.status, response.reason, body=json_body) + def _retry_handler(self, response, i, next_sleep): + status = None + if response.status == 400: + response_body = response.read() + boto.log.debug(response_body) + data = json.loads(response_body) + if 'ProvisionedThroughputExceededException' in data.get('__type'): + self.throughput_exceeded_events += 1 + msg = "%s, retry attempt %s" % ( + 'ProvisionedThroughputExceededException', + i + ) + next_sleep = self._exponential_time(i) + i += 1 + status = (msg, i, next_sleep) + if i == self.NumberRetries: + # If this was our last retry attempt, raise + # a specific error saying that the throughput + # was exceeded. + raise exceptions.ProvisionedThroughputExceededException( + response.status, response.reason, data) + elif 'ConditionalCheckFailedException' in data.get('__type'): + raise exceptions.ConditionalCheckFailedException( + response.status, response.reason, data) + elif 'ValidationException' in data.get('__type'): + raise exceptions.ValidationException( + response.status, response.reason, data) + else: + raise self.ResponseError(response.status, response.reason, + data) + expected_crc32 = response.getheader('x-amz-crc32') + if self._validate_checksums and expected_crc32 is not None: + boto.log.debug('Validating crc32 checksum for body: %s', + response.read()) + actual_crc32 = crc32(response.read()) & 0xffffffff + expected_crc32 = int(expected_crc32) + if actual_crc32 != expected_crc32: + msg = ("The calculated checksum %s did not match the expected " + "checksum %s" % (actual_crc32, expected_crc32)) + status = (msg, i + 1, self._exponential_time(i)) + return status + + def _exponential_time(self, i): + if i == 0: + next_sleep = 0 + else: + next_sleep = 0.05 * (2 ** i) + return next_sleep diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/ec2/connection.py new/boto-2.9.2/boto/ec2/connection.py --- old/boto-2.9.0/boto/ec2/connection.py 2013-04-18 13:18:21.000000000 +0200 +++ new/boto-2.9.2/boto/ec2/connection.py 2013-05-01 02:40:31.000000000 +0200 @@ -2208,9 +2208,9 @@ it to AWS. :rtype: :class:`boto.ec2.keypair.KeyPair` - :return: The newly created :class:`boto.ec2.keypair.KeyPair`. - The material attribute of the new KeyPair object - will contain the the unencrypted PEM encoded RSA private key. + :return: A :class:`boto.ec2.keypair.KeyPair` object representing + the newly imported key pair. This object will contain only + the key name and the fingerprint. """ public_key_material = base64.b64encode(public_key_material) params = {'KeyName': key_name, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/gs/resumable_upload_handler.py new/boto-2.9.2/boto/gs/resumable_upload_handler.py --- old/boto-2.9.0/boto/gs/resumable_upload_handler.py 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/boto/gs/resumable_upload_handler.py 2013-05-01 02:40:31.000000000 +0200 @@ -161,6 +161,22 @@ """ return self.tracker_uri + def get_upload_id(self): + """ + Returns the upload ID for the resumable upload, or None if the upload + has not yet started. + """ + # We extract the upload_id from the tracker uri. We could retrieve the + # upload_id from the headers in the response but this only works for + # the case where we get the tracker uri from the service. In the case + # where we get the tracker from the tracking file we need to do this + # logic anyway. + delim = '?upload_id=' + if self.tracker_uri and delim in self.tracker_uri: + return self.tracker_uri[self.tracker_uri.index(delim) + len(delim):] + else: + return None + def _remove_tracker_file(self): if (self.tracker_file_name and os.path.exists(self.tracker_file_name)): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/provider.py new/boto-2.9.2/boto/provider.py --- old/boto-2.9.0/boto/provider.py 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/boto/provider.py 2013-05-01 02:40:31.000000000 +0200 @@ -117,7 +117,8 @@ 'metadata-directive', RESUMABLE_UPLOAD_HEADER_KEY: None, SECURITY_TOKEN_HEADER_KEY: AWS_HEADER_PREFIX + 'security-token', - SERVER_SIDE_ENCRYPTION_KEY: AWS_HEADER_PREFIX + 'server-side-encryption', + SERVER_SIDE_ENCRYPTION_KEY: AWS_HEADER_PREFIX + + 'server-side-encryption', VERSION_ID_HEADER_KEY: AWS_HEADER_PREFIX + 'version-id', STORAGE_CLASS_HEADER_KEY: AWS_HEADER_PREFIX + 'storage-class', MFA_HEADER_KEY: AWS_HEADER_PREFIX + 'mfa', @@ -166,6 +167,7 @@ def __init__(self, name, access_key=None, secret_key=None, security_token=None): self.host = None + self.port = None self.access_key = access_key self.secret_key = secret_key self.security_token = security_token @@ -176,10 +178,13 @@ self.get_credentials(access_key, secret_key) self.configure_headers() self.configure_errors() - # allow config file to override default host + # Allow config file to override default host and port. host_opt_name = '%s_host' % self.HostKeyMap[self.name] if config.has_option('Credentials', host_opt_name): self.host = config.get('Credentials', host_opt_name) + port_opt_name = '%s_port' % self.HostKeyMap[self.name] + if config.has_option('Credentials', port_opt_name): + self.port = config.getint('Credentials', port_opt_name) def get_access_key(self): if self._credentials_need_refresh(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/redshift/__init__.py new/boto-2.9.2/boto/redshift/__init__.py --- old/boto-2.9.0/boto/redshift/__init__.py 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/boto/redshift/__init__.py 2013-05-01 02:40:31.000000000 +0200 @@ -39,6 +39,9 @@ RegionInfo(name='us-west-2', endpoint='redshift.us-west-2.amazonaws.com', connection_cls=cls), + RegionInfo(name='eu-west-1', + endpoint='redshift.eu-west-1.amazonaws.com', + connection_cls=cls), ] @@ -47,4 +50,3 @@ if region.name == region_name: return region.connect(**kw_params) return None - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/s3/key.py new/boto-2.9.2/boto/s3/key.py --- old/boto-2.9.0/boto/s3/key.py 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/boto/s3/key.py 2013-05-01 02:40:31.000000000 +0200 @@ -1419,6 +1419,7 @@ if e.errno == errno.ENOSPC: raise StorageDataError('Out of space for destination file ' '%s' % fp.name) + raise if cb and (cb_count <= 1 or i > 0) and data_len > 0: cb(data_len, cb_size) for alg in digesters: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/s3/resumable_download_handler.py new/boto-2.9.2/boto/s3/resumable_download_handler.py --- old/boto-2.9.0/boto/s3/resumable_download_handler.py 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/boto/s3/resumable_download_handler.py 2013-05-01 02:40:31.000000000 +0200 @@ -263,9 +263,9 @@ headers = {} # Use num-retries from constructor if one was provided; else check - # for a value specified in the boto config file; else default to 5. + # for a value specified in the boto config file; else default to 6. if self.num_retries is None: - self.num_retries = config.getint('Boto', 'num_retries', 5) + self.num_retries = config.getint('Boto', 'num_retries', 6) progress_less_iterations = 0 while True: # Retry as long as we're making progress. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/storage_uri.py new/boto-2.9.2/boto/storage_uri.py --- old/boto-2.9.0/boto/storage_uri.py 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/boto/storage_uri.py 2013-05-01 02:40:31.000000000 +0200 @@ -101,15 +101,7 @@ @return: A connection to storage service provider of the given URI. """ connection_args = dict(self.connection_args or ()) - # Use OrdinaryCallingFormat instead of boto-default - # SubdomainCallingFormat because the latter changes the hostname - # that's checked during cert validation for HTTPS connections, - # which will fail cert validation (when cert validation is enabled). - # Note: the following import can't be moved up to the start of - # this file else it causes a config import failure when run from - # the resumable upload/download tests. - from boto.s3.connection import OrdinaryCallingFormat - connection_args['calling_format'] = OrdinaryCallingFormat() + if (hasattr(self, 'suppress_consec_slashes') and 'suppress_consec_slashes' not in connection_args): connection_args['suppress_consec_slashes'] = ( @@ -126,6 +118,23 @@ self.provider_pool[self.scheme] = self.connection elif self.scheme == 'gs': from boto.gs.connection import GSConnection + # Use OrdinaryCallingFormat instead of boto-default + # SubdomainCallingFormat because the latter changes the hostname + # that's checked during cert validation for HTTPS connections, + # which will fail cert validation (when cert validation is + # enabled). + # + # The same is not true for S3's HTTPS certificates. In fact, + # we don't want to do this for S3 because S3 requires the + # subdomain to match the location of the bucket. If the proper + # subdomain is not used, the server will return a 301 redirect + # with no Location header. + # + # Note: the following import can't be moved up to the + # start of this file else it causes a config import failure when + # run from the resumable upload/download tests. + from boto.s3.connection import OrdinaryCallingFormat + connection_args['calling_format'] = OrdinaryCallingFormat() self.connection = GSConnection(access_key_id, secret_access_key, **connection_args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/support/__init__.py new/boto-2.9.2/boto/support/__init__.py --- old/boto-2.9.0/boto/support/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/boto-2.9.2/boto/support/__init__.py 2013-05-01 03:17:04.000000000 +0200 @@ -0,0 +1,47 @@ +# Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, dis- +# tribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the fol- +# lowing conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- +# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +from boto.regioninfo import RegionInfo + + +def regions(): + """ + Get all available regions for the Amazon Support service. + + :rtype: list + :return: A list of :class:`boto.regioninfo.RegionInfo` + """ + from boto.support.layer1 import SupportConnection + return [ + RegionInfo( + name='us-east-1', + endpoint='support.us-east-1.amazonaws.com', + connection_cls=SupportConnection + ), + ] + + +def connect_to_region(region_name, **kw_params): + for region in regions(): + if region.name == region_name: + return region.connect(**kw_params) + return None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/support/exceptions.py new/boto-2.9.2/boto/support/exceptions.py --- old/boto-2.9.0/boto/support/exceptions.py 1970-01-01 01:00:00.000000000 +0100 +++ new/boto-2.9.2/boto/support/exceptions.py 2013-05-01 03:17:04.000000000 +0200 @@ -0,0 +1,34 @@ +# Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, dis- +# tribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the fol- +# lowing conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- +# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +from boto.exception import JSONResponseError + + +class CaseIdNotFound(JSONResponseError): + pass + + +class CaseCreationLimitExceeded(JSONResponseError): + pass + + +class InternalServerError(JSONResponseError): + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto/support/layer1.py new/boto-2.9.2/boto/support/layer1.py --- old/boto-2.9.0/boto/support/layer1.py 1970-01-01 01:00:00.000000000 +0100 +++ new/boto-2.9.2/boto/support/layer1.py 2013-05-01 03:17:04.000000000 +0200 @@ -0,0 +1,529 @@ +# Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, dis- +# tribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the fol- +# lowing conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- +# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +import json +import boto +from boto.connection import AWSQueryConnection +from boto.regioninfo import RegionInfo +from boto.exception import JSONResponseError +from boto.support import exceptions + + +class SupportConnection(AWSQueryConnection): + """ + AWS Support + The AWS Support API reference is intended for programmers who need + detailed information about the AWS Support actions and data types. + This service enables you to manage with your AWS Support cases + programmatically. It is built on the AWS Query API programming + model and provides HTTP methods that take parameters and return + results in JSON format. + + The AWS Support service also exposes a set of `Trusted Advisor`_ + features. You can retrieve a list of checks you can run on your + resources, specify checks to run and refresh, and check the status + of checks you have submitted. + + The following list describes the AWS Support case management + actions: + + + + **Service names, issue categories, and available severity + levels. **The actions `DescribeServices`_ and + `DescribeSeverityLevels`_ enable you to obtain AWS service names, + service codes, service categories, and problem severity levels. + You use these values when you call the `CreateCase`_ action. + + **Case Creation, case details, and case resolution**. The + actions `CreateCase`_, `DescribeCases`_, and `ResolveCase`_ enable + you to create AWS Support cases, retrieve them, and resolve them. + + **Case communication**. The actions + `DescribeCaseCommunications`_ and `AddCommunicationToCase`_ enable + you to retrieve and add communication to AWS Support cases. + + + The following list describes the actions available from the AWS + Support service for Trusted Advisor: + + + + `DescribeTrustedAdviserChecks`_ returns the list of checks that you can run against your AWS + resources. + + Using the CheckId for a specific check returned by + DescribeTrustedAdviserChecks, you can call + `DescribeTrustedAdvisorCheckResult`_ and obtain a new result for the check you specified. + + Using `DescribeTrustedAdvisorCheckSummaries`_, you can get + summaries for a set of Trusted Advisor checks. + + `RefreshTrustedAdvisorCheck`_ enables you to request that + Trusted Advisor run the check again. + + ``_ gets statuses on the checks you are running. + + + For authentication of requests, the AWS Support uses `Signature + Version 4 Signing Process`_. + + See the AWS Support Developer Guide for information about how to + use this service to manage create and manage your support cases, + and how to call Trusted Advisor for results of checks on your + resources. + """ + APIVersion = "2012-12-15" + DefaultRegionName = "us-east-1" + DefaultRegionEndpoint = "support.us-east-1.amazonaws.com" + ServiceName = "Support" + TargetPrefix = "AWSSupport_20130415" + ResponseError = JSONResponseError + + _faults = { + "CaseIdNotFound": exceptions.CaseIdNotFound, + "CaseCreationLimitExceeded": exceptions.CaseCreationLimitExceeded, + "InternalServerError": exceptions.InternalServerError, + } + + + def __init__(self, **kwargs): + region = kwargs.pop('region', None) + if not region: + region = RegionInfo(self, self.DefaultRegionName, + self.DefaultRegionEndpoint) + kwargs['host'] = region.endpoint + AWSQueryConnection.__init__(self, **kwargs) + self.region = region + + def _required_auth_capability(self): + return ['hmac-v4'] + + def add_communication_to_case(self, communication_body, case_id=None, + cc_email_addresses=None): + """ + This action adds additional customer communication to an AWS + Support case. You use the CaseId value to identify the case to + which you want to add communication. You can list a set of + email addresses to copy on the communication using the + CcEmailAddresses value. The CommunicationBody value contains + the text of the communication. + + This action's response indicates the success or failure of the + request. + + This action implements a subset of the behavior on the AWS + Support `Your Support Cases`_ web form. + + :type case_id: string + :param case_id: + + :type communication_body: string + :param communication_body: + + :type cc_email_addresses: list + :param cc_email_addresses: + + """ + params = {'communicationBody': communication_body, } + if case_id is not None: + params['caseId'] = case_id + if cc_email_addresses is not None: + params['ccEmailAddresses'] = cc_email_addresses + return self.make_request(action='AddCommunicationToCase', + body=json.dumps(params)) + + def create_case(self, subject, service_code, category_code, + communication_body, severity_code=None, + cc_email_addresses=None, language=None, issue_type=None): + """ + Creates a new case in the AWS Support Center. This action is + modeled on the behavior of the AWS Support Center `Open a new + case`_ page. Its parameters require you to specify the + following information: + + + #. **ServiceCode.** Represents a code for an AWS service. You + obtain the ServiceCode by calling `DescribeServices`_. + #. **CategoryCode**. Represents a category for the service + defined for the ServiceCode value. You also obtain the + cateogory code for a service by calling `DescribeServices`_. + Each AWS service defines its own set of category codes. + #. **SeverityCode**. Represents a value that specifies the + urgency of the case, and the time interval in which your + service level agreement specifies a response from AWS Support. + You obtain the SeverityCode by calling + `DescribeSeverityLevels`_. + #. **Subject**. Represents the **Subject** field on the AWS + Support Center `Open a new case`_ page. + #. **CommunicationBody**. Represents the **Description** field + on the AWS Support Center `Open a new case`_ page. + #. **Language**. Specifies the human language in which AWS + Support handles the case. The API currently supports English + and Japanese. + #. **CcEmailAddresses**. Represents the AWS Support Center + **CC** field on the `Open a new case`_ page. You can list + email addresses to be copied on any correspondence about the + case. The account that opens the case is already identified by + passing the AWS Credentials in the HTTP POST method or in a + method or function call from one of the programming languages + supported by an `AWS SDK`_. + + + The AWS Support API does not currently support the ability to + add attachments to cases. You can, however, call + `AddCommunicationToCase`_ to add information to an open case. + + A successful `CreateCase`_ request returns an AWS Support case + number. Case numbers are used by `DescribeCases`_ request to + retrieve existing AWS Support support cases. + + :type subject: string + :param subject: + + :type service_code: string + :param service_code: + + :type severity_code: string + :param severity_code: + + :type category_code: string + :param category_code: + + :type communication_body: string + :param communication_body: + + :type cc_email_addresses: list + :param cc_email_addresses: + + :type language: string + :param language: + + :type issue_type: string + :param issue_type: + + """ + params = { + 'subject': subject, + 'serviceCode': service_code, + 'categoryCode': category_code, + 'communicationBody': communication_body, + } + if severity_code is not None: + params['severityCode'] = severity_code + if cc_email_addresses is not None: + params['ccEmailAddresses'] = cc_email_addresses + if language is not None: + params['language'] = language + if issue_type is not None: + params['issueType'] = issue_type + return self.make_request(action='CreateCase', + body=json.dumps(params)) + + def describe_cases(self, case_id_list=None, display_id=None, + after_time=None, before_time=None, + include_resolved_cases=None, next_token=None, + max_results=None, language=None): + """ + This action returns a list of cases that you specify by + passing one or more CaseIds. In addition, you can filter the + cases by date by setting values for the AfterTime and + BeforeTime request parameters. + The response returns the following in JSON format: + + #. One or more `CaseDetails`_ data types. + #. One or more NextToken objects, strings that specifies where + to paginate the returned records represented by CaseDetails . + + :type case_id_list: list + :param case_id_list: + + :type display_id: string + :param display_id: + + :type after_time: string + :param after_time: + + :type before_time: string + :param before_time: + + :type include_resolved_cases: boolean + :param include_resolved_cases: + + :type next_token: string + :param next_token: + + :type max_results: integer + :param max_results: + + :type language: string + :param language: + + """ + params = {} + if case_id_list is not None: + params['caseIdList'] = case_id_list + if display_id is not None: + params['displayId'] = display_id + if after_time is not None: + params['afterTime'] = after_time + if before_time is not None: + params['beforeTime'] = before_time + if include_resolved_cases is not None: + params['includeResolvedCases'] = include_resolved_cases + if next_token is not None: + params['nextToken'] = next_token + if max_results is not None: + params['maxResults'] = max_results + if language is not None: + params['language'] = language + return self.make_request(action='DescribeCases', + body=json.dumps(params)) + + def describe_communications(self, case_id, before_time=None, + after_time=None, next_token=None, + max_results=None): + """ + This action returns communications regarding the support case. + You can use the AfterTime and BeforeTime parameters to filter + by date. The CaseId parameter enables you to identify a + specific case by its CaseId number. + + The MaxResults and NextToken parameters enable you to control + the pagination of the result set. Set MaxResults to the number + of cases you want displayed on each page, and use NextToken to + specify the resumption of pagination. + + :type case_id: string + :param case_id: + + :type before_time: string + :param before_time: + + :type after_time: string + :param after_time: + + :type next_token: string + :param next_token: + + :type max_results: integer + :param max_results: + + """ + params = {'caseId': case_id, } + if before_time is not None: + params['beforeTime'] = before_time + if after_time is not None: + params['afterTime'] = after_time + if next_token is not None: + params['nextToken'] = next_token + if max_results is not None: + params['maxResults'] = max_results + return self.make_request(action='DescribeCommunications', + body=json.dumps(params)) + + def describe_services(self, service_code_list=None, language=None): + """ + Returns the current list of AWS services and a list of service + categories that applies to each one. You then use service + names and categories in your `CreateCase`_ requests. Each AWS + service has its own set of categories. + + The service codes and category codes correspond to the values + that are displayed in the **Service** and **Category** drop- + down lists on the AWS Support Center `Open a new case`_ page. + The values in those fields, however, do not necessarily match + the service codes and categories returned by the + `DescribeServices` request. Always use the service codes and + categories obtained programmatically. This practice ensures + that you always have the most recent set of service and + category codes. + + :type service_code_list: list + :param service_code_list: + + :type language: string + :param language: + + """ + params = {} + if service_code_list is not None: + params['serviceCodeList'] = service_code_list + if language is not None: + params['language'] = language + return self.make_request(action='DescribeServices', + body=json.dumps(params)) + + def describe_severity_levels(self, language=None): + """ + This action returns the list of severity levels that you can + assign to an AWS Support case. The severity level for a case + is also a field in the `CaseDetails`_ data type included in + any `CreateCase`_ request. + + :type language: string + :param language: + + """ + params = {} + if language is not None: + params['language'] = language + return self.make_request(action='DescribeSeverityLevels', + body=json.dumps(params)) + + def resolve_case(self, case_id=None): + """ + Takes a CaseId and returns the initial state of the case along + with the state of the case after the call to `ResolveCase`_ + completed. + + :type case_id: string + :param case_id: + + """ + params = {} + if case_id is not None: + params['caseId'] = case_id + return self.make_request(action='ResolveCase', + body=json.dumps(params)) + + def describe_trusted_advisor_check_refresh_statuses(self, check_ids): + """ + Returns the status of all refresh requests Trusted Advisor + checks called using `RefreshTrustedAdvisorCheck`_. + + :type check_ids: list + :param check_ids: + + """ + params = {'checkIds': check_ids, } + return self.make_request(action='DescribeTrustedAdvisorCheckRefreshStatuses', + body=json.dumps(params)) + + def describe_trusted_advisor_check_result(self, check_id, language=None): + """ + This action responds with the results of a Trusted Advisor + check. Once you have obtained the list of available Trusted + Advisor checks by calling `DescribeTrustedAdvisorChecks`_, you + specify the CheckId for the check you want to retrieve from + AWS Support. + + The response for this action contains a JSON-formatted + `TrustedAdvisorCheckResult`_ object + , which is a container for the following three objects: + + + + #. `TrustedAdvisorCategorySpecificSummary`_ + #. `TrustedAdvisorResourceDetail`_ + #. `TrustedAdvisorResourcesSummary`_ + + + In addition, the response contains the following fields: + + + #. **Status**. Overall status of the check. + #. **Timestamp**. Time at which Trusted Advisor last ran the + check. + #. **CheckId**. Unique identifier for the specific check + returned by the request. + + :type check_id: string + :param check_id: + + :type language: string + :param language: + + """ + params = {'checkId': check_id, } + if language is not None: + params['language'] = language + return self.make_request(action='DescribeTrustedAdvisorCheckResult', + body=json.dumps(params)) + + def describe_trusted_advisor_check_summaries(self, check_ids): + """ + This action enables you to get the latest summaries for + Trusted Advisor checks that you specify in your request. You + submit the list of Trusted Advisor checks for which you want + summaries. You obtain these CheckIds by submitting a + `DescribeTrustedAdvisorChecks`_ request. + + The response body contains an array of + `TrustedAdvisorCheckSummary`_ objects. + + :type check_ids: list + :param check_ids: + + """ + params = {'checkIds': check_ids, } + return self.make_request(action='DescribeTrustedAdvisorCheckSummaries', + body=json.dumps(params)) + + def describe_trusted_advisor_checks(self, language): + """ + This action enables you to get a list of the available Trusted + Advisor checks. You must specify a language code. English + ("en") and Japanese ("jp") are currently supported. The + response contains a list of `TrustedAdvisorCheckDescription`_ + objects. + + :type language: string + :param language: + + """ + params = {'language': language, } + return self.make_request(action='DescribeTrustedAdvisorChecks', + body=json.dumps(params)) + + def refresh_trusted_advisor_check(self, check_id): + """ + This action enables you to query the service to request a + refresh for a specific Trusted Advisor check. Your request + body contains a CheckId for which you are querying. The + response body contains a `RefreshTrustedAdvisorCheckResult`_ + object containing Status and TimeUntilNextRefresh fields. + + :type check_id: string + :param check_id: + + """ + params = {'checkId': check_id, } + return self.make_request(action='RefreshTrustedAdvisorCheck', + body=json.dumps(params)) + + def make_request(self, action, body): + headers = { + 'X-Amz-Target': '%s.%s' % (self.TargetPrefix, action), + 'Host': self.region.endpoint, + 'Content-Type': 'application/x-amz-json-1.1', + 'Content-Length': str(len(body)), + } + http_request = self.build_base_http_request( + method='POST', path='/', auth_path='/', params={}, + headers=headers, data=body) + response = self._mexe(http_request, sender=None, + override_num_retries=10) + response_body = response.read() + boto.log.debug(response_body) + if response.status == 200: + if response_body: + return json.loads(response_body) + else: + json_body = json.loads(response_body) + fault_name = json_body.get('__type', None) + exception_class = self._faults.get(fault_name, self.ResponseError) + raise exception_class(response.status, response.reason, + body=json_body) + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto.egg-info/PKG-INFO new/boto-2.9.2/boto.egg-info/PKG-INFO --- old/boto-2.9.0/boto.egg-info/PKG-INFO 2013-04-18 13:42:12.000000000 +0200 +++ new/boto-2.9.2/boto.egg-info/PKG-INFO 2013-05-01 03:30:28.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: boto -Version: 2.9.0 +Version: 2.9.2 Summary: Amazon Web Services Library Home-page: https://github.com/boto/boto/ Author: Mitch Garnaat @@ -9,8 +9,8 @@ Description: #### boto #### - boto 2.8.0 - 31-Jan-2013 + boto 2.9.2 + 30-Apr-2013 .. image:: https://secure.travis-ci.org/boto/boto.png?branch=develop :target: https://secure.travis-ci.org/boto/boto diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/boto.egg-info/SOURCES.txt new/boto-2.9.2/boto.egg-info/SOURCES.txt --- old/boto-2.9.0/boto.egg-info/SOURCES.txt 2013-04-18 13:42:13.000000000 +0200 +++ new/boto-2.9.2/boto.egg-info/SOURCES.txt 2013-05-01 03:30:28.000000000 +0200 @@ -310,6 +310,9 @@ boto/sts/__init__.py boto/sts/connection.py boto/sts/credentials.py +boto/support/__init__.py +boto/support/exceptions.py +boto/support/layer1.py boto/swf/__init__.py boto/swf/exceptions.py boto/swf/layer1.py @@ -347,6 +350,7 @@ docs/source/ses_tut.rst docs/source/simpledb_tut.rst docs/source/sqs_tut.rst +docs/source/support_tut.rst docs/source/vpc_tut.rst docs/source/_templates/layout.html docs/source/boto_theme/theme.conf @@ -390,8 +394,10 @@ docs/source/ref/sns.rst docs/source/ref/sqs.rst docs/source/ref/sts.rst +docs/source/ref/support.rst docs/source/ref/swf.rst docs/source/ref/vpc.rst +docs/source/releasenotes/v2.9.1.rst tests/__init__.py tests/test.py tests/db/test_lists.py @@ -498,6 +504,9 @@ tests/integration/sts/__init__.py tests/integration/sts/test_cert_verification.py tests/integration/sts/test_session_token.py +tests/integration/support/__init__.py +tests/integration/support/test_cert_verification.py +tests/integration/support/test_layer1.py tests/integration/swf/__init__.py tests/integration/swf/test_cert_verification.py tests/integration/swf/test_layer1.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/docs/source/autoscale_tut.rst new/boto-2.9.2/docs/source/autoscale_tut.rst --- old/boto-2.9.0/docs/source/autoscale_tut.rst 2013-04-18 13:18:22.000000000 +0200 +++ new/boto-2.9.2/docs/source/autoscale_tut.rst 2013-05-01 02:40:31.000000000 +0200 @@ -202,7 +202,7 @@
conn.get_all_groups(names=['my_group'])[0] instance_ids = [i.instance_id for i in group.instances] reservations = ec2.get_all_instances(instance_ids) ->>> instances = [i for i in reservations for i in r.instances] +>>> instances = [i for r in reservations for i in r.instances]
To delete your autoscale group, we first need to shutdown all the
instances:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/boto-2.9.0/docs/source/index.rst new/boto-2.9.2/docs/source/index.rst
--- old/boto-2.9.0/docs/source/index.rst 2013-04-18 13:39:58.000000000 +0200
+++ new/boto-2.9.2/docs/source/index.rst 2013-05-01 03:17:04.000000000 +0200
@@ -85,6 +85,7 @@
* **Other**
* Marketplace Web Services -- (:doc:`API Reference `)
+ * :doc:`Support