From 2fc732fdc80bd06094e022a59807db374290b0de Mon Sep 17 00:00:00 2001 From: Mark Nunnikhoven Date: Sat, 29 Sep 2012 00:03:59 -0400 Subject: [PATCH 1/7] Added support for provisioned IOPS in RDS --- boto/rds/__init__.py | 31 +++++++++++++++++++++++++++++-- boto/rds/dbinstance.py | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/boto/rds/__init__.py b/boto/rds/__init__.py index 8190eef3f4..94e92a6a54 100644 --- a/boto/rds/__init__.py +++ b/boto/rds/__init__.py @@ -161,8 +161,9 @@ def create_dbinstance(self, db_subnet_group_name = None, license_model = None, option_group_name = None, + iops=None, ): - # API version: 2012-04-23 + # API version: 2012-09-17 # Parameter notes: # ================= # id should be db_instance_identifier according to API docs but has been left @@ -348,6 +349,17 @@ def create_dbinstance(self, :param option_group_name: Indicates that the DB Instance should be associated with the specified option group. + :type iops: int + :param iops: The amount of IOPS (input/output operations per second) to Provisioned + for the DB Instance. Can be modified at a later date. + + Must scale linearly. For every 1000 IOPS provision, you must allocated + 100 GB of storage space. This scales up to 1 TB / 10 000 IOPS for MySQL + and Oracle. MSSQL is limited to 700 GB / 7 000 IOPS. + + If you specify a value, it must be at least 1000 IOPS and you must + allocate 100 GB of storage. + :rtype: :class:`boto.rds.dbinstance.DBInstance` :return: The new db instance. """ @@ -388,6 +400,7 @@ def create_dbinstance(self, 'DBSubnetGroupName': db_subnet_group_name, 'Engine': engine, 'EngineVersion': engine_version, + 'Iops': iops, 'LicenseModel': license_model, 'MasterUsername': master_username, 'MasterUserPassword': master_password, @@ -488,7 +501,8 @@ def modify_dbinstance(self, id, param_group=None, security_groups=None, backup_retention_period=None, preferred_backup_window=None, multi_az=False, - apply_immediately=False): + apply_immediately=False, + iops=None): """ Modify an existing DBInstance. @@ -548,6 +562,17 @@ def modify_dbinstance(self, id, param_group=None, security_groups=None, :param multi_az: If True, specifies the DB Instance will be deployed in multiple availability zones. + :type iops: int + :param iops: The amount of IOPS (input/output operations per second) to Provisioned + for the DB Instance. Can be modified at a later date. + + Must scale linearly. For every 1000 IOPS provision, you must allocated + 100 GB of storage space. This scales up to 1 TB / 10 000 IOPS for MySQL + and Oracle. MSSQL is limited to 700 GB / 7 000 IOPS. + + If you specify a value, it must be at least 1000 IOPS and you must + allocate 100 GB of storage. + :rtype: :class:`boto.rds.dbinstance.DBInstance` :return: The modified db instance. """ @@ -578,6 +603,8 @@ def modify_dbinstance(self, id, param_group=None, security_groups=None, params['MultiAZ'] = 'true' if apply_immediately: params['ApplyImmediately'] = 'true' + if iops: + params['Iops'] = iops return self.get_object('ModifyDBInstance', params, DBInstance) diff --git a/boto/rds/dbinstance.py b/boto/rds/dbinstance.py index f6c2787701..6cb689bf6f 100644 --- a/boto/rds/dbinstance.py +++ b/boto/rds/dbinstance.py @@ -61,6 +61,7 @@ class DBInstance(object): a database can be restored with point-in-time restore. TODO: type? :ivar multi_az: Boolean that specifies if the DB Instance is a Multi-AZ deployment. + :ivar iops: The current number of provisioned IOPS for the DB Instance. Can be None if this is a standard instance :ivar pending_modified_values: Specifies that changes to the DB Instance are pending. This element is only included when changes are pending. Specific changes are identified by subelements. @@ -84,6 +85,7 @@ def __init__(self, connection=None, id=None): self.preferred_maintenance_window = None self.latest_restorable_time = None self.multi_az = False + self.iops = None self.pending_modified_values = None self._in_endpoint = False self._port = None @@ -145,6 +147,11 @@ def endElement(self, name, value, connection): elif name == 'MultiAZ': if value.lower() == 'true': self.multi_az = True + elif name == 'Iops': + try: + self.iops = int(value) + except Exception, err: + self.iops = None else: setattr(self, name, value) @@ -217,6 +224,7 @@ def modify(self, param_group=None, security_groups=None, backup_retention_period=None, preferred_backup_window=None, multi_az=False, + iops=None, apply_immediately=False): """ Modify this DBInstance. @@ -271,6 +279,17 @@ def modify(self, param_group=None, security_groups=None, :param multi_az: If True, specifies the DB Instance will be deployed in multiple availability zones. + :type iops: int + :param iops: The amount of IOPS (input/output operations per second) to Provisioned + for the DB Instance. Can be modified at a later date. + + Must scale linearly. For every 1000 IOPS provision, you must allocated + 100 GB of storage space. This scales up to 1 TB / 10 000 IOPS for MySQL + and Oracle. MSSQL is limited to 700 GB / 7 000 IOPS. + + If you specify a value, it must be at least 1000 IOPS and you must + allocate 100 GB of storage. + :rtype: :class:`boto.rds.dbinstance.DBInstance` :return: The modified db instance. """ @@ -284,6 +303,7 @@ def modify(self, param_group=None, security_groups=None, backup_retention_period, preferred_backup_window, multi_az, + iops, apply_immediately) From 86c84f295fe72a00e284190e1be0f880117f1272 Mon Sep 17 00:00:00 2001 From: Mark Nunnikhoven Date: Sat, 29 Sep 2012 20:26:08 -0400 Subject: [PATCH 2/7] Updated RDS API version to 2012-09-17 --- boto/rds/__init__.py | 2 +- docs/source/rds_tut.rst | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/source/rds_tut.rst diff --git a/boto/rds/__init__.py b/boto/rds/__init__.py index 94e92a6a54..02b1a03cfe 100644 --- a/boto/rds/__init__.py +++ b/boto/rds/__init__.py @@ -81,7 +81,7 @@ class RDSConnection(AWSQueryConnection): DefaultRegionName = 'us-east-1' DefaultRegionEndpoint = 'rds.us-east-1.amazonaws.com' - APIVersion = '2011-04-01' + APIVersion = '2012-09-17' def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, is_secure=True, port=None, proxy=None, proxy_port=None, diff --git a/docs/source/rds_tut.rst b/docs/source/rds_tut.rst new file mode 100644 index 0000000000..e69de29bb2 From db9bc0236cd783c4745c663d9c20a5f561a84d56 Mon Sep 17 00:00:00 2001 From: Mark Nunnikhoven Date: Sat, 29 Sep 2012 20:27:22 -0400 Subject: [PATCH 3/7] Removed placeholder for RDS tutorial --- docs/source/rds_tut.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/source/rds_tut.rst diff --git a/docs/source/rds_tut.rst b/docs/source/rds_tut.rst deleted file mode 100644 index e69de29bb2..0000000000 From 9ec1aece702143ac699f6375cb21643a587d4bbd Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Wed, 3 Oct 2012 15:00:23 -0700 Subject: [PATCH 4/7] pep8: doc line should be less than 80 chars --- boto/rds/dbinstance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boto/rds/dbinstance.py b/boto/rds/dbinstance.py index 6cb689bf6f..e9d9e5a6d2 100644 --- a/boto/rds/dbinstance.py +++ b/boto/rds/dbinstance.py @@ -61,7 +61,8 @@ class DBInstance(object): a database can be restored with point-in-time restore. TODO: type? :ivar multi_az: Boolean that specifies if the DB Instance is a Multi-AZ deployment. - :ivar iops: The current number of provisioned IOPS for the DB Instance. Can be None if this is a standard instance + :ivar iops: The current number of provisioned IOPS for the DB Instance. + Can be None if this is a standard instance. :ivar pending_modified_values: Specifies that changes to the DB Instance are pending. This element is only included when changes are pending. Specific changes are identified by subelements. From 27a63bf15ab019a3545f81a119f7fdaff1eacb89 Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Wed, 3 Oct 2012 15:05:05 -0700 Subject: [PATCH 5/7] Remove try/except from iops attribute If the db instance does not use provisioned iops, the Iops element is not returned at all. --- boto/rds/dbinstance.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/boto/rds/dbinstance.py b/boto/rds/dbinstance.py index e9d9e5a6d2..d26e55e1ad 100644 --- a/boto/rds/dbinstance.py +++ b/boto/rds/dbinstance.py @@ -58,7 +58,7 @@ class DBInstance(object): :ivar preferred_maintenance_window: Specifies the weekly time range (in UTC) during which system maintenance can occur. (string) :ivar latest_restorable_time: Specifies the latest time to which - a database can be restored with point-in-time restore. TODO: type? + a database can be restored with point-in-time restore. (string) :ivar multi_az: Boolean that specifies if the DB Instance is a Multi-AZ deployment. :ivar iops: The current number of provisioned IOPS for the DB Instance. @@ -149,10 +149,7 @@ def endElement(self, name, value, connection): if value.lower() == 'true': self.multi_az = True elif name == 'Iops': - try: - self.iops = int(value) - except Exception, err: - self.iops = None + self.iops = int(value) else: setattr(self, name, value) From f8a2e7946d1056eb8411161e9de2f21786492794 Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Thu, 4 Oct 2012 11:09:44 -0700 Subject: [PATCH 6/7] Add start of unittests for rds connection class --- tests/unit/rds/__init__.py | 0 tests/unit/rds/test_connection.py | 131 ++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 tests/unit/rds/__init__.py create mode 100644 tests/unit/rds/test_connection.py diff --git a/tests/unit/rds/__init__.py b/tests/unit/rds/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/rds/test_connection.py b/tests/unit/rds/test_connection.py new file mode 100644 index 0000000000..0d4bff8343 --- /dev/null +++ b/tests/unit/rds/test_connection.py @@ -0,0 +1,131 @@ +#!/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.rds import RDSConnection + + +class TestRDSConnection(AWSMockServiceTestCase): + connection_class = RDSConnection + + def setUp(self): + super(TestRDSConnection, self).setUp() + + def default_body(self): + return """ + + + + + 2000 + 1 + false + backing-up + mydbinstance2 + 10:30-11:00 + wed:06:30-wed:07:00 + + default:mysql-5-5 + in-sync + + us-west-2b + + mysql + + general-public-license + + + in-sync + default.mysql5.5 + + + + 3306 +
mydbinstance2.c0hjqouvn9mf.us-west-2.rds.amazonaws.com
+
+ 5.5.27 + + + active + default + + + mydb2 + true + 2012-10-03T22:01:51.047Z + 200 + db.m1.large + awsuser +
+
+
+
+ """ + + def test_get_all_db_instances(self): + self.set_http_response(status_code=200) + response = self.service_connection.get_all_dbinstances('instance_id') + self.assertEqual(len(response), 1) + self.assert_request_parameters({ + 'Action': 'DescribeDBInstances', + 'DBInstanceIdentifier': 'instance_id', + }, ignore_params_values=['AWSAccessKeyId', 'Timestamp', 'Version', + 'SignatureVersion', 'SignatureMethod']) + db = response[0] + self.assertEqual(db.id, 'mydbinstance2') + self.assertEqual(db.create_time, '2012-10-03T22:01:51.047Z') + self.assertEqual(db.engine, 'mysql') + self.assertEqual(db.status, 'backing-up') + self.assertEqual(db.allocated_storage, 200) + self.assertEqual( + db.endpoint, + (u'mydbinstance2.c0hjqouvn9mf.us-west-2.rds.amazonaws.com', 3306)) + self.assertEqual(db.instance_class, 'db.m1.large') + self.assertEqual(db.master_username, 'awsuser') + self.assertEqual(db.availability_zone, 'us-west-2b') + self.assertEqual(db.backup_retention_period, '1') + self.assertEqual(db.preferred_backup_window, '10:30-11:00') + self.assertEqual(db.preferred_maintenance_window, + 'wed:06:30-wed:07:00') + self.assertEqual(db.latest_restorable_time, None) + self.assertEqual(db.multi_az, False) + self.assertEqual(db.iops, 2000) + self.assertEqual(db.pending_modified_values, {}) + + self.assertEqual(db.parameter_group.name, + 'default.mysql5.5') + self.assertEqual(db.parameter_group.description, None) + self.assertEqual(db.parameter_group.engine, None) + + self.assertEqual(db.security_group.owner_id, None) + self.assertEqual(db.security_group.name, 'default') + self.assertEqual(db.security_group.description, None) + self.assertEqual(db.security_group.ec2_groups, []) + self.assertEqual(db.security_group.ip_ranges, []) + + +if __name__ == '__main__': + unittest.main() + From acec1e28dfc77896845a7ae2b8eb8c6479ddc25e Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Thu, 4 Oct 2012 11:12:33 -0700 Subject: [PATCH 7/7] Remove unused import --- boto/rds/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/boto/rds/__init__.py b/boto/rds/__init__.py index 02b1a03cfe..b8f4219284 100644 --- a/boto/rds/__init__.py +++ b/boto/rds/__init__.py @@ -20,7 +20,6 @@ # IN THE SOFTWARE. # -import boto.utils import urllib from boto.connection import AWSQueryConnection from boto.rds.dbinstance import DBInstance