Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added ``boto.rds2``.

  • Loading branch information...
commit 10774a9deabdb1735f7f1e5b4eb52129d875fbad 1 parent aada5d3
@toastdriven toastdriven authored
View
15 boto/__init__.py
@@ -312,6 +312,21 @@ def connect_rds(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
return RDSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
+def connect_rds2(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.rds2.layer1.RDSConnection`
+ :return: A connection to RDS
+ """
+ from boto.rds2.layer1 import RDSConnection
+ return RDSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
+
+
def connect_emr(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
"""
:type aws_access_key_id: string
View
53 boto/rds2/__init__.py
@@ -0,0 +1,53 @@
+# Copyright (c) 2014 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 get_regions
+
+
+def regions():
+ """
+ Get all available regions for the RDS service.
+
+ :rtype: list
+ :return: A list of :class:`boto.regioninfo.RegionInfo`
+ """
+ from boto.rds2.layer1 import RDSConnection
+ return get_regions('rds', connection_cls=RDSConnection)
+
+
+def connect_to_region(region_name, **kw_params):
+ """
+ Given a valid region name, return a
+ :class:`boto.rds2.layer1.RDSConnection`.
+ Any additional parameters after the region_name are passed on to
+ the connect method of the region object.
+
+ :type: str
+ :param region_name: The name of the region to connect to.
+
+ :rtype: :class:`boto.rds2.layer1.RDSConnection` or ``None``
+ :return: A connection to the given region, or None if an invalid region
+ name is given
+ """
+ for region in regions():
+ if region.name == region_name:
+ return region.connect(**kw_params)
+ return None
View
234 boto/rds2/exceptions.py
@@ -0,0 +1,234 @@
+# Copyright (c) 2014 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 InvalidSubnet(JSONResponseError):
+ pass
+
+
+class DBParameterGroupQuotaExceeded(JSONResponseError):
+ pass
+
+
+class DBSubnetGroupAlreadyExists(JSONResponseError):
+ pass
+
+
+class DBSubnetGroupQuotaExceeded(JSONResponseError):
+ pass
+
+
+class InstanceQuotaExceeded(JSONResponseError):
+ pass
+
+
+class InvalidRestore(JSONResponseError):
+ pass
+
+
+class InvalidDBParameterGroupState(JSONResponseError):
+ pass
+
+
+class AuthorizationQuotaExceeded(JSONResponseError):
+ pass
+
+
+class DBSecurityGroupAlreadyExists(JSONResponseError):
+ pass
+
+
+class InsufficientDBInstanceCapacity(JSONResponseError):
+ pass
+
+
+class ReservedDBInstanceQuotaExceeded(JSONResponseError):
+ pass
+
+
+class DBSecurityGroupNotFound(JSONResponseError):
+ pass
+
+
+class DBInstanceAlreadyExists(JSONResponseError):
+ pass
+
+
+class ReservedDBInstanceNotFound(JSONResponseError):
+ pass
+
+
+class DBSubnetGroupDoesNotCoverEnoughAZs(JSONResponseError):
+ pass
+
+
+class InvalidDBSecurityGroupState(JSONResponseError):
+ pass
+
+
+class InvalidVPCNetworkState(JSONResponseError):
+ pass
+
+
+class ReservedDBInstancesOfferingNotFound(JSONResponseError):
+ pass
+
+
+class SNSTopicArnNotFound(JSONResponseError):
+ pass
+
+
+class SNSNoAuthorization(JSONResponseError):
+ pass
+
+
+class SnapshotQuotaExceeded(JSONResponseError):
+ pass
+
+
+class OptionGroupQuotaExceeded(JSONResponseError):
+ pass
+
+
+class DBParameterGroupNotFound(JSONResponseError):
+ pass
+
+
+class SNSInvalidTopic(JSONResponseError):
+ pass
+
+
+class InvalidDBSubnetGroupState(JSONResponseError):
+ pass
+
+
+class DBSubnetGroupNotFound(JSONResponseError):
+ pass
+
+
+class InvalidOptionGroupState(JSONResponseError):
+ pass
+
+
+class SourceNotFound(JSONResponseError):
+ pass
+
+
+class SubscriptionCategoryNotFound(JSONResponseError):
+ pass
+
+
+class EventSubscriptionQuotaExceeded(JSONResponseError):
+ pass
+
+
+class DBSecurityGroupNotSupported(JSONResponseError):
+ pass
+
+
+class InvalidEventSubscriptionState(JSONResponseError):
+ pass
+
+
+class InvalidDBSubnetState(JSONResponseError):
+ pass
+
+
+class InvalidDBSnapshotState(JSONResponseError):
+ pass
+
+
+class SubscriptionAlreadyExist(JSONResponseError):
+ pass
+
+
+class DBSecurityGroupQuotaExceeded(JSONResponseError):
+ pass
+
+
+class ProvisionedIopsNotAvailableInAZ(JSONResponseError):
+ pass
+
+
+class AuthorizationNotFound(JSONResponseError):
+ pass
+
+
+class OptionGroupAlreadyExists(JSONResponseError):
+ pass
+
+
+class SubscriptionNotFound(JSONResponseError):
+ pass
+
+
+class DBUpgradeDependencyFailure(JSONResponseError):
+ pass
+
+
+class PointInTimeRestoreNotEnabled(JSONResponseError):
+ pass
+
+
+class AuthorizationAlreadyExists(JSONResponseError):
+ pass
+
+
+class DBSubnetQuotaExceeded(JSONResponseError):
+ pass
+
+
+class OptionGroupNotFound(JSONResponseError):
+ pass
+
+
+class DBParameterGroupAlreadyExists(JSONResponseError):
+ pass
+
+
+class DBInstanceNotFound(JSONResponseError):
+ pass
+
+
+class ReservedDBInstanceAlreadyExists(JSONResponseError):
+ pass
+
+
+class InvalidDBInstanceState(JSONResponseError):
+ pass
+
+
+class DBSnapshotNotFound(JSONResponseError):
+ pass
+
+
+class DBSnapshotAlreadyExists(JSONResponseError):
+ pass
+
+
+class StorageQuotaExceeded(JSONResponseError):
+ pass
+
+
+class SubnetAlreadyInUse(JSONResponseError):
+ pass
View
3,774 boto/rds2/layer1.py
3,774 additions, 0 deletions not shown
View
2  docs/source/index.rst
@@ -34,6 +34,7 @@ Currently Supported Services
* :doc:`DynamoDB2 <dynamodb2_tut>` -- (:doc:`API Reference <ref/dynamodb2>`) -- (:doc:`Migration Guide from v1 <migrations/dynamodb_v1_to_v2>`)
* :doc:`DynamoDB <dynamodb_tut>` -- (:doc:`API Reference <ref/dynamodb>`)
+ * Relational Data Services 2 (RDS) -- (:doc:`API Reference <ref/rds2>`) -- (:doc:`Migration Guide from v1 <migrations/rds_v1_to_v2>`)
* :doc:`Relational Data Services (RDS) <rds_tut>` -- (:doc:`API Reference <ref/rds>`)
* ElastiCache -- (:doc:`API Reference <ref/elasticache>`)
* Redshift -- (:doc:`API Reference <ref/redshift>`)
@@ -194,6 +195,7 @@ Release Notes
support_tut
dynamodb2_tut
migrations/dynamodb_v1_to_v2
+ migrations/rds_v1_to_v2
apps_built_on_boto
ref/*
releasenotes/*
View
91 docs/source/migrations/rds_v1_to_v2.rst
@@ -0,0 +1,91 @@
+.. rds_v1_to_v2:
+
+===============================
+Migrating from RDS v1 to RDS v2
+===============================
+
+The original ``boto.rds`` module has historically lagged quite far behind the
+service (at time of writing, almost 50% of the API calls are
+missing/out-of-date). To address this, the Boto core team has switched to
+a generated client for RDS (``boto.rds2.layer1.RDSConnection``).
+
+However, this generated variant is not backward-compatible with the older
+``boto.rds.RDSConnection``. This document is to help you update your code
+(as desired) to take advantage of the latest API calls.
+
+For the duration of the document, **RDS2Connection** refers to
+``boto.rds2.layer1.RDSConnection``, where **RDSConnection** refers to
+``boto.rds.RDSConnection``.
+
+
+Prominent Differences
+=====================
+
+* The new **RDS2Connection** maps very closely to the `official API operations`_,
+ where the old **RDSConnection** had non-standard & inconsistent method names.
+* **RDS2Connection** almost always returns a Python dictionary that maps
+ closely to the API output. **RDSConnection** returned Python objects.
+* **RDS2Connection** is much more verbose in terms of output. Tools like
+ `jmespath`_ or `jsonq`_ can make handling these sometimes complex dictionaries more
+ manageable.
+
+.. _`official API operations`: http://docs.aws.amazon.com/AmazonRDS/latest/APIReference/Welcome.html
+.. _`jmespath`: https://github.com/boto/jmespath
+.. _`jsonq`: https://github.com/edmund-huber/jsonq
+
+
+Method Renames
+==============
+
+Format is ``old_method_name`` -> ``new_method_name``:
+
+* ``authorize_dbsecurity_group`` -> ``authorize_db_security_group_ingress``
+* ``create_dbinstance`` -> ``create_db_instance``
+* ``create_dbinstance_read_replica`` -> ``create_db_instance_read_replica``
+* ``create_parameter_group`` -> ``create_db_parameter_group``
+* ``get_all_dbsnapshots`` -> ``describe_db_snapshots``
+* ``get_all_events`` -> ``describe_events``
+* ``modify_dbinstance`` -> ``modify_db_instance``
+* ``reboot_dbinstance`` -> ``reboot_db_instance``
+* ``restore_dbinstance_from_dbsnapshot`` -> ``restore_db_instance_from_db_snapshot``
+* ``restore_dbinstance_from_point_in_time`` -> ``restore_db_instance_to_point_in_time``
+* ``revoke_dbsecurity_group`` -> ``revoke_db_security_group_ingress``
+
+
+Parameter Changes
+=================
+
+Many parameter names have changed between **RDSConnection** &
+**RDS2Connection**. For instance, the old name for the instance identifier was
+``id``, where the new name is ``db_instance_identifier``. These changes are to
+ensure things map more closely to the API.
+
+In addition, in some cases, ordering & required-ness of parameters has changed
+as well. For instance, in ``create_db_instance``, the
+``engine`` parameter is now required (previously defaulted to ``MySQL5.1``) &
+its position in the call has change to be before ``master_username``.
+
+As such, when updating your API calls, you should check the
+API Reference documentation to ensure you're passing the
+correct parameters.
+
+
+Return Values
+=============
+
+**RDSConnection** frequently returned higher-level Python objects. In contrast,
+**RDS2Connection** returns Python dictionaries of the data. This will require
+a bit more work to extract the necessary values. For example::
+
+ # Old
+ >>> instances = rds1_conn.get_all_dbinstances()
+ >>> inst = instances[0]
+ >>> inst.name
+ 'test-db'
+
+ # New
+ >>> instances = rds2_conn.describe_db_instances()
+ >>> inst = instances['DescribeDBInstancesResponse']\
+ ... ['DescribeDBInstancesResult']['DBInstances'][0]
+ >>> inst['DBName']
+ 'test-db'
View
9 docs/source/rds_tut.rst
@@ -8,6 +8,15 @@ This tutorial focuses on the boto interface to the Relational Database Service
from Amazon Web Services. This tutorial assumes that you have boto already
downloaded and installed, and that you wish to setup a MySQL instance in RDS.
+.. warning::
+
+ This tutorial covers the **ORIGINAL** module for RDS.
+ It has since been supplanted by a second major version & an
+ updated API complete with all service operations. The documentation for the
+ new version of boto's support for RDS is at
+ :doc:`RDS v2 <ref/rds2>`.
+
+
Creating a Connection
---------------------
The first step in accessing RDS is to create a connection to the service.
View
26 docs/source/ref/rds2.rst
@@ -0,0 +1,26 @@
+.. ref-rds2
+
+====
+RDS2
+====
+
+boto.rds2
+---------
+
+.. automodule:: boto.rds2
+ :members:
+ :undoc-members:
+
+boto.rds2.exceptions
+--------------------
+
+.. automodule:: boto.rds2.exceptions
+ :members:
+ :undoc-members:
+
+boto.rds2.layer1
+----------------
+
+.. automodule:: boto.rds2.layer1
+ :members:
+ :undoc-members:
View
2  setup.py
@@ -75,7 +75,7 @@ def readme():
"boto.beanstalk", "boto.datapipeline", "boto.elasticache",
"boto.elastictranscoder", "boto.opsworks", "boto.redshift",
"boto.dynamodb2", "boto.support", "boto.cloudtrail",
- "boto.directconnect", "boto.kinesis"],
+ "boto.directconnect", "boto.kinesis", "boto.rds2"],
package_data = {
"boto.cacerts": ["cacerts.txt"],
"boto": ["endpoints.json"],
View
21 tests/integration/rds2/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
+# Copyright (c) 2012 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.
View
39 tests/integration/rds2/test_cert_verification.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
+# Copyright (c) 2012 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.
+
+"""
+Check that all of the certs on all service endpoints validate.
+"""
+import unittest
+
+from tests.integration import ServiceCertVerificationTest
+
+import boto.rds2
+
+
+class RDSCertVerificationTest(unittest.TestCase, ServiceCertVerificationTest):
+ rds = True
+ regions = boto.rds2.regions()
+
+ def sample_service_call(self, conn):
+ conn.describe_db_instances()
View
87 tests/integration/rds2/test_connection.py
@@ -0,0 +1,87 @@
+# Copyright (c) 2014 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 unittest
+import time
+from boto.rds2.layer1 import RDSConnection
+
+
+class TestRDS2Connection(unittest.TestCase):
+ rds = True
+
+ def setUp(self):
+ self.conn = RDSConnection()
+ self.db_name = "test-db-%s" % str(int(time.time()))
+
+ def test_integration(self):
+ resp = self.conn.create_db_instance(
+ db_instance_identifier=self.db_name,
+ allocated_storage=5,
+ db_instance_class='db.t1.micro',
+ engine='postgres',
+ master_username='bototestuser',
+ master_user_password='testtestt3st',
+ # Try to limit the impact & test options.
+ multi_az=False,
+ backup_retention_period=0
+ )
+ self.addCleanup(
+ self.conn.delete_db_instance,
+ self.db_name,
+ skip_final_snapshot=True
+ )
+
+ # Wait for 6 minutes for it to come up.
+ time.sleep(60 * 6)
+
+ instances = self.conn.describe_db_instances(self.db_name)
+ inst = instances['DescribeDBInstancesResponse']\
+ ['DescribeDBInstancesResult']['DBInstances'][0]
+ self.assertEqual(inst['DBInstanceStatus'], 'available')
+ self.assertEqual(inst['Engine'], 'postgres')
+ self.assertEqual(inst['AllocatedStorage'], 5)
+
+ # Try renaming it.
+ resp = self.conn.modify_db_instance(
+ self.db_name,
+ allocated_storage=10,
+ apply_immediately=True
+ )
+
+ # Give it a chance to start modifying...
+ time.sleep(60)
+
+ instances = self.conn.describe_db_instances(self.db_name)
+ inst = instances['DescribeDBInstancesResponse']\
+ ['DescribeDBInstancesResult']['DBInstances'][0]
+ self.assertEqual(inst['DBInstanceStatus'], 'modifying')
+ self.assertEqual(inst['Engine'], 'postgres')
+
+ # ...then finish the remainder of 10 minutes for the change.
+ time.sleep(60 * 9)
+
+ instances = self.conn.describe_db_instances(self.db_name)
+ inst = instances['DescribeDBInstancesResponse']\
+ ['DescribeDBInstancesResult']['DBInstances'][0]
+ self.assertEqual(inst['DBInstanceStatus'], 'available')
+ self.assertEqual(inst['Engine'], 'postgres')
+ self.assertEqual(inst['AllocatedStorage'], 10)
View
0  tests/unit/rds2/__init__.py
No changes.
View
209 tests/unit/rds2/test_connection.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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 tests.unit import unittest
+from tests.unit import AWSMockServiceTestCase
+
+from boto.ec2.securitygroup import SecurityGroup
+from boto.rds2.layer1 import RDSConnection
+
+
+class TestRDS2Connection(AWSMockServiceTestCase):
+ connection_class = RDSConnection
+
+ def setUp(self):
+ super(TestRDS2Connection, self).setUp()
+
+ def default_body(self):
+ return """{
+ "DescribeDBInstancesResponse": {
+ "DescribeDBInstancesResult": {
+ "DBInstances": [{
+ "DBInstance": {
+ "Iops": 2000,
+ "BackupRetentionPeriod": 1,
+ "MultiAZ": false,
+ "DBInstanceStatus": "backing-up",
+ "DBInstanceIdentifier": "mydbinstance2",
+ "PreferredBackupWindow": "10:30-11:00",
+ "PreferredMaintenanceWindow": "wed:06:30-wed:07:00",
+ "OptionGroupMembership": {
+ "OptionGroupName": "default:mysql-5-5",
+ "Status": "in-sync"
+ },
+ "AvailabilityZone": "us-west-2b",
+ "ReadReplicaDBInstanceIdentifiers": null,
+ "Engine": "mysql",
+ "PendingModifiedValues": null,
+ "LicenseModel": "general-public-license",
+ "DBParameterGroups": [{
+ "DBParameterGroup": {
+ "ParameterApplyStatus": "in-sync",
+ "DBParameterGroupName": "default.mysql5.5"
+ }
+ }],
+ "Endpoint": {
+ "Port": 3306,
+ "Address": "mydbinstance2.c0hjqouvn9mf.us-west-2.rds.amazonaws.com"
+ },
+ "EngineVersion": "5.5.27",
+ "DBSecurityGroups": [{
+ "DBSecurityGroup": {
+ "Status": "active",
+ "DBSecurityGroupName": "default"
+ }
+ }],
+ "VpcSecurityGroups": [{
+ "VpcSecurityGroupMembership": {
+ "VpcSecurityGroupId": "sg-1",
+ "Status": "active"
+ }
+ }],
+ "DBName": "mydb2",
+ "AutoMinorVersionUpgrade": true,
+ "InstanceCreateTime": "2012-10-03T22:01:51.047Z",
+ "AllocatedStorage": 200,
+ "DBInstanceClass": "db.m1.large",
+ "MasterUsername": "awsuser",
+ "StatusInfos": [{
+ "DBInstanceStatusInfo": {
+ "Message": null,
+ "Normal": true,
+ "Status": "replicating",
+ "StatusType": "read replication"
+ }
+ }],
+ "DBSubnetGroup": {
+ "VpcId": "990524496922",
+ "SubnetGroupStatus": "Complete",
+ "DBSubnetGroupDescription": "My modified DBSubnetGroup",
+ "DBSubnetGroupName": "mydbsubnetgroup",
+ "Subnets": [{
+ "Subnet": {
+ "SubnetStatus": "Active",
+ "SubnetIdentifier": "subnet-7c5b4115",
+ "SubnetAvailabilityZone": {
+ "Name": "us-east-1c"
+ }
+ },
+ "Subnet": {
+ "SubnetStatus": "Active",
+ "SubnetIdentifier": "subnet-7b5b4112",
+ "SubnetAvailabilityZone": {
+ "Name": "us-east-1b"
+ }
+ },
+ "Subnet": {
+ "SubnetStatus": "Active",
+ "SubnetIdentifier": "subnet-3ea6bd57",
+ "SubnetAvailabilityZone": {
+ "Name": "us-east-1d"
+ }
+ }
+ }]
+ }
+ }
+ }]
+ }
+ }
+ }"""
+
+ def test_describe_db_instances(self):
+ self.set_http_response(status_code=200)
+ response = self.service_connection.describe_db_instances('instance_id')
+ self.assertEqual(len(response), 1)
+ self.assert_request_parameters({
+ 'Action': 'DescribeDBInstances',
+ 'ContentType': 'JSON',
+ 'DBInstanceIdentifier': 'instance_id',
+ }, ignore_params_values=['Version'])
+ db = response['DescribeDBInstancesResponse']\
+ ['DescribeDBInstancesResult']['DBInstances'][0]\
+ ['DBInstance']
+ self.assertEqual(db['DBInstanceIdentifier'], 'mydbinstance2')
+ self.assertEqual(db['InstanceCreateTime'], '2012-10-03T22:01:51.047Z')
+ self.assertEqual(db['Engine'], 'mysql')
+ self.assertEqual(db['DBInstanceStatus'], 'backing-up')
+ self.assertEqual(db['AllocatedStorage'], 200)
+ self.assertEqual(db['Endpoint']['Port'], 3306)
+ self.assertEqual(db['DBInstanceClass'], 'db.m1.large')
+ self.assertEqual(db['MasterUsername'], 'awsuser')
+ self.assertEqual(db['AvailabilityZone'], 'us-west-2b')
+ self.assertEqual(db['BackupRetentionPeriod'], 1)
+ self.assertEqual(db['PreferredBackupWindow'], '10:30-11:00')
+ self.assertEqual(db['PreferredMaintenanceWindow'],
+ 'wed:06:30-wed:07:00')
+ self.assertEqual(db['MultiAZ'], False)
+ self.assertEqual(db['Iops'], 2000)
+ self.assertEqual(db['PendingModifiedValues'], None)
+ self.assertEqual(
+ db['DBParameterGroups'][0]['DBParameterGroup']\
+ ['DBParameterGroupName'],
+ 'default.mysql5.5'
+ )
+ self.assertEqual(
+ db['DBSecurityGroups'][0]['DBSecurityGroup']['DBSecurityGroupName'],
+ 'default'
+ )
+ self.assertEqual(
+ db['DBSecurityGroups'][0]['DBSecurityGroup']['Status'],
+ 'active'
+ )
+ self.assertEqual(len(db['StatusInfos']), 1)
+ self.assertEqual(
+ db['StatusInfos'][0]['DBInstanceStatusInfo']['Message'],
+ None
+ )
+ self.assertEqual(
+ db['StatusInfos'][0]['DBInstanceStatusInfo']['Normal'],
+ True
+ )
+ self.assertEqual(
+ db['StatusInfos'][0]['DBInstanceStatusInfo']['Status'],
+ 'replicating'
+ )
+ self.assertEqual(
+ db['StatusInfos'][0]['DBInstanceStatusInfo']['StatusType'],
+ 'read replication'
+ )
+ self.assertEqual(
+ db['VpcSecurityGroups'][0]['VpcSecurityGroupMembership']['Status'],
+ 'active'
+ )
+ self.assertEqual(
+ db['VpcSecurityGroups'][0]['VpcSecurityGroupMembership']\
+ ['VpcSecurityGroupId'],
+ 'sg-1'
+ )
+ self.assertEqual(db['LicenseModel'], 'general-public-license')
+ self.assertEqual(db['EngineVersion'], '5.5.27')
+ self.assertEqual(db['AutoMinorVersionUpgrade'], True)
+ self.assertEqual(
+ db['DBSubnetGroup']['DBSubnetGroupName'],
+ 'mydbsubnetgroup'
+ )
+
+
+if __name__ == '__main__':
+ unittest.main()
+
Please sign in to comment.
Something went wrong with that request. Please try again.