summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lindsley <daniel@toastdriven.com>2013-05-28 21:31:56 -0700
committerDaniel Lindsley <daniel@toastdriven.com>2013-05-28 21:31:56 -0700
commitc6118201920858c18a7fe6a8a86b4f418f4ce78d (patch)
tree94cc206768bdaef174e4381ddcaf3c5754d7ae15
parent9bffa78496b63f54ddb22460af570f6f1e69c9f9 (diff)
parentf21e933278dead47af617792733b2b1480b526c9 (diff)
downloadboto-c6118201920858c18a7fe6a8a86b4f418f4ce78d.tar.gz
Merge branch 'release-2.9.5'2.9.5
* release-2.9.5: Bumping version to 2.9.5 Updated release notes. Fixed a bug where an instance variable was not present in the low-level DynamoDB client. Added release notes for v2.9.5. Fixed headers in EC2 autodocs. Added support for web identity federation. Updated tests to accommodate the changes to ``_build_filters``. Solving bugs on empty results and between comparisions Added a failing test for no results to DDBv2. Added tests for the EBS Optimized change. Modifiy EbsOptimized param type in LauchConfig. Fix unit test Added tests for the dynamodb2 region fix. Fix a bug always connecting to the default end point in dynamodb2's DynamoDBConnecting Update release notes to use the new sphinx roles Add sphinx extension for linking to github Make s3 key buffer size configurable.
-rw-r--r--README.rst4
-rw-r--r--boto/__init__.py2
-rw-r--r--boto/dynamodb2/layer1.py7
-rw-r--r--boto/dynamodb2/results.py5
-rw-r--r--boto/dynamodb2/table.py20
-rw-r--r--boto/ec2/autoscale/__init__.py4
-rw-r--r--boto/s3/key.py2
-rw-r--r--boto/sts/connection.py304
-rw-r--r--docs/source/conf.py9
-rw-r--r--docs/source/extensions/githublinks/__init__.py55
-rw-r--r--docs/source/index.rst2
-rw-r--r--docs/source/ref/ec2.rst16
-rw-r--r--docs/source/releasenotes/v2.9.1.rst18
-rw-r--r--docs/source/releasenotes/v2.9.2.rst2
-rw-r--r--docs/source/releasenotes/v2.9.3.rst34
-rw-r--r--docs/source/releasenotes/v2.9.4.rst12
-rw-r--r--docs/source/releasenotes/v2.9.5.rst32
-rw-r--r--tests/integration/dynamodb2/test_layer1.py36
-rw-r--r--tests/integration/ec2/autoscale/test_connection.py15
-rw-r--r--tests/integration/sts/test_session_token.py16
-rw-r--r--tests/unit/dynamodb2/test_layer1.py45
-rw-r--r--tests/unit/dynamodb2/test_table.py32
22 files changed, 565 insertions, 107 deletions
diff --git a/README.rst b/README.rst
index c5904b48..77c64aa5 100644
--- a/README.rst
+++ b/README.rst
@@ -1,9 +1,9 @@
####
boto
####
-boto 2.9.4
+boto 2.9.5
-Released: 20-May-2013
+Released: 28-May-2013
.. image:: https://travis-ci.org/boto/boto.png?branch=develop
:target: https://travis-ci.org/boto/boto
diff --git a/boto/__init__.py b/boto/__init__.py
index 45ae1d04..21666707 100644
--- a/boto/__init__.py
+++ b/boto/__init__.py
@@ -36,7 +36,7 @@ import logging.config
import urlparse
from boto.exception import InvalidUriError
-__version__ = '2.9.4'
+__version__ = '2.9.5'
Version = __version__ # for backware compatibility
UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform)
diff --git a/boto/dynamodb2/layer1.py b/boto/dynamodb2/layer1.py
index e30d4991..532e2f6e 100644
--- a/boto/dynamodb2/layer1.py
+++ b/boto/dynamodb2/layer1.py
@@ -63,13 +63,16 @@ class DynamoDBConnection(AWSQueryConnection):
if not region:
region_name = boto.config.get('DynamoDB', 'region',
self.DefaultRegionName)
- region = RegionInfo(self, region_name,
- self.DefaultRegionEndpoint)
+ for reg in boto.dynamodb2.regions():
+ if reg.name == region_name:
+ region = reg
+ break
kwargs['host'] = region.endpoint
AWSQueryConnection.__init__(self, **kwargs)
self.region = region
self._validate_checksums = boto.config.getbool(
'DynamoDB', 'validate_checksums', validate_checksums)
+ self.throughput_exceeded_events = 0
def _required_auth_capability(self):
return ['hmac-v4']
diff --git a/boto/dynamodb2/results.py b/boto/dynamodb2/results.py
index ac6851ca..bcd855c3 100644
--- a/boto/dynamodb2/results.py
+++ b/boto/dynamodb2/results.py
@@ -58,7 +58,10 @@ class ResultSet(object):
self.fetch_more()
- return self._results[self._offset]
+ if self._offset < len(self._results):
+ return self._results[self._offset]
+ else:
+ raise StopIteration()
def to_call(self, the_callable, *args, **kwargs):
"""
diff --git a/boto/dynamodb2/table.py b/boto/dynamodb2/table.py
index 3b4d848d..36f918ed 100644
--- a/boto/dynamodb2/table.py
+++ b/boto/dynamodb2/table.py
@@ -611,12 +611,7 @@ class Table(object):
'AttributeValueList': [],
'ComparisonOperator': op,
}
-
- # Fix up the value for encoding, because it was built to only work
- # with ``set``s.
- if isinstance(value, (list, tuple)):
- value = set(value)
-
+
# Special-case the ``NULL/NOT_NULL`` case.
if field_bits[-1] == 'null':
del lookup['AttributeValueList']
@@ -625,7 +620,20 @@ class Table(object):
lookup['ComparisonOperator'] = 'NOT_NULL'
else:
lookup['ComparisonOperator'] = 'NULL'
+ # Special-case the ``BETWEEN`` case.
+ elif field_bits[-1] == 'between':
+ if len(value) == 2 and isinstance(value, (list, tuple)):
+ lookup['AttributeValueList'].append(
+ self._dynamizer.encode(value[0])
+ )
+ lookup['AttributeValueList'].append(
+ self._dynamizer.encode(value[1])
+ )
else:
+ # Fix up the value for encoding, because it was built to only work
+ # with ``set``s.
+ if isinstance(value, (list, tuple)):
+ value = set(value)
lookup['AttributeValueList'].append(
self._dynamizer.encode(value)
)
diff --git a/boto/ec2/autoscale/__init__.py b/boto/ec2/autoscale/__init__.py
index fab5accc..277c26db 100644
--- a/boto/ec2/autoscale/__init__.py
+++ b/boto/ec2/autoscale/__init__.py
@@ -238,9 +238,9 @@ class AutoScaleConnection(AWSQueryConnection):
if launch_config.instance_profile_name is not None:
params['IamInstanceProfile'] = launch_config.instance_profile_name
if launch_config.ebs_optimized:
- params['EbsOptimized'] = True
+ params['EbsOptimized'] = 'true'
else:
- params['EbsOptimized'] = False
+ params['EbsOptimized'] = 'false'
return self.get_object('CreateLaunchConfiguration', params,
Request, verb='POST')
diff --git a/boto/s3/key.py b/boto/s3/key.py
index 2fceb64d..327feae3 100644
--- a/boto/s3/key.py
+++ b/boto/s3/key.py
@@ -82,7 +82,7 @@ class Key(object):
</RestoreRequest>"""
- BufferSize = 8192
+ BufferSize = boto.config.getint('Boto', 'key_buffer_size', 8192)
# The object metadata fields a user can set, other than custom metadata
# fields (i.e., those beginning with a provider-specific prefix like
diff --git a/boto/sts/connection.py b/boto/sts/connection.py
index 49e04c29..5a1fdf2c 100644
--- a/boto/sts/connection.py
+++ b/boto/sts/connection.py
@@ -32,7 +32,33 @@ _session_token_cache = {}
class STSConnection(AWSQueryConnection):
+ """
+ AWS Security Token Service
+ The AWS Security Token Service is a web service that enables you
+ to request temporary, limited-privilege credentials for AWS
+ Identity and Access Management (IAM) users or for users that you
+ authenticate (federated users). This guide provides descriptions
+ of the AWS Security Token Service API.
+ For more detailed information about using this service, go to
+ `Using Temporary Security Credentials`_.
+
+ For information about setting up signatures and authorization
+ through the API, go to `Signing AWS API Requests`_ in the AWS
+ General Reference . For general information about the Query API,
+ go to `Making Query Requests`_ in Using IAM . For information
+ about using security tokens with other AWS products, go to `Using
+ Temporary Security Credentials to Access AWS`_ in Using Temporary
+ Security Credentials .
+
+ If you're new to AWS and need additional technical information
+ about a specific AWS product, you can find the product's technical
+ documentation at `http://aws.amazon.com/documentation/`_.
+
+ We will refer to Amazon Identity and Access Management using the
+ abbreviated form IAM. All copyrights and legal protections still
+ apply.
+ """
DefaultRegionName = 'us-east-1'
DefaultRegionEndpoint = 'sts.amazonaws.com'
APIVersion = '2011-06-15'
@@ -133,16 +159,65 @@ class STSConnection(AWSQueryConnection):
def get_federation_token(self, name, duration=None, policy=None):
"""
- :type name: str
- :param name: The name of the Federated user associated with
- the credentials.
+ Returns a set of temporary security credentials (consisting of
+ an access key ID, a secret access key, and a security token)
+ for a federated user. A typical use is in a proxy application
+ that is getting temporary security credentials on behalf of
+ distributed applications inside a corporate network. Because
+ you must call the `GetFederationToken` action using the long-
+ term security credentials of an IAM user, this call is
+ appropriate in contexts where those credentials can be safely
+ stored, usually in a server-based application.
- :type duration: int
- :param duration: The number of seconds the credentials should
- remain valid.
+ **Note:** Do not use this call in mobile applications or
+ client-based web applications that directly get temporary
+ security credentials. For those types of applications, use
+ `AssumeRoleWithWebIdentity`.
+
+ The `GetFederationToken` action must be called by using the
+ long-term AWS security credentials of the AWS account or an
+ IAM user. Credentials that are created by IAM users are valid
+ for the specified duration, between 900 seconds (15 minutes)
+ and 129600 seconds (36 hours); credentials that are created by
+ using account credentials have a maximum duration of 3600
+ seconds (1 hour).
- :type policy: str
- :param policy: A JSON policy to associate with these credentials.
+ The permissions that are granted to the federated user are the
+ intersection of the policy that is passed with the
+ `GetFederationToken` request and policies that are associated
+ with of the entity making the `GetFederationToken` call.
+
+ For more information about how permissions work, see
+ `Controlling Permissions in Temporary Credentials`_ in Using
+ Temporary Security Credentials . For information about using
+ `GetFederationToken` to create temporary security credentials,
+ see `Creating Temporary Credentials to Enable Access for
+ Federated Users`_ in Using Temporary Security Credentials .
+
+ :type name: string
+ :param name: The name of the federated user. The name is used as an
+ identifier for the temporary security credentials (such as `Bob`).
+ For example, you can reference the federated user name in a
+ resource-based policy, such as in an Amazon S3 bucket policy.
+
+ :type policy: string
+ :param policy: A policy that specifies the permissions that are granted
+ to the federated user. By default, federated users have no
+ permissions; they do not inherit any from the IAM user. When you
+ specify a policy, the federated user's permissions are intersection
+ of the specified policy and the IAM user's policy. If you don't
+ specify a policy, federated users can only access AWS resources
+ that explicitly allow those federated users in a resource policy,
+ such as in an Amazon S3 bucket policy.
+
+ :type duration: integer
+ :param duration: The duration, in seconds, that the session
+ should last. Acceptable durations for federation sessions range
+ from 900 seconds (15 minutes) to 129600 seconds (36 hours), with
+ 43200 seconds (12 hours) as the default. Sessions for AWS account
+ owners are restricted to a maximum of 3600 seconds (one hour). If
+ the duration is longer than one hour, the session for AWS account
+ owners defaults to one hour.
"""
params = {'Name': name}
@@ -156,42 +231,93 @@ class STSConnection(AWSQueryConnection):
def assume_role(self, role_arn, role_session_name, policy=None,
duration_seconds=None, external_id=None):
"""
- Returns a set of temporary credentials that the caller can use to
- access resources that are allowed by the temporary credentials. The
- credentials are valid for the duration that the caller specified, which
- can be from 15 minutes (900 seconds) to 1 hour (3600 seconds)
+ Returns a set of temporary security credentials (consisting of
+ an access key ID, a secret access key, and a security token)
+ that you can use to access AWS resources that you might not
+ normally have access to. Typically, you use `AssumeRole` for
+ cross-account access or federation.
+
+ For cross-account access, imagine that you own multiple
+ accounts and need to access resources in each account. You
+ could create long-term credentials in each account to access
+ those resources. However, managing all those credentials and
+ remembering which one can access which account can be time
+ consuming. Instead, you can create one set of long-term
+ credentials in one account and then use temporary security
+ credentials to access all the other accounts by assuming roles
+ in those accounts. For more information about roles, see
+ `Roles`_ in Using IAM .
- :type role_arn: str
+ For federation, you can, for example, grant single sign-on
+ access to the AWS Management Console. If you already have an
+ identity and authentication system in your corporate network,
+ you don't have to recreate user identities in AWS in order to
+ grant those user identities access to AWS. Instead, after a
+ user has been authenticated, you call `AssumeRole` (and
+ specify the role with the appropriate permissions) to get
+ temporary security credentials for that user. With those
+ temporary security credentials, you construct a sign-in URL
+ that users can use to access the console. For more
+ information, see `Scenarios for Granting Temporary Access`_ in
+ AWS Security Token Service .
+
+ The temporary security credentials are valid for the duration
+ that you specified when calling `AssumeRole`, which can be
+ from 900 seconds (15 minutes) to 3600 seconds (1 hour). The
+ default is 1 hour.
+
+ The temporary security credentials that are returned from the
+ `AssumeRoleWithWebIdentity` response have the permissions that
+ are associated with the access policy of the role being
+ assumed and any policies that are associated with the AWS
+ resource being accessed. You can further restrict the
+ permissions of the temporary security credentials by passing a
+ policy in the request. The resulting permissions are an
+ intersection of the role's access policy and the policy that
+ you passed. These policies and any applicable resource-based
+ policies are evaluated when calls to AWS service APIs are made
+ using the temporary security credentials.
+
+ To assume a role, your AWS account must be trusted by the
+ role. The trust relationship is defined in the role's trust
+ policy when the IAM role is created. You must also have a
+ policy that allows you to call `sts:AssumeRole`.
+
+ **Important:** You cannot call `Assumerole` by using AWS
+ account credentials; access will be denied. You must use IAM
+ user credentials to call `AssumeRole`.
+
+ :type role_arn: string
:param role_arn: The Amazon Resource Name (ARN) of the role that the
caller is assuming.
- :type role_session_name: str
- :param role_session_name: The session name of the temporary security
- credentials. The session name is part of the AssumedRoleUser.
+ :type role_session_name: string
+ :param role_session_name: An identifier for the assumed role session.
+ The session name is included as part of the `AssumedRoleUser`.
- :type policy: str
- :param policy: A supplemental policy that can be associated with the
- temporary security credentials. The caller can limit the
- permissions that are available on the role's temporary security
- credentials to maintain the least amount of privileges. When a
- service call is made with the temporary security credentials, both
- policies (the role policy and supplemental policy) are checked.
+ :type policy: string
+ :param policy: A supplemental policy that is associated with the
+ temporary security credentials from the `AssumeRole` call. The
+ resulting permissions of the temporary security credentials are an
+ intersection of this policy and the access policy that is
+ associated with the role. Use this policy to further restrict the
+ permissions of the temporary security credentials.
-
- :type duration_seconds: int
- :param duration_seconds: he duration, in seconds, of the role session.
+ :type duration_seconds: integer
+ :param duration_seconds: The duration, in seconds, of the role session.
The value can range from 900 seconds (15 minutes) to 3600 seconds
- (1 hour). By default, the value is set to 3600 seconds.
-
- :type external_id: str
- :param external_id: A unique identifier that is used by
- third-party services to ensure that they are assuming a role that
- corresponds to the correct users. For third-party services that
- have access to resources across multiple AWS accounts, the unique
- client ID helps third-party services simplify access control
- verification.
+ (1 hour). By default, the value is set to 3600 seconds.
- :return: An instance of :class:`boto.sts.credentials.AssumedRole`
+ :type external_id: string
+ :param external_id: A unique identifier that is used by third parties
+ to assume a role in their customers' accounts. For each role that
+ the third party can assume, they should instruct their customers to
+ create a role with the external ID that the third party generated.
+ Each time the third party assumes the role, they must pass the
+ customer's external ID. The external ID is useful in order to help
+ third parties bind a role to the customer who created it. For more
+ information about the external ID, see `About the External ID`_ in
+ Using Temporary Security Credentials .
"""
params = {
@@ -205,3 +331,109 @@ class STSConnection(AWSQueryConnection):
if external_id is not None:
params['ExternalId'] = external_id
return self.get_object('AssumeRole', params, AssumedRole, verb='POST')
+
+ def assume_role_with_web_identity(self, role_arn, role_session_name,
+ web_identity_token, provider_id=None,
+ policy=None, duration_seconds=None):
+ """
+ Returns a set of temporary security credentials for users who
+ have been authenticated in a mobile or web application with a
+ web identity provider, such as Login with Amazon, Facebook, or
+ Google. `AssumeRoleWithWebIdentity` is an API call that does
+ not require the use of AWS security credentials. Therefore,
+ you can distribute an application (for example, on mobile
+ devices) that requests temporary security credentials without
+ including long-term AWS credentials in the application or by
+ deploying server-based proxy services that use long-term AWS
+ credentials. For more information, see `Creating a Mobile
+ Application with Third-Party Sign-In`_ in AWS Security Token
+ Service .
+
+ The temporary security credentials consist of an access key
+ ID, a secret access key, and a security token. Applications
+ can use these temporary security credentials to sign calls to
+ AWS service APIs. The credentials are valid for the duration
+ that you specified when calling `AssumeRoleWithWebIdentity`,
+ which can be from 900 seconds (15 minutes) to 3600 seconds (1
+ hour). By default, the temporary security credentials are
+ valid for 1 hour.
+
+ The temporary security credentials that are returned from the
+ `AssumeRoleWithWebIdentity` response have the permissions that
+ are associated with the access policy of the role being
+ assumed. You can further restrict the permissions of the
+ temporary security credentials by passing a policy in the
+ request. The resulting permissions are an intersection of the
+ role's access policy and the policy that you passed. These
+ policies and any applicable resource-based policies are
+ evaluated when calls to AWS service APIs are made using the
+ temporary security credentials.
+
+ Before your application can call `AssumeRoleWithWebIdentity`,
+ you must have an identity token from a supported identity
+ provider and create a role that the application can assume.
+ The role that your application assumes must trust the identity
+ provider that is associated with the identity token. In other
+ words, the identity provider must be specified in the role's
+ trust policy. For more information, see ` Creating Temporary
+ Security Credentials for Mobile Apps Using Third-Party
+ Identity Providers`_.
+
+ :type role_arn: string
+ :param role_arn: The Amazon Resource Name (ARN) of the role that the
+ caller is assuming.
+
+ :type role_session_name: string
+ :param role_session_name: An identifier for the assumed role session.
+ Typically, you pass the name or identifier that is associated with
+ the user who is using your application. That way, the temporary
+ security credentials that your application will use are associated
+ with that user. This session name is included as part of the ARN
+ and assumed role ID in the `AssumedRoleUser` response element.
+
+ :type web_identity_token: string
+ :param web_identity_token: The OAuth 2.0 access token or OpenID Connect
+ ID token that is provided by the identity provider. Your
+ application must get this token by authenticating the user who is
+ using your application with a web identity provider before the
+ application makes an `AssumeRoleWithWebIdentity` call.
+
+ :type provider_id: string
+ :param provider_id: Specify this value only for OAuth access tokens. Do
+ not specify this value for OpenID Connect ID tokens, such as
+ `accounts.google.com`. This is the fully-qualified host component
+ of the domain name of the identity provider. Do not include URL
+ schemes and port numbers. Currently, `www.amazon.com` and
+ `graph.facebook.com` are supported.
+
+ :type policy: string
+ :param policy: A supplemental policy that is associated with the
+ temporary security credentials from the `AssumeRoleWithWebIdentity`
+ call. The resulting permissions of the temporary security
+ credentials are an intersection of this policy and the access
+ policy that is associated with the role. Use this policy to further
+ restrict the permissions of the temporary security credentials.
+
+ :type duration_seconds: integer
+ :param duration_seconds: The duration, in seconds, of the role session.
+ The value can range from 900 seconds (15 minutes) to 3600 seconds
+ (1 hour). By default, the value is set to 3600 seconds.
+
+ """
+ params = {
+ 'RoleArn': role_arn,
+ 'RoleSessionName': role_session_name,
+ 'WebIdentityToken': web_identity_token,
+ }
+ if provider_id is not None:
+ params['ProviderId'] = provider_id
+ if policy is not None:
+ params['Policy'] = policy
+ if duration_seconds is not None:
+ params['DurationSeconds'] = duration_seconds
+ return self.get_object(
+ 'AssumeRoleWithWebIdentity',
+ params,
+ AssumedRole,
+ verb='POST'
+ )
diff --git a/docs/source/conf.py b/docs/source/conf.py
index fa1d0c24..4fbbf3fc 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -2,9 +2,13 @@
import os
import boto
+import sys
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo']
-autoclass_content="both"
+sys.path.append(os.path.join(os.path.dirname(__file__), 'extensions'))
+
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo',
+ 'githublinks']
+autoclass_content = "both"
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
@@ -22,6 +26,7 @@ latex_documents = [
u'Mitch Garnaat', 'manual'),
]
intersphinx_mapping = {'http://docs.python.org/': None}
+github_project_url = 'https://github.com/boto/boto/'
try:
release = os.environ.get('SVN_REVISION', 'HEAD')
diff --git a/docs/source/extensions/githublinks/__init__.py b/docs/source/extensions/githublinks/__init__.py
new file mode 100644
index 00000000..9641a83d
--- /dev/null
+++ b/docs/source/extensions/githublinks/__init__.py
@@ -0,0 +1,55 @@
+"""Add github roles to sphinx docs.
+
+Based entirely on Doug Hellmann's bitbucket version, but
+adapted for Github.
+(https://bitbucket.org/dhellmann/sphinxcontrib-bitbucket/)
+
+"""
+from urlparse import urljoin
+
+from docutils import nodes, utils
+from docutils.parsers.rst.roles import set_classes
+
+
+def make_node(rawtext, app, type_, slug, options):
+ base_url = app.config.github_project_url
+ if base_url is None:
+ raise ValueError(
+ "Configuration value for 'github_project_url' is not set.")
+ relative = '%s/%s' % (type_, slug)
+ full_ref = urljoin(base_url, relative)
+ set_classes(options)
+ if type_ == 'issues':
+ type_ = 'issue'
+ node = nodes.reference(rawtext, type_ + ' ' + utils.unescape(slug),
+ refuri=full_ref, **options)
+ return node
+
+
+def github_sha(name, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ app = inliner.document.settings.env.app
+ node = make_node(rawtext, app, 'commit', text, options)
+ return [node], []
+
+
+def github_issue(name, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ try:
+ issue = int(text)
+ except ValueError:
+ msg = inliner.reporter.error(
+ "Invalid Github Issue '%s', must be an integer" % text,
+ line=lineno)
+ problem = inliner.problematic(rawtext, rawtext, msg)
+ return [problem], [msg]
+ app = inliner.document.settings.env.app
+ node = make_node(rawtext, app, 'issues', str(issue), options)
+ return [node], []
+
+
+def setup(app):
+ app.info('Adding github link roles')
+ app.add_role('sha', github_sha)
+ app.add_role('issue', github_issue)
+ app.add_config_value('github_project_url', None, 'env')
diff --git a/docs/source/index.rst b/docs/source/index.rst
index f9facc97..252f14a6 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -111,6 +111,8 @@ Release Notes
.. toctree::
:titlesonly:
+ releasenotes/v2.9.5
+ releasenotes/v2.9.4
releasenotes/v2.9.3
releasenotes/v2.9.2
releasenotes/v2.9.1
diff --git a/docs/source/ref/ec2.rst b/docs/source/ref/ec2.rst
index db98293c..3d06fa8c 100644
--- a/docs/source/ref/ec2.rst
+++ b/docs/source/ref/ec2.rst
@@ -57,12 +57,12 @@ boto.ec2.ec2object
:undoc-members:
boto.ec2.elb
--------------------
+------------
See the :doc:`ELB Reference <elb>`.
boto.ec2.group
-----------------
+--------------
.. automodule:: boto.ec2.group
:members:
@@ -90,7 +90,7 @@ boto.ec2.instanceinfo
:undoc-members:
boto.ec2.instancestatus
---------------------------
+-----------------------
.. automodule:: boto.ec2.instancestatus
:members:
@@ -104,21 +104,21 @@ boto.ec2.keypair
:undoc-members:
boto.ec2.launchspecification
-----------------
+----------------------------
.. automodule:: boto.ec2.launchspecification
:members:
:undoc-members:
boto.ec2.networkinterface
-----------------
+-------------------------
.. automodule:: boto.ec2.networkinterface
:members:
:undoc-members:
boto.ec2.placementgroup
-----------------
+-----------------------
.. automodule:: boto.ec2.placementgroup
:members:
@@ -160,14 +160,14 @@ boto.ec2.spotinstancerequest
:undoc-members:
boto.ec2.tag
-----------------------------
+------------
.. automodule:: boto.ec2.tag
:members:
:undoc-members:
boto.ec2.vmtype
-----------------------------
+---------------
.. automodule:: boto.ec2.vmtype
:members:
diff --git a/docs/source/releasenotes/v2.9.1.rst b/docs/source/releasenotes/v2.9.1.rst
index 217500cd..488730ef 100644
--- a/docs/source/releasenotes/v2.9.1.rst
+++ b/docs/source/releasenotes/v2.9.1.rst
@@ -27,22 +27,22 @@ Features
u'case-...'
The :ref:`Support Tutorial <support_tut>` has more information on how to use
- the new API. (SHA: 8c0451)
+ the new API. (:sha:`8c0451`)
Bugfixes
--------
* The reintroduction of ``ResumableUploadHandler.get_upload_id`` that was
- accidentally removed in a previous commit. (SHA: 758322)
+ accidentally removed in a previous commit. (:sha:`758322`)
* Added ``OrdinaryCallingFormat`` to support Google Storage's certificate
- verification. (SHA: 4ca83b)
-* Added the ``eu-west-1`` region for Redshift. (SHA: e98b95)
+ verification. (:sha:`4ca83b`)
+* Added the ``eu-west-1`` region for Redshift. (:sha:`e98b95`)
* Added support for overriding the port any connection in ``boto`` uses.
- (SHA: 08e893)
-* Added retry/checksumming support to the DynamoDB v2 client. (SHA: 969ae2)
+ (:sha:`08e893`)
+* Added retry/checksumming support to the DynamoDB v2 client. (:sha:`969ae2`)
* Several documentation improvements/fixes:
- * Incorrect docs on EC2's ``import_key_pair``. (SHA: 6ada7d)
- * Clearer docs on the DynamoDB ``count`` parameter. (SHA: dfa456)
- * Fixed a typo in the ``autoscale_tut``. (SHA: 6df1ae)
+ * Incorrect docs on EC2's ``import_key_pair``. (:sha:`6ada7d`)
+ * Clearer docs on the DynamoDB ``count`` parameter. (:sha:`dfa456`)
+ * Fixed a typo in the ``autoscale_tut``. (:sha:`6df1ae`)
diff --git a/docs/source/releasenotes/v2.9.2.rst b/docs/source/releasenotes/v2.9.2.rst
index f2848e34..0e9994ae 100644
--- a/docs/source/releasenotes/v2.9.2.rst
+++ b/docs/source/releasenotes/v2.9.2.rst
@@ -15,4 +15,4 @@ Features
Bugfixes
--------
-* Fixed the missing ``boto.support`` in ``setup.py``. (SHA: 9ac196)
+* Fixed the missing ``boto.support`` in ``setup.py``. (:sha:`9ac196`)
diff --git a/docs/source/releasenotes/v2.9.3.rst b/docs/source/releasenotes/v2.9.3.rst
index a8323371..1835862a 100644
--- a/docs/source/releasenotes/v2.9.3.rst
+++ b/docs/source/releasenotes/v2.9.3.rst
@@ -12,16 +12,16 @@ Features
--------
* ELB support in Opsworks - You can now attach & describe the Elastic Load
- Balancers within the Opsworks client. (SHA: ecda87)
+ Balancers within the Opsworks client. (:sha:`ecda87`)
* Optimized EBS support in EC2 AutoScale - You can now specify whether an
- AutoScale instance should be optimized for EBS I/O. (SHA: f8acaa)
+ AutoScale instance should be optimized for EBS I/O. (:sha:`f8acaa`)
* Parallel Scan support in DynamoDB v2 - If you have extra read capacity &
a large amount of data, you can scan over the records in parallel by
telling DynamoDB to split the table into segments, then spinning up
- threads/processes to each run over their own segment. (SHA: db7f7b & 7ed73c)
+ threads/processes to each run over their own segment. (:sha:`db7f7b` & :sha:`7ed73c`)
* Higher-level interface to DynamoDB v2 - A more convenient API for using
DynamoDB v2. The :ref:`DynamoDB v2 Tutorial <dynamodb2_tut>` has more
- information on how to use the new API. (SHA: 0f7c8b)
+ information on how to use the new API. (:sha:`0f7c8b`)
Backward-Incompatible Changes
@@ -29,25 +29,25 @@ Backward-Incompatible Changes
* API Update for DataPipeline - The ``error_code`` (integer) argument to
``set_task_status`` changed to ``error_id`` (string). Many documentation
- updates were also added. (SHA: a78572)
+ updates were also added. (:sha:`a78572`)
Bugfixes
--------
-* Bumped the AWS Support API version. (SHA: 0323f4)
+* Bumped the AWS Support API version. (:sha:`0323f4`)
* Fixed the S3 ``ResumableDownloadHandler`` so that it no longer tries to use
- a hashing algorithm when used outside of GCS. (SHA: 29b046)
-* Fixed a bug where Sig V4 URIs were improperly canonicalized. (SHA: 5269d8)
-* Fixed a bug where Sig V4 ports were not included. (SHA: cfaba3)
+ a hashing algorithm when used outside of GCS. (:sha:`29b046`)
+* Fixed a bug where Sig V4 URIs were improperly canonicalized. (:sha:`5269d8`)
+* Fixed a bug where Sig V4 ports were not included. (:sha:`cfaba3`)
* Fixed a bug in CloudWatch's ``build_put_params`` that would overwrite
- existing/necessary variables. (SHA: 550e00)
+ existing/necessary variables. (:sha:`550e00`)
* Several documentation improvements/fixes:
- * Added docs for RDS ``modify/modify_dbinstance``. (SHA: 777d73)
- * Fixed a typo in the ``README.rst``. (SHA: 181e0f)
- * Documentation fallout from the previous release. (SHA: 14a111)
- * Fixed a typo in the EC2 ``Image.run`` docs. (SHA: 5edd6a)
- * Added/improved docs for EC2 ``Image.run``. (SHA: 773ce5)
- * Added a CONTRIBUTING doc. (SHA: cecbe8)
- * Fixed S3 ``create_bucket`` docs to specify "European Union". (SHA: ddddfd)
+ * Added docs for RDS ``modify/modify_dbinstance``. (:sha:`777d73`)
+ * Fixed a typo in the ``README.rst``. (:sha:`181e0f`)
+ * Documentation fallout from the previous release. (:sha:`14a111`)
+ * Fixed a typo in the EC2 ``Image.run`` docs. (:sha:`5edd6a`)
+ * Added/improved docs for EC2 ``Image.run``. (:sha:`773ce5`)
+ * Added a CONTRIBUTING doc. (:sha:`cecbe8`)
+ * Fixed S3 ``create_bucket`` docs to specify "European Union". (:sha:`ddddfd`)
diff --git a/docs/source/releasenotes/v2.9.4.rst b/docs/source/releasenotes/v2.9.4.rst
index 1956dbff..675afd45 100644
--- a/docs/source/releasenotes/v2.9.4.rst
+++ b/docs/source/releasenotes/v2.9.4.rst
@@ -11,7 +11,7 @@ Features
--------
* Updated Elastic Transcoder support - It now supports HLS, WebM, MPEG2-TS & a
- host of `other features`_. (SHA: 89196a)
+ host of `other features`_. (:sha:`89196a`)
.. _`other features`: http://aws.typepad.com/aws/2013/05/new-features-for-the-amazon-elastic-transcoder.html
@@ -19,12 +19,12 @@ Features
Bugfixes
--------
-* Fixed a bug in the canonicalization of URLs on Windows. (SHA: 09ef8c)
-* Fixed glacier part size bug (issue: 1478, SHA: 9e04171)
+* Fixed a bug in the canonicalization of URLs on Windows. (:sha:`09ef8c`)
+* Fixed glacier part size bug (:issue:`1478`, :sha:`9e04171`)
* Fixed a bug in the bucket regex for S3 involving capital letters.
- (SHA: 950031)
+ (:sha:`950031`)
* Fixed a bug where timestamps from Cloudformation would fail to be parsed.
- (SHA: b40542)
+ (:sha:`b40542`)
* Several documentation improvements/fixes:
- * Added autodocs for many of the EC2 apis. (SHA: 79f939)
+ * Added autodocs for many of the EC2 apis. (:sha:`79f939`)
diff --git a/docs/source/releasenotes/v2.9.5.rst b/docs/source/releasenotes/v2.9.5.rst
new file mode 100644
index 00000000..84d6d63b
--- /dev/null
+++ b/docs/source/releasenotes/v2.9.5.rst
@@ -0,0 +1,32 @@
+boto v2.9.5
+===========
+
+:date: 2013/05/28
+
+This release adds support for `web identity federation`_ within the Secure
+Token Service (STS) & fixes several bugs.
+
+.. _`web identity federation`: http://docs.aws.amazon.com/STS/latest/UsingSTS/CreatingWIF.html
+
+Features
+--------
+
+* Added support for web identity federation - You can now delegate token access
+ via either an Oauth 2.0 or OpenID provider. (:sha:`9bd0a3`)
+
+
+Bugfixes
+--------
+
+* Altered the S3 key buffer to be a configurable value. (:issue:`1506`,
+ :sha:`8e3e36`)
+* Added Sphinx extension for better release notes. (:issue:`1511`,
+ :sha:`e2e32d` & :sha:`3d998b`)
+* Fixed a bug where DynamoDB v2 would only ever connect to the default endpoint.
+ (:issue:`1508`, :sha:`139912`)
+* Fixed a iteration/empty results bug & a ``between`` bug in DynamoDB v2.
+ (:issue:`1512`, :sha:`d109b6`)
+* Fixed an issue with ``EbsOptimized`` in EC2 Autoscale. (:issue:`1513`,
+ :sha:`424c41`)
+* Fixed a missing instance variable bug in DynamoDB v2. (:issue:`1516`,
+ :sha: `6fa8bf`)
diff --git a/tests/integration/dynamodb2/test_layer1.py b/tests/integration/dynamodb2/test_layer1.py
index 43212676..0a0beef9 100644
--- a/tests/integration/dynamodb2/test_layer1.py
+++ b/tests/integration/dynamodb2/test_layer1.py
@@ -286,3 +286,39 @@ class DynamoDBv2Layer1Test(unittest.TestCase):
self.assertEqual(johndoe['Item']['friends']['SS'], [
'alice', 'bob', 'jane'
])
+
+ def test_throughput_exceeded_regression(self):
+ tiny_tablename = 'TinyThroughput'
+ tiny = self.create_table(
+ tiny_tablename,
+ self.attributes,
+ self.schema,
+ {
+ 'ReadCapacityUnits': 1,
+ 'WriteCapacityUnits': 1,
+ }
+ )
+
+ self.dynamodb.put_item(tiny_tablename, {
+ 'username': {'S': 'johndoe'},
+ 'first_name': {'S': 'John'},
+ 'last_name': {'S': 'Doe'},
+ 'date_joined': {'N': '1366056668'},
+ })
+ self.dynamodb.put_item(tiny_tablename, {
+ 'username': {'S': 'jane'},
+ 'first_name': {'S': 'Jane'},
+ 'last_name': {'S': 'Doe'},
+ 'date_joined': {'N': '1366056669'},
+ })
+ self.dynamodb.put_item(tiny_tablename, {
+ 'username': {'S': 'alice'},
+ 'first_name': {'S': 'Alice'},
+ 'last_name': {'S': 'Expert'},
+ 'date_joined': {'N': '1366057000'},
+ })
+ time.sleep(20)
+
+ for i in range(100):
+ # This would cause an exception due to a non-existant instance variable.
+ self.dynamodb.scan(tiny_tablename)
diff --git a/tests/integration/ec2/autoscale/test_connection.py b/tests/integration/ec2/autoscale/test_connection.py
index cf8d99ac..094adb14 100644
--- a/tests/integration/ec2/autoscale/test_connection.py
+++ b/tests/integration/ec2/autoscale/test_connection.py
@@ -165,3 +165,18 @@ class AutoscaleConnectionTest(unittest.TestCase):
assert not found
print '--- tests completed ---'
+
+ def test_ebs_optimized_regression(self):
+ c = AutoScaleConnection()
+ time_string = '%d' % int(time.time())
+ lc_name = 'lc-%s' % time_string
+ lc = LaunchConfiguration(
+ name=lc_name,
+ image_id='ami-2272864b',
+ instance_type='t1.micro',
+ ebs_optimized=True
+ )
+ # This failed due to the difference between native Python ``True/False``
+ # & the expected string variants.
+ c.create_launch_configuration(lc)
+ self.addCleanup(c.delete_launch_configuration, lc_name)
diff --git a/tests/integration/sts/test_session_token.py b/tests/integration/sts/test_session_token.py
index fa33d5f0..35d42ca8 100644
--- a/tests/integration/sts/test_session_token.py
+++ b/tests/integration/sts/test_session_token.py
@@ -27,10 +27,12 @@ Tests for Session Tokens
import unittest
import time
import os
+from boto.exception import BotoServerError
from boto.sts.connection import STSConnection
from boto.sts.credentials import Credentials
from boto.s3.connection import S3Connection
+
class SessionTokenTest (unittest.TestCase):
sts = True
@@ -63,3 +65,17 @@ class SessionTokenTest (unittest.TestCase):
buckets = s3.get_all_buckets()
print '--- tests completed ---'
+
+ def test_assume_role_with_web_identity(self):
+ c = STSConnection()
+
+ try:
+ creds = c.assume_role_with_web_identity(
+ 'arn:aws:s3:::my_corporate_bucket/*',
+ 'guestuser',
+ 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9',
+ provider_id='www.amazon.com',
+ )
+ except BotoServerError as err:
+ self.assertEqual(err.status, 403)
+ self.assertTrue('Not authorized' in err.body)
diff --git a/tests/unit/dynamodb2/test_layer1.py b/tests/unit/dynamodb2/test_layer1.py
new file mode 100644
index 00000000..5778a72d
--- /dev/null
+++ b/tests/unit/dynamodb2/test_layer1.py
@@ -0,0 +1,45 @@
+# 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.
+
+"""
+Tests for Layer1 of DynamoDB v2
+"""
+from tests.unit import unittest
+from boto.dynamodb2.layer1 import DynamoDBConnection
+from boto.regioninfo import RegionInfo
+
+
+class DynamoDBv2Layer1UnitTest(unittest.TestCase):
+ dynamodb = True
+
+ def test_init_region(self):
+ dynamodb = DynamoDBConnection(
+ aws_access_key_id='aws_access_key_id',
+ aws_secret_access_key='aws_secret_access_key')
+ self.assertEqual(dynamodb.region.name, 'us-east-1')
+ dynamodb = DynamoDBConnection(
+ region=RegionInfo(name='us-west-2',
+ endpoint='dynamodb.us-west-2.amazonaws.com'),
+ aws_access_key_id='aws_access_key_id',
+ aws_secret_access_key='aws_secret_access_key',
+ )
+ self.assertEqual(dynamodb.region.name, 'us-west-2')
diff --git a/tests/unit/dynamodb2/test_table.py b/tests/unit/dynamodb2/test_table.py
index 591f69c4..705d14f0 100644
--- a/tests/unit/dynamodb2/test_table.py
+++ b/tests/unit/dynamodb2/test_table.py
@@ -671,6 +671,16 @@ class ResultSetTestCase(unittest.TestCase):
self.assertRaises(StopIteration, self.results.next)
self.assertEqual(self.results.call_kwargs['limit'], 7)
+ def test_iteration_noresults(self):
+ def none(limit=10):
+ return {
+ 'results': [],
+ }
+
+ results = ResultSet()
+ results.to_call(none, limit=20)
+ self.assertRaises(StopIteration, results.next)
+
def test_list(self):
self.assertEqual(list(self.results), [
'Hello john #0',
@@ -1381,7 +1391,7 @@ class TableTestCase(unittest.TestCase):
'ComparisonOperator': 'IN',
},
'last_name': {
- 'AttributeValueList': [{'SS': ['only', 'danzig']}],
+ 'AttributeValueList': [{'S': 'danzig'}, {'S': 'only'}],
'ComparisonOperator': 'BETWEEN',
},
'first_name': {
@@ -1423,7 +1433,7 @@ class TableTestCase(unittest.TestCase):
'ComparisonOperator': 'GE',
},
'last_name': {
- 'AttributeValueList': [{'SS': ['only', 'danzig']}],
+ 'AttributeValueList': [{'S': 'danzig'}, {'S': 'only'}],
'ComparisonOperator': 'BETWEEN',
},
'gender': {
@@ -1506,18 +1516,16 @@ class TableTestCase(unittest.TestCase):
self.assertEqual(results['last_key'], None)
mock_query.assert_called_once_with('users',
+ consistent_read=False,
+ index_name=None,
+ scan_index_forward=True,
+ limit=4,
key_conditions={
'username': {
- 'AttributeValueList': [
- {'SS': ['mmm', 'aaa']}
- ],
+ 'AttributeValueList': [{'S': 'aaa'}, {'S': 'mmm'}],
'ComparisonOperator': 'BETWEEN',
}
- },
- index_name=None,
- scan_index_forward=True,
- limit=4,
- consistent_read=False
+ }
)
# Now alter the expected.
@@ -1548,9 +1556,7 @@ class TableTestCase(unittest.TestCase):
mock_query_2.assert_called_once_with('users',
key_conditions={
'username': {
- 'AttributeValueList': [
- {'SS': ['mmm', 'aaa']}
- ],
+ 'AttributeValueList': [{'S': 'aaa'}, {'S': 'mmm'}],
'ComparisonOperator': 'BETWEEN',
}
},