aboisvert_aws 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. data/History.txt +329 -0
  2. data/Manifest.txt +61 -0
  3. data/README.txt +163 -0
  4. data/Rakefile +130 -0
  5. data/lib/acf/right_acf_interface.rb +549 -0
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +248 -0
  10. data/lib/as/right_as_interface.rb +698 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +1343 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +541 -0
  16. data/lib/ec2/right_ec2_ebs.rb +481 -0
  17. data/lib/ec2/right_ec2_images.rb +444 -0
  18. data/lib/ec2/right_ec2_instances.rb +788 -0
  19. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  20. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  21. data/lib/ec2/right_ec2_reserved_instances.rb +184 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +491 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +422 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +590 -0
  26. data/lib/ec2/right_ec2_vpc2.rb +381 -0
  27. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  28. data/lib/elb/right_elb_interface.rb +573 -0
  29. data/lib/emr/right_emr_interface.rb +727 -0
  30. data/lib/iam/right_iam_access_keys.rb +71 -0
  31. data/lib/iam/right_iam_groups.rb +195 -0
  32. data/lib/iam/right_iam_interface.rb +341 -0
  33. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  34. data/lib/iam/right_iam_users.rb +251 -0
  35. data/lib/rds/right_rds_interface.rb +1384 -0
  36. data/lib/right_aws.rb +86 -0
  37. data/lib/route_53/right_route_53_interface.rb +640 -0
  38. data/lib/s3/right_s3.rb +1138 -0
  39. data/lib/s3/right_s3_interface.rb +1278 -0
  40. data/lib/sdb/active_sdb.rb +1107 -0
  41. data/lib/sdb/right_sdb_interface.rb +762 -0
  42. data/lib/sns/right_sns_interface.rb +286 -0
  43. data/lib/sqs/right_sqs.rb +387 -0
  44. data/lib/sqs/right_sqs_gen2.rb +342 -0
  45. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  46. data/lib/sqs/right_sqs_interface.rb +593 -0
  47. data/right_aws.gemspec +90 -0
  48. data/test/README.mdown +39 -0
  49. data/test/acf/test_helper.rb +2 -0
  50. data/test/acf/test_right_acf.rb +138 -0
  51. data/test/awsbase/test_helper.rb +2 -0
  52. data/test/awsbase/test_right_awsbase.rb +11 -0
  53. data/test/ec2/test_helper.rb +2 -0
  54. data/test/ec2/test_right_ec2.rb +107 -0
  55. data/test/elb/test_helper.rb +2 -0
  56. data/test/elb/test_right_elb.rb +43 -0
  57. data/test/http_connection.rb +87 -0
  58. data/test/rds/test_helper.rb +2 -0
  59. data/test/rds/test_right_rds.rb +120 -0
  60. data/test/route_53/fixtures/a_record.xml +18 -0
  61. data/test/route_53/fixtures/alias_record.xml +18 -0
  62. data/test/route_53/test_helper.rb +2 -0
  63. data/test/route_53/test_right_route_53.rb +141 -0
  64. data/test/s3/test_helper.rb +2 -0
  65. data/test/s3/test_right_s3.rb +528 -0
  66. data/test/s3/test_right_s3_stubbed.rb +97 -0
  67. data/test/sdb/test_active_sdb.rb +357 -0
  68. data/test/sdb/test_batch_put_attributes.rb +54 -0
  69. data/test/sdb/test_helper.rb +3 -0
  70. data/test/sdb/test_right_sdb.rb +253 -0
  71. data/test/sns/test_helper.rb +2 -0
  72. data/test/sns/test_right_sns.rb +153 -0
  73. data/test/sqs/test_helper.rb +2 -0
  74. data/test/sqs/test_right_sqs.rb +285 -0
  75. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  76. data/test/test_credentials.rb +37 -0
  77. data/test/ts_right_aws.rb +15 -0
  78. metadata +257 -0
@@ -0,0 +1,67 @@
1
+ module RightAws
2
+
3
+ class IamInterface < RightAwsBase
4
+
5
+ #-----------------------------------------------------------------
6
+ # MFADevices
7
+ #-----------------------------------------------------------------
8
+
9
+ # Lists the MFA devices associated with the specified User name.
10
+ #
11
+ # Options: :user_name, :max_items, :marker
12
+ #
13
+ def list_mfa_devices(options={}, &block)
14
+ incrementally_list_iam_resources('ListMFADevices', options, &block)
15
+ end
16
+
17
+ # Enables the specified MFA device and associates it with the specified User name.
18
+ # Once enabled, the MFA device is required for every subsequent login by the User name associated with the device.
19
+ #
20
+ # iam.enable_mfa_device('kd1', 'x12345', '12345', '67890') #=> true
21
+ #
22
+ def enable_mfa_device(user_name, serial_number, auth_code1, auth_code2)
23
+ request_hash = { 'UserName' => user_name,
24
+ 'SerialNumber' => serial_number,
25
+ 'AuthenticationCode1' => auth_code1,
26
+ 'AuthenticationCode2' => auth_code2 }
27
+ link = generate_request("EnableMFADevice", request_hash)
28
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
29
+ end
30
+
31
+ # Synchronizes the specified MFA device with AWS servers.
32
+ #
33
+ # iam.resync_mfa_device('kd1', 'x12345', '12345', '67890') #=> true
34
+ #
35
+ def resync_mfa_device(user_name, serial_number, auth_code1, auth_code2)
36
+ request_hash = { 'UserName' => user_name,
37
+ 'SerialNumber' => serial_number,
38
+ 'AuthenticationCode1' => auth_code1,
39
+ 'AuthenticationCode2' => auth_code2 }
40
+ link = generate_request("ResyncMFADevice", request_hash)
41
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
42
+ end
43
+
44
+ # Deactivates the specified MFA device and removes it from association with the User name for which it was originally enabled.
45
+ #
46
+ # deactivate_mfa_device('kd1', 'dev1234567890') #=> true
47
+ #
48
+ def deactivate_mfa_device(user_name, serial_number)
49
+ request_hash = { 'UserName' => user_name,
50
+ 'SerialNumber' => serial_number }
51
+ link = generate_request("DeactivateMFADevice", request_hash)
52
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
53
+ end
54
+
55
+ #-----------------------------------------------------------------
56
+ # PARSERS
57
+ #-----------------------------------------------------------------
58
+
59
+ class ListMFADevicesParser < BasicIamListParser #:nodoc:
60
+ def reset
61
+ @expected_tags = %w{ SerialNumber UserName }
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,251 @@
1
+ module RightAws
2
+
3
+ class IamInterface < RightAwsBase
4
+
5
+ #-----------------------------------------------------------------
6
+ # Users
7
+ #-----------------------------------------------------------------
8
+
9
+ # Lists the Users that have the specified path prefix.
10
+ #
11
+ # Options: :path_prefix, :max_items, :marker
12
+ #
13
+ # iam.list_users #=>
14
+ # [{:user_name=>"kd",
15
+ # :user_id=>"AI000000000000000006A",
16
+ # :arn=>"arn:aws:iam::640000000037:user/kd",
17
+ # :path=>"/"}]
18
+ #
19
+ def list_users(options={}, &block)
20
+ incrementally_list_iam_resources('ListUsers', options, &block)
21
+ end
22
+
23
+ # Creates a new User for your AWS Account.
24
+ #
25
+ # Options: :path
26
+ #
27
+ # iam.create_user('kd') #=>
28
+ # {:user_name=>"kd",
29
+ # :user_id=>"AI000000000000000006A",
30
+ # :arn=>"arn:aws:iam::640000000037:user/kd",
31
+ # :path=>"/"}
32
+ #
33
+ def create_user(user_name, options={})
34
+ request_hash = { 'UserName' => user_name }
35
+ request_hash['Path'] = options[:path] unless options[:path]
36
+ link = generate_request("CreateUser", request_hash)
37
+ request_info(link, GetUserParser.new(:logger => @logger))
38
+ end
39
+
40
+ # Updates the name and/or the path of the specified User.
41
+ #
42
+ # iam.update_user('kd1', :new_user_name => 'kd1', :new_path => '/kd1/') #=> true
43
+ #
44
+ def update_user(user_name, options={})
45
+ request_hash = { 'UserName' => user_name}
46
+ request_hash['NewUserName'] = options[:new_user_name] unless options[:new_user_name].right_blank?
47
+ request_hash['NewPath'] = options[:new_path] unless options[:new_path].right_blank?
48
+ link = generate_request("UpdateUser", request_hash)
49
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
50
+ end
51
+
52
+ # Retrieves information about the specified User, including the User's path, GUID, and ARN.
53
+ #
54
+ # iam.get_user('kd') #=>
55
+ # {:user_name=>"kd",
56
+ # :user_id=>"AI000000000000000006A",
57
+ # :arn=>"arn:aws:iam::640000000037:user/kd",
58
+ # :path=>"/"}
59
+ #
60
+ def get_user(user_name)
61
+ request_hash = { 'UserName' => user_name }
62
+ link = generate_request("GetUser", request_hash)
63
+ request_info(link, GetUserParser.new(:logger => @logger))
64
+ end
65
+
66
+ # Deletes the specified User. The User must not belong to any groups, have any keys or signing certificates, or have any attached policies.
67
+ #
68
+ # iam.delete_user('kd') #=> true
69
+ #
70
+ def delete_user(user_name)
71
+ request_hash = { 'UserName' => user_name }
72
+ link = generate_request("DeleteUser", request_hash)
73
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
74
+ end
75
+
76
+ #-----------------------------------------------------------------
77
+ # User Policies
78
+ #-----------------------------------------------------------------
79
+
80
+ # Lists the names of the policies associated with the specified User.
81
+ #
82
+ # Options: :max_items, :marker
83
+ #
84
+ # iam.list_user_policies('kd') #=> ["kd_user_policy_1"]
85
+ #
86
+ def list_user_policies(user_name, options={}, &block)
87
+ options[:user_name] = user_name
88
+ incrementally_list_iam_resources('ListUserPolicies', options, :parser => BasicIamListParser, &block)
89
+ end
90
+
91
+ # Adds (or updates) a policy document associated with the specified User
92
+ #
93
+ # iam.put_user_policy('kd', 'kd_user_policy_1', %Q({"Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]})) #=> true
94
+ #
95
+ def put_user_policy(user_name, policy_name, policy_document)
96
+ request_hash = { 'UserName' => user_name,
97
+ 'PolicyDocument' => policy_document,
98
+ 'PolicyName' => policy_name }
99
+ link = generate_request_impl(:post, "PutUserPolicy", request_hash)
100
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
101
+ end
102
+
103
+ # Retrieves the specified policy document for the specified User.
104
+ #
105
+ # iam.get_user_policy('kd','kd_user_policy_1') #=>
106
+ # {:user_name=>"kd",
107
+ # :policy_name=>"kd_user_policy_1",
108
+ # :policy_document=>"{\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"*\",\"Resource\":\"*\"}]}"}
109
+ #
110
+ def get_user_policy(user_name, policy_name)
111
+ request_hash = { 'UserName' => user_name,
112
+ 'PolicyName' => policy_name }
113
+ link = generate_request("GetUserPolicy", request_hash)
114
+ result = request_info(link, GetUserPolicyParser.new(:logger => @logger))
115
+ result[:policy_document] = URI::decode(result[:policy_document])
116
+ result
117
+ end
118
+
119
+ # Deletes the specified policy associated with the specified User.
120
+ #
121
+ # iam.delete_user_policy('kd','kd_user_policy_1') #=> true
122
+ #
123
+ def delete_user_policy(user_name, policy_name)
124
+ request_hash = { 'UserName' => user_name,
125
+ 'PolicyName' => policy_name }
126
+ link = generate_request("DeleteUserPolicy", request_hash)
127
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
128
+ end
129
+
130
+ #-----------------------------------------------------------------
131
+ # User Groups
132
+ #-----------------------------------------------------------------
133
+
134
+ # Lists the names of the policies associated with the specified group. If there are none,
135
+ # the action returns an empty list.
136
+ #
137
+ # Options: :max_items, :marker
138
+ #
139
+ # iam.list_groups_for_user('kd') #=>
140
+ # [{:group_name=>"kd_test_1",
141
+ # :group_id=>"AGP000000000000000UTY",
142
+ # :arn=>"arn:aws:iam::640000000037:group/kd1/kd_test_1",
143
+ # :path=>"/kd1/"}]
144
+ #
145
+ def list_groups_for_user(user_name, options={}, &block)
146
+ options[:user_name] = user_name
147
+ incrementally_list_iam_resources('ListGroupsForUser', options, :parser => ListGroupsParser, &block)
148
+ end
149
+
150
+ # Adds the specified User to the specified group.
151
+ #
152
+ # iam.add_user_to_group('kd', 'kd_test_1') #=> true
153
+ #
154
+ def add_user_to_group(user_name, group_name)
155
+ request_hash = { 'UserName' => user_name,
156
+ 'GroupName' => group_name }
157
+ link = generate_request("AddUserToGroup", request_hash)
158
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
159
+ end
160
+
161
+ # Removes the specified User from the specified group.
162
+ #
163
+ # iam.remove_user_from_group('kd', 'kd_test_1') #=> true
164
+ #
165
+ def remove_user_from_group(user_name, group_name)
166
+ request_hash = { 'UserName' => user_name,
167
+ 'GroupName' => group_name }
168
+ link = generate_request("RemoveUserFromGroup", request_hash)
169
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
170
+ end
171
+
172
+ #-----------------------------------------------------------------
173
+ # User Login Profiles
174
+ #-----------------------------------------------------------------
175
+
176
+ # Creates a login profile for the specified User, giving the User the ability to access
177
+ # AWS services such as the AWS Management Console.
178
+ #
179
+ # iam.create_login_profile('kd','q1w2e3r4t5') #=> { :user_name => 'kd' }
180
+ #
181
+ def create_login_profile(user_name, password)
182
+ request_hash = { 'UserName' => user_name,
183
+ 'Password' => password}
184
+ link = generate_request("CreateLoginProfile", request_hash)
185
+ request_info(link, GetLoginProfileParser.new(:logger => @logger))
186
+ end
187
+
188
+ # Updates the login profile for the specified User. Use this API to change the User's password.
189
+ #
190
+ # update_login_profile('kd', '00000000') #=> true
191
+ #
192
+ def update_login_profile(user_name, options={})
193
+ request_hash = { 'UserName' => user_name}
194
+ request_hash['Password'] = options[:password] unless options[:passwrod].right_blank?
195
+ link = generate_request("UpdateLoginProfile", request_hash)
196
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
197
+ end
198
+
199
+ # Retrieves the login profile for the specified User
200
+ #
201
+ # iam.create_login_profile('kd','q1w2e3r4t5') #=> { :user_name => 'kd' }
202
+ #
203
+ def get_login_profile(user_name)
204
+ request_hash = { 'UserName' => user_name }
205
+ link = generate_request("GetLoginProfile", request_hash)
206
+ request_info(link, GetLoginProfileParser.new(:logger => @logger))
207
+ end
208
+
209
+ # Deletes the login profile for the specified User, which terminates the User's ability to access
210
+ # AWS services through the IAM login page.
211
+ #
212
+ # iam.delete_login_profile('kd') #=> true
213
+ #
214
+ def delete_login_profile(user_name)
215
+ request_hash = { 'UserName' => user_name }
216
+ link = generate_request("DeleteLoginProfile", request_hash)
217
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
218
+ end
219
+
220
+ #-----------------------------------------------------------------
221
+ # PARSERS
222
+ #-----------------------------------------------------------------
223
+
224
+ class ListUsersParser < BasicIamListParser #:nodoc:
225
+ def reset
226
+ @expected_tags = %w{ Arn Path UserId UserName }
227
+ end
228
+ end
229
+
230
+ class GetUserParser < BasicIamParser #:nodoc:
231
+ def reset
232
+ @expected_tags = %w{ Arn Path UserId UserName }
233
+ end
234
+ end
235
+
236
+ class GetUserPolicyParser < BasicIamParser #:nodoc:
237
+ def reset
238
+ @expected_tags = %w{ PolicyDocument PolicyName UserName }
239
+ end
240
+ end
241
+
242
+ class GetLoginProfileParser < BasicIamParser #:nodoc:
243
+ def reset
244
+ @expected_tags = %w{ UserName }
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ end
251
+
@@ -0,0 +1,1384 @@
1
+ #
2
+ # Copyright (c) 2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ module RightAws
25
+
26
+ class RdsInterface < RightAwsBase
27
+
28
+ include RightAwsBaseInterface
29
+
30
+ API_VERSION = "2011-04-01"
31
+ DEFAULT_HOST = 'rds.amazonaws.com'
32
+ DEFAULT_PORT = 443
33
+ DEFAULT_PROTOCOL = 'https'
34
+ DEFAULT_PATH = '/'
35
+
36
+ DEFAULT_INSTANCE_CLASS = 'db.m1.small'
37
+ INSTANCE_CLASSES = ['db.m1.small', 'db.m1.large', 'db.m1.xlarge', 'db.m2.2xlarge', 'db.m2.2xlarge', 'db.m2.4xlarge']
38
+ LICENSE_MODELS = ['bring-your-own-license', 'license-included', 'general-public-license']
39
+
40
+ @@bench = AwsBenchmarkingBlock.new
41
+ def self.bench_xml
42
+ @@bench.xml
43
+ end
44
+ def self.bench_service
45
+ @@bench.service
46
+ end
47
+
48
+ # Create a new handle to a RDS account. All handles share the same per process or per thread
49
+ # HTTP connection to RDS. Each handle is for a specific account. The params have the
50
+ # following options:
51
+ # * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol). Example: 'https://rds.amazonaws.com'
52
+ # * <tt>:server</tt>: RDS service host, default: DEFAULT_HOST
53
+ # * <tt>:port</tt>: RDS service port, default: DEFAULT_PORT
54
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
55
+ # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
56
+ #
57
+ # rds = RightAws::RdsInterface.new('xxxxxxxxxxxxxxxxxxxxx','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
58
+ # {:logger => Logger.new('/tmp/x.log')}) #=> #<RightAws::RdsInterface::0xb7b3c30c>
59
+ #
60
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
61
+ init({ :name => 'RDS',
62
+ :default_host => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).host : DEFAULT_HOST,
63
+ :default_port => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).port : DEFAULT_PORT,
64
+ :default_service => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).path : DEFAULT_PATH,
65
+ :default_protocol => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).scheme : DEFAULT_PROTOCOL,
66
+ :default_api_version => ENV['RDS_API_VERSION'] || API_VERSION },
67
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
68
+ aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
69
+ params)
70
+ end
71
+
72
+ #-----------------------------------------------------------------
73
+ # Requests
74
+ #-----------------------------------------------------------------
75
+
76
+ # Generates request hash for REST API.
77
+ def generate_request(action, params={}) #:nodoc:
78
+ generate_request_impl(:get, action, params )
79
+ end
80
+
81
+ # Sends request to Amazon and parses the response.
82
+ # Raises AwsError if any banana happened.
83
+ def request_info(request, parser, &block) # :nodoc:
84
+ request_info_impl(:rds_connection, @@bench, request, parser, &block)
85
+ end
86
+
87
+ # Incrementally lists something.
88
+ def incrementally_list_items(action, parser_class, params={}, &block) # :nodoc:
89
+ params = params.dup
90
+ params['MaxRecords'] = params.delete(:max_records) if params[:max_records]
91
+ params['Marker'] = params.delete(:marker) if params[:marker]
92
+ last_response = nil
93
+ loop do
94
+ link = generate_request(action, params)
95
+ last_response = request_info( link, parser_class.new(:logger => @logger))
96
+ params['Marker'] = last_response[:marker]
97
+ break unless block && block.call(last_response) && !last_response[:marker].right_blank?
98
+ end
99
+ last_response
100
+ end
101
+
102
+ #-----------------------------------------------------------------
103
+ # API Calls:
104
+ #-----------------------------------------------------------------
105
+
106
+ # --------------------------------------------
107
+ # DB Instances
108
+ # --------------------------------------------
109
+
110
+ # List DB instances.
111
+ #
112
+ # Optional params: +:aws_id+, +:max_records+, +:marker+
113
+ #
114
+ # # Get a list of DB instances. The response is an +Array+ of instances.
115
+ # rds.describe_db_instances #=>
116
+ # [{:instance_class=>"db.m1.small",
117
+ # :status=>"creating",
118
+ # :backup_retention_period=>1,
119
+ # :read_replica_db_instance_identifiers=>["kd-delete-me-01-replica-01"],
120
+ # :master_username=>"username",
121
+ # :preferred_maintenance_window=>"sun:05:00-sun:09:00",
122
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
123
+ # :multi_az=>true,
124
+ # :engine=>"mysql",
125
+ # :auto_minor_version_upgrade=>false,
126
+ # :allocated_storage=>25,
127
+ # :availability_zone=>"us-east-1d",
128
+ # :aws_id=>"kd-delete-me-01",
129
+ # :preferred_backup_window=>"03:00-05:00",
130
+ # :engine_version=>"5.1.50",
131
+ # :pending_modified_values=>{:master_user_password=>"****"},
132
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}]}]
133
+ #
134
+ # # Retrieve a custom DB instance.
135
+ # # The response is an +Array+ with a single instance record.
136
+ # rds.describe_db_instances("kd-test-n3")
137
+ #
138
+ # # Incrementally a list DB instances. Every response part is a +Hash+.
139
+ # rds.describe_db_instances(:max_records => 30) do |x|
140
+ # puts x.inspect #=>
141
+ # {:db_instances=>
142
+ # [{:instance_class=>"db.m1.small",
143
+ # :status=>"creating",
144
+ # :backup_retention_period=>1,
145
+ # :read_replica_db_instance_identifiers=>["kd-delete-me-01-replica-01"],
146
+ # :master_username=>"username",
147
+ # :preferred_maintenance_window=>"sun:05:00-sun:09:00",
148
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
149
+ # :multi_az=>true,
150
+ # :engine=>"mysql",
151
+ # :auto_minor_version_upgrade=>false,
152
+ # :allocated_storage=>25,
153
+ # :availability_zone=>"us-east-1d",
154
+ # :aws_id=>"kd-delete-me-01",
155
+ # :preferred_backup_window=>"03:00-05:00",
156
+ # :engine_version=>"5.1.50",
157
+ # :pending_modified_values=>{:master_user_password=>"****"},
158
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}]}]}
159
+ # true
160
+ # end
161
+ #
162
+ def describe_db_instances(*params, &block)
163
+ item, params = AwsUtils::split_items_and_params(params)
164
+ params = params.dup
165
+ params['DBInstanceIdentifier'] = item.first unless item.right_blank?
166
+ result = []
167
+ incrementally_list_items('DescribeDBInstances', DescribeDbInstancesParser, params) do |response|
168
+ result += response[:db_instances]
169
+ block ? block.call(response) : true
170
+ end
171
+ result
172
+ end
173
+
174
+ # Create a new RDS instance of the type and size specified by you. The default storage engine for RDS Instances is InnoDB.
175
+ #
176
+ # Mandatory arguments: +aws_id+, +master_username+, +master_user_password+
177
+ # Optional params: +:allocated_storage+ (25 by def), +:instance_class+, +:engine+ ('MySQL' by def),
178
+ # +:endpoint_port+, +:db_name+, +:db_security_groups+, +:db_parameter_group+, +:availability_zone+, +:preferred_maintenance_window+
179
+ # +:backup_retention_period+, +:preferred_backup_window+, +:multi_az+, +:engine_version+, +:auto_minor_version_upgrade+,
180
+ # +:license_model+
181
+ #
182
+ # rds.create_db_instance('kd-delete-me-01', 'username', 'password',
183
+ # :instance_class => 'db.m1.small',
184
+ # :multi_az => true,
185
+ # :auto_minor_version_upgrade => false ) #=>
186
+ # {:instance_class=>"db.m1.small",
187
+ # :multi_az=>true,
188
+ # :status=>"creating",
189
+ # :backup_retention_period=>1,
190
+ # :read_replica_db_instance_identifiers=>[],
191
+ # :master_username=>"username",
192
+ # :preferred_maintenance_window=>"sun:05:00-sun:09:00",
193
+ # :auto_minor_version_upgrade=>false,
194
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
195
+ # :engine=>"mysql",
196
+ # :allocated_storage=>25,
197
+ # :aws_id=>"kd-delete-me-01",
198
+ # :preferred_backup_window=>"03:00-05:00",
199
+ # :engine_version=>"5.1.50",
200
+ # :pending_modified_values=>{:master_user_password=>"****"},
201
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}]}
202
+ #
203
+ def create_db_instance(aws_id, master_username, master_user_password, params={})
204
+ request_hash = {}
205
+ # Mandatory
206
+ request_hash['DBInstanceIdentifier'] = aws_id
207
+ request_hash['MasterUsername'] = master_username
208
+ request_hash['MasterUserPassword'] = master_user_password
209
+ # Mandatory with default values
210
+ request_hash['DBInstanceClass'] = params[:instance_class].right_blank? ? DEFAULT_INSTANCE_CLASS : params[:instance_class].to_s
211
+ request_hash['AllocatedStorage'] = params[:allocated_storage].right_blank? ? 25 : params[:allocated_storage]
212
+ request_hash['Engine'] = params[:engine].right_blank? ? 'mysql' : params[:engine]
213
+ # Optional
214
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
215
+ request_hash['DBName'] = params[:db_name] unless params[:db_name].right_blank?
216
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
217
+ request_hash['MultiAZ'] = params[:multi_az].to_s unless params[:multi_az].nil?
218
+ request_hash['PreferredMaintenanceWindow'] = params[:preferred_maintenance_window] unless params[:preferred_maintenance_window].right_blank?
219
+ request_hash['BackupRetentionPeriod'] = params[:backup_retention_period] unless params[:backup_retention_period].right_blank?
220
+ request_hash['PreferredBackupWindow'] = params[:preferred_backup_window] unless params[:preferred_backup_window].right_blank?
221
+ request_hash['DBParameterGroupName'] = params[:db_parameter_group] unless params[:db_parameter_group].right_blank?
222
+ request_hash['EngineVersion'] = params[:engine_version] unless params[:engine_version].right_blank?
223
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade].to_s unless params[:auto_minor_version_upgrade].nil?
224
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
225
+ request_hash.merge!(amazonize_list('DBSecurityGroups.member', params[:db_security_groups]))
226
+ link = generate_request('CreateDBInstance', request_hash)
227
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
228
+ end
229
+
230
+ # Modify a DB instance.
231
+ #
232
+ # Mandatory arguments: +aws_id+.
233
+ # Optional params: +:master_user_password+, +:instance_class+, +:db_security_groups+,
234
+ # +:db_parameter_group+, +:preferred_maintenance_window+, +:allocated_storage+, +:apply_immediately+,
235
+ # +:backup_retention_period+, +:preferred_backup_window+, +:multi_az+, +:engine_version+,
236
+ # +:auto_minor_version_upgrade+, +:allow_major_version_upgrade+
237
+ #
238
+ # rds.modify_db_instance('kd-delete-me-01',
239
+ # :master_user_password => 'newpassword',
240
+ # :instance_class => 'db.m1.large',
241
+ # :multi_az => false,
242
+ # :allocated_storage => 30,
243
+ # :allow_major_version_upgrade => true,
244
+ # :auto_minor_version_upgrade => true,
245
+ # :preferred_maintenance_window => 'sun:06:00-sun:10:00',
246
+ # :preferred_backup_window => '02:00-04:00',
247
+ # :apply_immediately => true,
248
+ # :backup_retention_period => 2) #=>
249
+ # {:engine_version=>"5.1.50",
250
+ # :aws_id=>"kd-delete-me-01",
251
+ # :multi_az=>true,
252
+ # :status=>"available",
253
+ # :read_replica_db_instance_identifiers=>[],
254
+ # :availability_zone=>"us-east-1d",
255
+ # :auto_minor_version_upgrade=>true,
256
+ # :master_username=>"username",
257
+ # :preferred_maintenance_window=>"sun:06:00-sun:10:00",
258
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
259
+ # :create_time=>"2010-11-17T10:21:59.720Z",
260
+ # :preferred_backup_window=>"02:00-04:00",
261
+ # :engine=>"mysql",
262
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}],
263
+ # :endpoint_address=>"kd-delete-me-01.chxspydgchoo.us-east-1.rds.amazonaws.com",
264
+ # :instance_class=>"db.m1.small",
265
+ # :latest_restorable_time=>"2010-11-17T10:27:17.089Z",
266
+ # :backup_retention_period=>2,
267
+ # :pending_modified_values=>
268
+ # {:multi_az=>false, :master_user_password=>"****", :allocated_storage=>30, :instance_class=>"db.m1.large"},
269
+ # :allocated_storage=>25}
270
+ #
271
+ def modify_db_instance(aws_id, params={})
272
+ request_hash = {}
273
+ # Mandatory
274
+ request_hash['DBInstanceIdentifier'] = aws_id
275
+ # Optional
276
+ request_hash['MasterUserPassword'] = params[:master_user_password] unless params[:master_user_password].right_blank?
277
+ request_hash['DBInstanceClass'] = params[:instance_class].to_s.capitalize unless params[:instance_class].right_blank?
278
+ request_hash['PreferredMaintenanceWindow'] = params[:preferred_maintenance_window] unless params[:preferred_maintenance_window].right_blank?
279
+ request_hash['BackupRetentionPeriod'] = params[:backup_retention_period] unless params[:backup_retention_period].right_blank?
280
+ request_hash['PreferredBackupWindow'] = params[:preferred_backup_window] unless params[:preferred_backup_window].right_blank?
281
+ request_hash['AllocatedStorage'] = params[:allocated_storage] unless params[:allocated_storage].right_blank?
282
+ request_hash['MultiAZ'] = params[:multi_az].to_s unless params[:multi_az].nil?
283
+ request_hash['EngineVersion'] = params[:engine_version] unless params[:engine_version].right_blank?
284
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade].to_s unless params[:auto_minor_version_upgrade].nil?
285
+ request_hash['AllowMajorVersionUpgrade'] = params[:allow_major_version_upgrade].to_s unless params[:allow_major_version_upgrade].nil?
286
+ request_hash['ApplyImmediately'] = params[:apply_immediately].to_s unless params[:apply_immediately].right_blank?
287
+ request_hash.merge!(amazonize_list('DBSecurityGroups.member', params[:db_security_groups]))
288
+ request_hash['DBParameterGroupName'] = params[:db_parameter_group] unless params[:db_parameter_group].right_blank?
289
+ link = generate_request('ModifyDBInstance', request_hash)
290
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
291
+ end
292
+
293
+ # Reboot Db instance.
294
+ #
295
+ # rds.reboot_db_instance('kd-my-awesome-db') #=>
296
+ # {:status=>"rebooting",
297
+ # :pending_modified_values=>{},
298
+ # :allocated_storage=>42,
299
+ # :master_username=>"kd",
300
+ # :db_security_groups=>[],
301
+ # :instance_class=>"Medium",
302
+ # :availability_zone=>"us-east-1a",
303
+ # :aws_id=>"kd-my-awesome-db",
304
+ # :create_time=>"2009-08-28T08:34:21.858Z",
305
+ # :engine=>"MySQL5.1",
306
+ # :preferred_maintenance_window=>"Sun:05:00-Sun:09:00"}
307
+ #
308
+ def reboot_db_instance(aws_id, params={})
309
+ params = params.dup
310
+ params['DBInstanceIdentifier'] = aws_id
311
+ link = generate_request('RebootDBInstance', params)
312
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
313
+ end
314
+
315
+ # Delete a DB instance
316
+ #
317
+ # Mandatory arguments: aws_id
318
+ # Optional params: :skip_final_snapshot ('false' by def),
319
+ # :snapshot_aws_id ('{instance_aws_id}-final-snapshot-YYYYMMDDHHMMSS')
320
+ #
321
+ # rds.delete_db_instance('my-awesome-db-g2') #=> true
322
+ #
323
+ def delete_db_instance(aws_id, params={})
324
+ request_hash = {}
325
+ request_hash['DBInstanceIdentifier'] = aws_id
326
+ request_hash['SkipFinalSnapshot'] = params.has_key?(:skip_final_snapshot) ? params[:skip_final_snapshot].to_s : 'false'
327
+ if request_hash['SkipFinalSnapshot'] == 'false' && params[:snapshot_aws_id].right_blank?
328
+ params = params.dup
329
+ params[:snapshot_aws_id] = "#{aws_id}-final-snapshot-#{Time.now.utc.strftime('%Y%m%d%H%M%S')}"
330
+ end
331
+ request_hash['FinalDBSnapshotIdentifier'] = params[:snapshot_aws_id] unless params[:snapshot_aws_id].right_blank?
332
+ link = generate_request('DeleteDBInstance', request_hash)
333
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
334
+ end
335
+
336
+ # --------------------------------------------
337
+ # DB SecurityGroups
338
+ # --------------------------------------------
339
+ #
340
+ # rds.describe_db_security_groups #=>
341
+ # [{:owner_id=>"82...25",
342
+ # :description=>"Default",
343
+ # :ec2_security_groups=>[],
344
+ # :ip_ranges=>[],
345
+ # :name=>"Default"},
346
+ # {:owner_id=>"82...25",
347
+ # :description=>"kd",
348
+ # :ec2_security_groups=>[],
349
+ # :ip_ranges=>[],
350
+ # :name=>"kd2"},
351
+ # {:owner_id=>"82...25",
352
+ # :description=>"kd",
353
+ # :ec2_security_groups=>
354
+ # [{:status=>"Authorized", :owner_id=>"82...23", :name=>"default"},
355
+ # {:status=>"Authorized", :owner_id=>"82...24", :name=>"default1"},
356
+ # {:status=>"Authorized", :owner_id=>"82...25", :name=>"default"},
357
+ # {:status=>"Authorized", :owner_id=>"82...26", :name=>"default"},
358
+ # {:status=>"Authorized", :owner_id=>"82...26", :name=>"default1"},
359
+ # {:status=>"Authorized", :owner_id=>"82...29", :name=>"default22"}],
360
+ # :ip_ranges=>
361
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
362
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
363
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
364
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
365
+ # {:status=>"Authorized", :cidrip=>"131.0.0.1/8"}],
366
+ # :name=>"kd3"}]
367
+ #
368
+ # # get a custom group
369
+ # rds.describe_db_security_groups('kd3')
370
+ #
371
+ def describe_db_security_groups(*db_security_group_name, &block)
372
+ items, params = AwsUtils::split_items_and_params(db_security_group_name)
373
+ params['DBSecurityGroupName'] = items.first unless items.right_blank?
374
+ result = []
375
+ incrementally_list_items('DescribeDBSecurityGroups', DescribeDbSecurityGroupsParser, params) do |response|
376
+ result += response[:db_security_groups]
377
+ block ? block.call(response) : true
378
+ end
379
+ result
380
+ end
381
+
382
+ # Create a database security group so that ingress to an RDS Instance can be controlled.
383
+ # A new security group cannot have the same name as an existing group.
384
+ #
385
+ # ds.create_db_security_group('kd3', 'kd') #=>
386
+ # {:ec2_security_groups=>[],
387
+ # :description=>"kd",
388
+ # :ip_ranges=>[],
389
+ # :name=>"kd3",
390
+ # :owner_id=>"82...25"}
391
+ #
392
+ def create_db_security_group(db_security_group_name, db_security_group_description)
393
+ link = generate_request('CreateDBSecurityGroup', 'DBSecurityGroupName' => db_security_group_name,
394
+ 'DBSecurityGroupDescription' => db_security_group_description)
395
+ request_info(link, DescribeDbSecurityGroupsParser.new(:logger => @logger))[:db_security_groups].first
396
+ end
397
+
398
+ def modify_db_security_group_ingress(action, db_security_group_name, params={}) # :nodoc:
399
+ request_hash = { 'DBSecurityGroupName' => db_security_group_name}
400
+ request_hash['CIDRIP'] = params[:cidrip] unless params[:cidrip].right_blank?
401
+ request_hash['EC2SecurityGroupName'] = params[:ec2_security_group_name] unless params[:ec2_security_group_name].right_blank?
402
+ request_hash['EC2SecurityGroupOwnerId'] = params[:ec2_security_group_owner] unless params[:ec2_security_group_owner].right_blank?
403
+ link = generate_request(action, request_hash)
404
+ request_info(link, DescribeDbSecurityGroupsParser.new(:logger => @logger))[:db_security_groups].first
405
+ end
406
+
407
+ # Authorize an ingress. Params: +:cidrip+ or (+:ec2_security_group_name+ and +:ec2_security_group_owner+)
408
+ #
409
+ # rds.authorize_db_security_group_ingress('kd3', :cidrip => '131.0.0.1/8')
410
+ # {:owner_id=>"82...25",
411
+ # :ec2_security_groups=>[],
412
+ # :description=>"kd",
413
+ # :ip_ranges=>
414
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
415
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
416
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
417
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
418
+ # {:status=>"Authorizing", :cidrip=>"131.0.0.1/8"}],
419
+ # :name=>"kd3"}
420
+ #
421
+ # rds.authorize_db_security_group_ingress('kd3',:ec2_security_group_owner => '82...27',
422
+ # :ec2_security_group_name => 'default') #=>
423
+ # {:owner_id=>"82...25",
424
+ # :ec2_security_groups=>
425
+ # [{:status=>"Authorized", :owner_id=>"82...25", :name=>"g1"},
426
+ # {:status=>"Authorized", :owner_id=>"82...26", :name=>"g2"},
427
+ # {:status=>"Authorizing", :owner_id=>"82...27", :name=>"default"}],
428
+ # :ip_ranges=>
429
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
430
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
431
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
432
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
433
+ # {:status=>"Authorized", :cidrip=>"131.0.0.1/8"}],
434
+ # :name=>"kd3"}
435
+ #
436
+ def authorize_db_security_group_ingress(db_security_group_name, params={})
437
+ modify_db_security_group_ingress('AuthorizeDBSecurityGroupIngress', db_security_group_name, params)
438
+ end
439
+
440
+ # Revoke an ingress.
441
+ # Optional params: +:cidrip+ or (+:ec2_security_group_name+ and +:ec2_security_group_owner+)
442
+ #
443
+ # rds.revoke_db_security_group_ingress('kd3', :ec2_security_group_owner => '82...25',
444
+ # :ec2_security_group_name => 'default') #=>
445
+ # {:owner_id=>"82...25",
446
+ # :ec2_security_groups=>
447
+ # [{:status=>"Revoking", :owner_id=>"826693181925", :name=>"default"}],
448
+ # :name=>"kd3",
449
+ # :description=>"kd",
450
+ # :ip_ranges=>
451
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
452
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
453
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
454
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
455
+ # {:status=>"Authorized", :cidrip=>"131.0.0.1/8"}]}
456
+ #
457
+ def revoke_db_security_group_ingress(db_security_group_name, params={})
458
+ modify_db_security_group_ingress('RevokeDBSecurityGroupIngress', db_security_group_name, params)
459
+ end
460
+
461
+ # Delete a database security group. Database security group must not be associated with any
462
+ # RDS Instances.
463
+ #
464
+ # rds.delete_db_security_group('kd3') #=> true
465
+ #
466
+ def delete_db_security_group(db_security_group_name)
467
+ link = generate_request('DeleteDBSecurityGroup', 'DBSecurityGroupName' => db_security_group_name)
468
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
469
+ end
470
+
471
+ # --------------------------------------------
472
+ # DB ParameterGroups
473
+ # --------------------------------------------
474
+
475
+ # Describe DBParameterGroups.
476
+ #
477
+ # rds.describe_db_parameter_groups #=>
478
+ # [{:engine=>"MySQL5.1",
479
+ # :description=>"Default parameter group for MySQL5.1",
480
+ # :name=>"default.MySQL5.1"}]
481
+ #
482
+ # # List parameter groups by 20
483
+ # rds.describe_db_parameter_groups(:max_records=>20) do |response|
484
+ # puts response.inspect
485
+ # true
486
+ # end
487
+ #
488
+ def describe_db_parameter_groups(*db_parameter_group_name, &block)
489
+ items, params = AwsUtils::split_items_and_params(db_parameter_group_name)
490
+ params['DBParameterGroupName'] = items.first unless items.right_blank?
491
+ result = []
492
+ incrementally_list_items('DescribeDBParameterGroups', DescribeDbParameterGroupsParser, params) do |response|
493
+ result += response[:db_parameter_groups]
494
+ block ? block.call(response) : true
495
+ end
496
+ result
497
+ end
498
+
499
+ # Creates a database parameter group so that configuration of an RDS Instance can be controlled.
500
+ #
501
+ # rds.create_db_parameter_group('my-new-group-1','My new group') #=> {}
502
+ #
503
+ # TODO: this call returns an empty hash, but should be a parameter group data - ask Amazon guys.
504
+ #
505
+ def create_db_parameter_group(db_parameter_group_name, db_parameter_group_description, db_parameter_group_family='mysql5.1', params={})
506
+ params['DBParameterGroupName'] = db_parameter_group_name
507
+ params['Description'] = db_parameter_group_description
508
+ params['DBParameterGroupFamily'] = db_parameter_group_family
509
+ link = generate_request('CreateDBParameterGroup', params )
510
+ request_info(link, DescribeDbParameterGroupsParser.new(:logger => @logger))[:db_parameter_groups].first
511
+ end
512
+
513
+ # Modify DBParameterGroup paramaters. Up to 20 params can be midified at once.
514
+ #
515
+ # rds.modify_db_parameter_group('kd1', 'max_allowed_packet' => 2048) #=> true
516
+ #
517
+ # rds.modify_db_parameter_group('kd1', 'max_allowed_packet' => {:value => 2048, :method => 'immediate') #=> true
518
+ #
519
+ def modify_db_parameter_group(db_parameter_group_name, params={}) # :nodoc:
520
+ request_hash = { 'DBParameterGroupName' => db_parameter_group_name}
521
+ parameters = []
522
+ params.each do |key, value|
523
+ method = 'pending-reboot'
524
+ if value.is_a?(Hash)
525
+ method = value[:method] unless value[:method].right_blank?
526
+ value = value[:value]
527
+ end
528
+ parameters << [key, value, method]
529
+ end
530
+ request_hash.merge!( amazonize_list(['Parameters.member.?.ParameterName',
531
+ 'Parameters.member.?.ParameterValue',
532
+ 'Parameters.member.?.ApplyMethod'],
533
+ parameters ))
534
+ link = generate_request('ModifyDBParameterGroup', request_hash)
535
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
536
+ end
537
+
538
+ # Delete DBParameter Group.
539
+ #
540
+ # rds.delete_db_parameter_group('kd1') #=> true
541
+ #
542
+ def delete_db_parameter_group(db_parameter_group_name)
543
+ link = generate_request('DeleteDBParameterGroup', 'DBParameterGroupName' => db_parameter_group_name)
544
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
545
+ end
546
+
547
+ # Modify the parameters of a DBParameterGroup to the engine/system default value.
548
+ #
549
+ # # Reset all parameters
550
+ # rds.reset_db_parameter_group('kd2', :all ) #=> true
551
+ #
552
+ # # Reset custom parameters
553
+ # rds.reset_db_parameter_group('kd2', 'max_allowed_packet', 'auto_increment_increment' ) #=> true
554
+ # rds.reset_db_parameter_group('kd2', 'max_allowed_packet', 'auto_increment_increment' => 'immediate' ) #=> true
555
+ #
556
+ def reset_db_parameter_group(db_parameter_group_name, *params)
557
+ params = params.flatten
558
+ request_hash = { 'DBParameterGroupName' => db_parameter_group_name }
559
+ if params.first.to_s == 'all'
560
+ request_hash['ResetAllParameters'] = true
561
+ else
562
+ tmp = []
563
+ params.each{ |item| tmp |= item.to_a }
564
+ params = []
565
+ tmp.each do |key, method|
566
+ method = 'pending-reboot' unless method
567
+ params << [key, method]
568
+ end
569
+ request_hash.merge!( amazonize_list(['Parameters.member.?.ParameterName',
570
+ 'Parameters.member.?.ApplyMethod'],
571
+ params ))
572
+ end
573
+ link = generate_request('ResetDBParameterGroup', request_hash)
574
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
575
+ end
576
+
577
+ # Get the detailed parameters list for a particular DBParameterGroup.
578
+ #
579
+ # rds.describe_db_parameters('kd1') #=>
580
+ # [{:is_modifiable=>true,
581
+ # :apply_type=>"static",
582
+ # :source=>"engine-default",
583
+ # :allowed_values=>"ON,OFF",
584
+ # :description=>"Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded",
585
+ # :name=>"allow-suspicious-udfs",
586
+ # :data_type=>"boolean"},
587
+ # {:is_modifiable=>true,
588
+ # :apply_type=>"dynamic",
589
+ # :source=>"engine-default",
590
+ # :allowed_values=>"1-65535",
591
+ # :description=>"Intended for use with master-to-master replication, and can be used to control the operation of AUTO_INCREMENT columns",
592
+ # :name=>"auto_increment_increment",
593
+ # :data_type=>"integer"}, ... ]
594
+ #
595
+ # # List parameters by 20
596
+ # rds.describe_db_parameters('kd1', :max_records=>20) do |response|
597
+ # puts response.inspect
598
+ # true
599
+ # end
600
+ #
601
+ def describe_db_parameters(*db_parameter_group_name, &block)
602
+ item, params = AwsUtils::split_items_and_params(db_parameter_group_name)
603
+ params['DBParameterGroupName'] = item
604
+ result = []
605
+ incrementally_list_items('DescribeDBParameters', DescribeDbParametersParser, params) do |response|
606
+ result += response[:parameters]
607
+ block ? block.call(response) : true
608
+ end
609
+ result
610
+ end
611
+
612
+ # Describe a default parameters for the parameter group family.
613
+ #
614
+ # rds.describe_engine_default_parameters('MySQL5.1') #=>
615
+ # [{:is_modifiable=>true,
616
+ # :apply_type=>"static",
617
+ # :source=>"engine-default",
618
+ # :allowed_values=>"ON,OFF",
619
+ # :description=>"Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded",
620
+ # :name=>"allow-suspicious-udfs",
621
+ # :data_type=>"boolean"},
622
+ # {:is_modifiable=>true,
623
+ # :apply_type=>"dynamic",
624
+ # :source=>"engine-default",
625
+ # :allowed_values=>"1-65535",
626
+ # :description=>"Intended for use with master-to-master replication, and can be used to control the operation of AUTO_INCREMENT columns",
627
+ # :name=>"auto_increment_increment",
628
+ # :data_type=>"integer"}, ... ]
629
+ #
630
+ def describe_engine_default_parameters(*db_parameter_group_family, &block)
631
+ db_parameter_group_family = ['MySQL5.1'] if db_parameter_group_family.right_blank?
632
+ item, params = AwsUtils::split_items_and_params(db_parameter_group_family)
633
+ params['DBParameterGroupFamily'] = item if item
634
+ result = []
635
+ incrementally_list_items('DescribeEngineDefaultParameters', DescribeDbParametersParser, params) do |response|
636
+ result += response[:parameters]
637
+ block ? block.call(response) : true
638
+ end
639
+ result
640
+ end
641
+
642
+ # Describe a list of orderable DB Instance options for the specified engine.
643
+ # Optionals: +:instance_class+, +:engine_version+ , +:license_model+
644
+ #
645
+ # rds.describe_orderable_db_instance_options('oracle-ee', :engine_version => '11.2.0.2.v2') #=>
646
+ # [{:read_replica_capable=>false,
647
+ # :instance_class=>"db.m1.large",
648
+ # :availability_zones=>["us-east-1a", "us-east-1b", "us-east-1d"],
649
+ # :engine=>"oracle-ee",
650
+ # :license_model=>"bring-your-own-license",
651
+ # :engine_version=>"11.2.0.2.v2",
652
+ # :multi_az_capable=>"false"}, ... ]
653
+ #
654
+ def describe_orderable_db_instance_options(engine, params={}, &block)
655
+ request_hash = { 'Engine' => engine }
656
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
657
+ request_hash['EngineVersion'] = params[:engine_version] unless params[:engine_version].right_blank?
658
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
659
+ result = []
660
+ incrementally_list_items('DescribeOrderableDBInstanceOptions', DescribeOrderableDBInstanceOptionsParser, request_hash) do |response|
661
+ result += response[:items]
662
+ block ? block.call(response) : true
663
+ end
664
+ result
665
+ end
666
+
667
+ # --------------------------------------------
668
+ # DB Snapshots
669
+ # --------------------------------------------
670
+
671
+ # Get DBSecurityGroup details for a particular customer or for a particular DBSecurityGroup if a name is specified.
672
+ # Optional params: +:instance_aws_id+
673
+ #
674
+ # # all snapshots
675
+ # rds.describe_db_snapshots #=>
676
+ # [{:status=>"Available",
677
+ # :instance_aws_id=>"kd-test-n1",
678
+ # :allocated_storage=>25,
679
+ # :availability_zone=>"us-east-1b",
680
+ # :aws_id=>"kd-test-n1-final-snapshot-at-20090630131215",
681
+ # :engine=>"MySQL5.1",
682
+ # :endpoint_port=>3306,
683
+ # :instance_create_time=>"2009-06-30T12:48:15.590Z",
684
+ # :master_username=>"payless",
685
+ # :snapshot_time=>"2009-06-30T13:16:48.496Z"}, ...]
686
+ #
687
+ # # all snapshots for a custom instance
688
+ # rds.describe_db_snapshots(:instance_aws_id => 'kd-test-n3') #=>
689
+ # [{:status=>"Available",
690
+ # :instance_aws_id=>"kd-test-n3",
691
+ # :allocated_storage=>25,
692
+ # :availability_zone=>"us-east-1a",
693
+ # :aws_id=>"kd-test-n3-final-snapshot-20090713074916",
694
+ # :engine=>"MySQL5.1",
695
+ # :endpoint_port=>3306,
696
+ # :instance_create_time=>"2009-06-30T12:51:32.540Z",
697
+ # :master_username=>"payless",
698
+ # :snapshot_time=>"2009-07-13T07:52:35.542Z"}]
699
+ #
700
+ # # a snapshot by id
701
+ # rds.describe_db_snapshots('my-awesome-db-final-snapshot-20090713075554') #=>
702
+ # [{:status=>"Available",
703
+ # :allocated_storage=>25,
704
+ # :engine=>"MySQL5.1",
705
+ # :instance_aws_id=>"my-awesome-db",
706
+ # :availability_zone=>"us-east-1a",
707
+ # :instance_create_time=>"2009-07-13T07:53:08.912Z",
708
+ # :endpoint_port=>3306,
709
+ # :master_username=>"medium",
710
+ # :aws_id=>"my-awesome-db-final-snapshot-20090713075554",
711
+ # :snapshot_time=>"2009-07-13T07:59:17.537Z"}]
712
+ #
713
+ def describe_db_snapshots(params={}, &block)
714
+ item, params = AwsUtils::split_items_and_params(params)
715
+ params['DBSnapshotIdentifier'] = item if item
716
+ params['DBInstanceIdentifier'] = params.delete(:instance_aws_id) unless params[:instance_aws_id].right_blank?
717
+ result = []
718
+ incrementally_list_items('DescribeDBSnapshots', DescribeDbSnapshotsParser, params) do |response|
719
+ result += response[:db_snapshots]
720
+ block ? block.call(response) : true
721
+ end
722
+ result
723
+ end
724
+
725
+ # Create a DBSnapshot. The source DBInstance must be in Available state
726
+ #
727
+ # rds.create_db_snapshot('remove-me-tomorrow-2', 'my-awesome-db-g7' ) #=>
728
+ # {:status=>"PendingCreation",
729
+ # :allocated_storage=>50,
730
+ # :availability_zone=>"us-east-1b",
731
+ # :engine=>"MySQL5.1",
732
+ # :aws_id=>"remove-me-tomorrow-2",
733
+ # :instance_create_time=>"2009-07-13T09:35:39.243Z",
734
+ # :endpoint_port=>3306,
735
+ # :instance_aws_id=>"my-awesome-db-g7",
736
+ # :db_master_username=>"username"}
737
+ #
738
+ def create_db_snapshot(aws_id, instance_aws_id)
739
+ link = generate_request('CreateDBSnapshot', 'DBSnapshotIdentifier' => aws_id,
740
+ 'DBInstanceIdentifier' => instance_aws_id)
741
+ request_info(link, DescribeDbSnapshotsParser.new(:logger => @logger))[:db_snapshots].first
742
+ end
743
+
744
+ # Create a new RDS instance from a DBSnapshot. The source DBSnapshot must be
745
+ # in the "Available" state. The new RDS instance is created with the Default security group.
746
+ #
747
+ # Optional params: +:instance_class+, +:endpoint_port+, +:availability_zone+, +:multi_az+,
748
+ # +:auto_minor_version_upgrade+, +:license_model+, +:db_name+, +:engine+
749
+ #
750
+ # rds.restore_db_instance_from_db_snapshot('ahahahaha-final-snapshot-20090828081159', 'q1') #=>
751
+ # {:status=>"creating",
752
+ # :pending_modified_values=>{},
753
+ # :allocated_storage=>42,
754
+ # :db_security_groups=>[],
755
+ # :master_username=>"kd",
756
+ # :availability_zone=>"us-east-1a",
757
+ # :aws_id=>"q1",
758
+ # :create_time=>"2009-08-29T18:07:01.510Z",
759
+ # :instance_class=>"Medium",
760
+ # :preferred_maintenance_window=>"Sun:05:00-Sun:09:00",
761
+ # :engine=>"MySQL",
762
+ # :engine_version=>"5.1.49"}
763
+ #
764
+ def restore_db_instance_from_db_snapshot(snapshot_aws_id, instance_aws_id, params={})
765
+ request_hash = { 'DBSnapshotIdentifier' => snapshot_aws_id,
766
+ 'DBInstanceIdentifier' => instance_aws_id }
767
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
768
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
769
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
770
+ request_hash['MultiAZ'] = params[:multi_az] unless params[:multi_az].nil?
771
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade] unless params[:auto_minor_version_upgrade].nil?
772
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
773
+ request_hash['DBName'] = params[:db_name] unless params[:db_name].right_blank?
774
+ request_hash['Engine'] = params[:engine] unless params[:enginel].right_blank?
775
+ link = generate_request('RestoreDBInstanceFromDBSnapshot', request_hash)
776
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
777
+ end
778
+
779
+ # Create a new RDS instance from a point-in-time system snapshot. The target
780
+ # database is created from the source database restore point with the same configuration as
781
+ # the original source database, except that the new RDS instance is created with the default
782
+ # security group.
783
+ #
784
+ # Optional params: +:instance_class+, +:endpoint_port+, +:availability_zone+, +:multi_az+, +:restore_time+,
785
+ # +:auto_minor_version_upgrade+, +:use_latest_restorable_time+, +:license_model+, +:db_name+, +:engine+
786
+ #
787
+ def restore_db_instance_to_point_in_time(instance_aws_id, new_instance_aws_id, params={})
788
+ request_hash = { 'SourceDBInstanceIdentifier' => instance_aws_id,
789
+ 'TargetDBInstanceIdentifier' => new_instance_aws_id}
790
+ request_hash['UseLatestRestorableTime'] = params[:use_latest_restorable_time].to_s unless params[:use_latest_restorable_time].nil?
791
+ request_hash['RestoreTime'] = params[:restore_time] unless params[:restore_time].right_blank?
792
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
793
+ request_hash['MultiAZ'] = params[:multi_az] unless params[:multi_az].nil?
794
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
795
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
796
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade] unless params[:auto_minor_version_upgrade].nil?
797
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
798
+ request_hash['DBName'] = params[:db_name] unless params[:db_name].right_blank?
799
+ request_hash['Engine'] = params[:engine] unless params[:enginel].right_blank?
800
+ link = generate_request('RestoreDBInstanceToPointInTime', request_hash)
801
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
802
+ end
803
+
804
+ # Delete a DBSnapshot. The DBSnapshot must be in the Available state to be deleted.
805
+ #
806
+ # rds.delete_db_snapshot('remove-me-tomorrow-1') #=>
807
+ # {:status=>"Deleted",
808
+ # :allocated_storage=>50,
809
+ # :instance_create_time=>"2009-07-13T09:27:01.053Z",
810
+ # :availability_zone=>"us-east-1a",
811
+ # :db_master_username=>"username",
812
+ # :aws_id=>"remove-me-tomorrow-1",
813
+ # :snapshot_time=>"2009-07-13T10:59:30.227Z",
814
+ # :endpoint_port=>3306,
815
+ # :instance_aws_id=>"my-awesome-db-g5",
816
+ # :engine=>"MySQL5.1"}
817
+ #
818
+ def delete_db_snapshot(aws_id)
819
+ link = generate_request('DeleteDBSnapshot', 'DBSnapshotIdentifier' => aws_id)
820
+ request_info(link, DescribeDbSnapshotsParser.new(:logger => @logger))[:db_snapshots].first
821
+ end
822
+
823
+ # --------------------------------------------
824
+ # DB Events
825
+ # --------------------------------------------
826
+
827
+ # Get events related to RDS instances and DBSecurityGroups for the past 14 days.
828
+ # Optional params: +:duration+, +:start_time+, +:end_time+, +:aws_id+,
829
+ # +:source_type+('db-instance', 'db-security-group', 'db-snapshot', 'db-parameter-group')
830
+ #
831
+ # # get all enevts
832
+ # rds.describe_events #=>
833
+ # [{:aws_id=>"my-awesome-db-g4",
834
+ # :source_type=>"DBInstance",
835
+ # :message=>"Started user snapshot for database instance:my-awesome-db-g4",
836
+ # :date=>"2009-07-13T10:54:13.661Z"},
837
+ # {:aws_id=>"my-awesome-db-g5",
838
+ # :source_type=>"DBInstance",
839
+ # :message=>"Started user snapshot for database instance:my-awesome-db-g5",
840
+ # :date=>"2009-07-13T10:55:13.674Z"},
841
+ # {:aws_id=>"my-awesome-db-g7",
842
+ # :source_type=>"DBInstance",
843
+ # :message=>"Started user snapshot for database instance:my-awesome-db-g7",
844
+ # :date=>"2009-07-13T10:56:34.226Z"}]
845
+ #
846
+ # # get all events since yesterday
847
+ # rds.describe_events(:start_date => 1.day.ago)
848
+ #
849
+ # # get last 60 min events
850
+ # rds.describe_events(:duration => 60)
851
+ #
852
+ def describe_events(params={}, &block)
853
+ params = params.dup
854
+ params['SourceIdentifier'] = params.delete(:aws_id) unless params[:aws_id].right_blank?
855
+ params['SourceType'] = params.delete(:source_type) unless params[:source_type].right_blank?
856
+ params['Duration'] = params.delete(:duration) unless params[:duration].right_blank?
857
+ params['StartDate'] = fix_date(params.delete(:start_date)) unless params[:start_date].right_blank?
858
+ params['EndDate'] = fix_date(params.delete(:end_date)) unless params[:end_date].right_blank?
859
+ result = []
860
+ incrementally_list_items('DescribeEvents', DescribeEventsParser, params) do |response|
861
+ result += response[:events]
862
+ block ? block.call(response) : true
863
+ end
864
+ result
865
+ end
866
+
867
+ def fix_date(date) # :nodoc:
868
+ date = Time.at(date) if date.is_a?(Fixnum)
869
+ date = date.utc.strftime('%Y-%m-%dT%H:%M:%SZ') if date.is_a?(Time)
870
+ date
871
+ end
872
+
873
+ # --------------------------------------------
874
+ # DB Engine Versions
875
+ # --------------------------------------------
876
+
877
+ # Get a list of the available DB engines.
878
+ # Optional params: +:db_parameter_group_family+, +:default_only+, +:engine+, +:engine_version+
879
+ #
880
+ # rds.describe_db_engine_versions #=>
881
+ # [{:db_parameter_group_family=>"mysql5.1",
882
+ # :engine=>"mysql",
883
+ # :db_engine_description=>"MySQL Community Edition",
884
+ # :db_engine_version_description=>"Mysql 5.1.45",
885
+ # :engine_version=>"5.1.45"},
886
+ # {:db_parameter_group_family=>"oracle-se1-11.2",
887
+ # :engine=>"oracle-se1",
888
+ # :db_engine_description=>"Oracle Database Standard Edition One",
889
+ # :db_engine_version_description=>
890
+ # "Oracle Standard Edition One - DB Engine Version 11.2.0.2.v2",
891
+ # :engine_version=>"11.2.0.2.v2"}]
892
+ #
893
+ def describe_db_engine_versions(params={}, &block)
894
+ params = params.dup
895
+ params['DBParameterGroupFamily'] = params.delete(:db_parameter_group_family) unless params[:db_parameter_group_family].right_blank?
896
+ params['DefaultOnly'] = params.delete(:default_only).to_s unless params[:default_only].nil?
897
+ params['Engine'] = params.delete(:engine) unless params[:engine].right_blank?
898
+ params['EngineVersion'] = params.delete(:engine_version) unless params[:engine_version].right_blank?
899
+ result = []
900
+ incrementally_list_items('DescribeDBEngineVersions', DescribeDBEngineVersionsParser, params) do |response|
901
+ result += response[:db_engine_versions]
902
+ block ? block.call(response) : true
903
+ end
904
+ result
905
+ end
906
+
907
+ # --------------------------------------------
908
+ # DB Replicas
909
+ # --------------------------------------------
910
+
911
+ # Create a DB Instance that acts as a Read Replica of a source DB Instance.
912
+ #
913
+ # Optional params: +:endpoint_port+, +:availability_zone+, +:instance_class+, +:auto_minor_version_upgrade+
914
+ #
915
+ # rds.create_db_instance_read_replica('kd-delete-me-01-replica-01', 'kd-delete-me-01',
916
+ # :instance_class => 'db.m1.small',
917
+ # :endpoint_port => '11000',
918
+ # :auto_minor_version_upgrade => false ) #=>
919
+ # {:auto_minor_version_upgrade=>false,
920
+ # :read_replica_source_db_instance_identifier=>"kd-delete-me-01",
921
+ # :status=>"creating",
922
+ # :backup_retention_period=>0,
923
+ # :allocated_storage=>30,
924
+ # :read_replica_db_instance_identifiers=>[],
925
+ # :engine_version=>"5.1.50",
926
+ # :aws_id=>"kd-delete-me-01-replica-01",
927
+ # :multi_az=>false,
928
+ # :preferred_maintenance_window=>"sun:06:00-sun:10:00",
929
+ # :master_username=>"username",
930
+ # :preferred_backup_window=>"02:00-04:00",
931
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
932
+ # :engine=>"mysql",
933
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}],
934
+ # :instance_class=>"db.m1.small",
935
+ # :pending_modified_values=>{}}
936
+ #
937
+ def create_db_instance_read_replica(aws_id, source_db_instance_identifier, params={})
938
+ request_hash = { 'DBInstanceIdentifier' => aws_id,
939
+ 'SourceDBInstanceIdentifier' => source_db_instance_identifier}
940
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
941
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
942
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
943
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade].to_s unless params[:auto_minor_version_upgrade].nil?
944
+ link = generate_request('CreateDBInstanceReadReplica', request_hash)
945
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
946
+ end
947
+
948
+
949
+ #---------------------------------------------
950
+ # Reserved Instances
951
+ #---------------------------------------------
952
+
953
+ # Lists available reserved DB Instance offerings.
954
+ # Options: :aws_id, :instance_class, :duration, :product_description, :multi_az
955
+ #
956
+ # rds.describe_reserved_db_instances_offerings #=>
957
+ # [{:usage_price=>0.262,
958
+ # :offering_aws_id=>"248e7b75-2451-4381-9025-b5553d421c7b",
959
+ # :multi_az=>false,
960
+ # :duration=>31536000,
961
+ # :currency_code=>"USD",
962
+ # :instance_class=>"db.m2.xlarge",
963
+ # :product_description=>"mysql",
964
+ # :fixed_price=>1325.0},
965
+ # {:usage_price=>0.092,
966
+ # :offering_aws_id=>"248e7b75-49a7-4cd7-9a9b-354f4906a9b1",
967
+ # :multi_az=>true,
968
+ # :duration=>94608000,
969
+ # :currency_code=>"USD",
970
+ # :instance_class=>"db.m1.small",
971
+ # :product_description=>"mysql",
972
+ # :fixed_price=>700.0}, ...]
973
+ #
974
+ # rds.describe_reserved_db_instances_offerings(:aws_id => "248e7b75-49a7-4cd7-9a9b-354f4906a9b1") #=>
975
+ # [{:duration=>94608000,
976
+ # :multi_az=>true,
977
+ # :fixed_price=>700.0,
978
+ # :usage_price=>0.092,
979
+ # :currency_code=>"USD",
980
+ # :aws_id=>"248e7b75-49a7-4cd7-9a9b-354f4906a9b1",
981
+ # :instance_class=>"db.m1.small",
982
+ # :product_description=>"mysql"}]
983
+ #
984
+ # rds.describe_reserved_db_instances_offerings(:instance_class => "db.m1.small")
985
+ # rds.describe_reserved_db_instances_offerings(:duration => 31536000)
986
+ # rds.describe_reserved_db_instances_offerings(:product_description => 'mysql')
987
+ # rds.describe_reserved_db_instances_offerings(:multi_az => true)
988
+ #
989
+ def describe_reserved_db_instances_offerings(params={}, &block)
990
+ params = params.dup
991
+ params['ReservedDBInstancesOfferingId'] = params.delete(:aws_id) unless params[:aws_id].right_blank?
992
+ params['DBInstanceClass'] = params.delete(:instance_class) unless params[:instance_class].right_blank?
993
+ params['Duration'] = params.delete(:duration) unless params[:duration].right_blank?
994
+ params['ProductDescription'] = params.delete(:product_description) unless params[:product_description].right_blank?
995
+ params['MultiAZ'] = params.delete(:multi_az).to_s unless params[:multi_az].nil?
996
+ result = []
997
+ incrementally_list_items('DescribeReservedDBInstancesOfferings', DescribeReservedDBInstancesOfferingsParser, params) do |response|
998
+ result += response[:reserved_db_instances_offerings]
999
+ block ? block.call(response) : true
1000
+ end
1001
+ result
1002
+ end
1003
+
1004
+ # Returns information about reserved DB Instances for this account, or about
1005
+ # a specified reserved DB Instance.
1006
+ # Options: :aws_id, :offering_aws_id, :instance_class, :duration, :product_description, :multi_az
1007
+ #
1008
+ # rds.describe_reserved_db_instances
1009
+ # rds.describe_reserved_db_instances(:aws_id => "myreservedinstance")
1010
+ # rds.describe_reserved_db_instances(:offering_aws_id => "248e7b75-49a7-4cd7-9a9b-354f4906a9b1")
1011
+ # rds.describe_reserved_db_instances(:instance_class => "db.m1.small")
1012
+ # rds.describe_reserved_db_instances(:duration => 31536000)
1013
+ # rds.describe_reserved_db_instances(:product_description => 'mysql')
1014
+ # rds.describe_reserved_db_instances_offerings(:multi_az => true)
1015
+ #
1016
+ def describe_reserved_db_instances(params={}, &block)
1017
+ params = params.dup
1018
+ params['ReservedDBInstancesId'] = params.delete(:aws_id) unless params[:aws_id].right_blank?
1019
+ params['ReservedDBInstancesOfferingId'] = params.delete(:offering_aws_id) unless params[:offering_aws_id].right_blank?
1020
+ params['DBInstanceClass'] = params.delete(:instance_class) unless params[:instance_class].right_blank?
1021
+ params['Duration'] = params.delete(:duration) unless params[:duration].right_blank?
1022
+ params['ProductDescription'] = params.delete(:product_description) unless params[:product_description].right_blank?
1023
+ params['MultiAZ'] = params.delete(:multi_az).to_s unless params[:multi_az].nil?
1024
+ result = []
1025
+ incrementally_list_items('DescribeReservedDBInstances', DescribeReservedDBInstancesParser, params) do |response|
1026
+ result += response[:reserved_db_instances]
1027
+ block ? block.call(response) : true
1028
+ end
1029
+ result
1030
+ end
1031
+
1032
+ # Purchases a reserved DB Instance offering.
1033
+ # Options: :aws_id, :count
1034
+ def purchase_reserved_db_instances_offering(offering_aws_id, params={})
1035
+ request_hash = { 'ReservedDBInstancesOfferingId' => offering_aws_id }
1036
+ request_hash['ReservedDBInstanceId'] = params[:aws_id] unless params[:aws_id].right_blank?
1037
+ request_hash['DBInstanceCount'] = params[:count] unless params[:count].right_blank?
1038
+ link = generate_request('PurchaseReservedDBInstancesOffering', request_hash)
1039
+ request_info(link, DescribeReservedDBInstancesParser.new(:logger => @logger))[:reserved_db_instances].first
1040
+ end
1041
+
1042
+ # --------------------------------------------
1043
+ # Parsers
1044
+ # --------------------------------------------
1045
+
1046
+ # --------------------------------------------
1047
+ # DB Instances
1048
+ # --------------------------------------------
1049
+
1050
+ class DescribeDbInstancesParser < RightAWSParser # :nodoc:
1051
+ def reset
1052
+ @result = { :db_instances => [] }
1053
+ end
1054
+ def tagstart(name, attributes)
1055
+ case name
1056
+ when 'DBInstance' then @item = { :db_security_groups => [], :pending_modified_values => {}, :read_replica_db_instance_identifiers => [] }
1057
+ when 'DBSecurityGroup' then @db_security_group = {}
1058
+ when 'DBParameterGroup',
1059
+ 'DBParameterGroupStatus' then @db_parameter_group = {}
1060
+ end
1061
+ end
1062
+ def tagend(name)
1063
+ case name
1064
+ when 'Marker' then @result[:marker] = @text
1065
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1066
+ when 'DBInstanceIdentifier' then @item[:aws_id] = @text
1067
+ when 'InstanceCreateTime' then @item[:create_time] = @text
1068
+ when 'Engine' then @item[:engine] = @text
1069
+ when 'DBInstanceStatus' then @item[:status] = @text
1070
+ when 'Address' then @item[:endpoint_address] = @text
1071
+ when 'Port' then @item[:endpoint_port] = @text.to_i
1072
+ when 'MasterUsername' then @item[:master_username] = @text
1073
+ when 'AvailabilityZone' then @item[:availability_zone] = @text
1074
+ when 'LatestRestorableTime' then @item[:latest_restorable_time] = @text
1075
+ when 'LicenseModel' then @item[:license_model] = @text
1076
+ when 'DBName' then @item[:db_name] = @text
1077
+ when 'ReadReplicaSourceDBInstanceIdentifier' then @item[:read_replica_source_db_instance_identifier] = @text
1078
+ when 'ReadReplicaDBInstanceIdentifier' then @item[:read_replica_db_instance_identifiers] << @text
1079
+ when 'DBSecurityGroupName' then @db_security_group[:name] = @text
1080
+ when 'Status' then @db_security_group[:status] = @text
1081
+ when 'DBParameterGroupName' then @db_parameter_group[:name] = @text
1082
+ when 'ParameterApplyStatus' then @db_parameter_group[:status] = @text
1083
+ when 'DBSecurityGroup' then @item[:db_security_groups] << @db_security_group
1084
+ when 'DBParameterGroup',
1085
+ 'DBParameterGroupStatus' then @item[:db_parameter_group] = @db_parameter_group
1086
+ when 'DBInstance' then @result[:db_instances] << @item
1087
+ else
1088
+ case full_tag_name
1089
+ when %r{DBInstance/DBInstanceClass$} then @item[:instance_class] = @text
1090
+ when %r{DBInstance/AllocatedStorage$} then @item[:allocated_storage] = @text.to_i
1091
+ when %r{DBInstance/MultiAZ$} then @item[:multi_az] = (@text == 'true')
1092
+ when %r{DBInstance/BackupRetentionPeriod$} then @item[:backup_retention_period] = @text.to_i
1093
+ when %r{DBInstance/PreferredMaintenanceWindow$} then @item[:preferred_maintenance_window] = @text
1094
+ when %r{DBInstance/PreferredBackupWindow$} then @item[:preferred_backup_window] = @text
1095
+ when %r{DBInstance/EngineVersion$} then @item[:engine_version] = @text
1096
+ when %r{DBInstance/AutoMinorVersionUpgrade$} then @item[:auto_minor_version_upgrade] = (@text == 'true')
1097
+ when %r{DBInstance/AllowMajorVersionUpgrade$} then @item[:allow_major_version_upgrade] = (@text == 'true')
1098
+ when %r{PendingModifiedValues/DBInstanceClass$} then @item[:pending_modified_values][:instance_class] = @text
1099
+ when %r{PendingModifiedValues/AllocatedStorage$} then @item[:pending_modified_values][:allocated_storage] = @text.to_i
1100
+ when %r{PendingModifiedValues/MasterUserPassword$} then @item[:pending_modified_values][:master_user_password] = @text
1101
+ when %r{PendingModifiedValues/MultiAZ$} then @item[:pending_modified_values][:multi_az] = (@text == 'true')
1102
+ when %r{PendingModifiedValues/BackupRetentionPeriod$} then @item[:pending_modified_values][:backup_retention_period] = @text.to_i
1103
+ when %r{PendingModifiedValues/PreferredMaintenanceWindow$} then @item[:pending_modified_values][:preferred_maintenance_window] = @text
1104
+ when %r{PendingModifiedValues/PreferredBackupWindow$} then @item[:pending_modified_values][:preferred_backup_window] = @text
1105
+ when %r{PendingModifiedValues/EngineVersion$} then @item[:pending_modified_values][:engine_version] = @text
1106
+ when %r{PendingModifiedValues/AutoMinorVersionUpgrade$} then @item[:pending_modified_values][:auto_minor_version_upgrade] = (@text == 'true')
1107
+ when %r{PendingModifiedValues/AllowMajorVersionUpgrade$} then @item[:pending_modified_values][:allow_major_version_upgrade] = (@text == 'true')
1108
+ end
1109
+ end
1110
+ end
1111
+ end
1112
+
1113
+ class DescribeOrderableDBInstanceOptionsParser < RightAWSParser # :nodoc:
1114
+ def reset
1115
+ @result = { :items => [] }
1116
+ end
1117
+ def tagstart(name, attributes)
1118
+ case name
1119
+ when 'OrderableDBInstanceOption' then @item = { :availability_zones => [] }
1120
+ end
1121
+ end
1122
+ def tagend(name)
1123
+ case name
1124
+ when 'Marker' then @result[:marker] = @text
1125
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1126
+ when 'DBInstanceClass' then @item[:instance_class] = @text
1127
+ when 'Engine' then @item[:engine] = @text
1128
+ when 'EngineVersion' then @item[:engine_version] = @text
1129
+ when 'LicenseModel' then @item[:license_model] = @text
1130
+ when 'MultiAZCapable' then @item[:multi_az_capable] = @text
1131
+ when 'ReadReplicaCapable' then @item[:read_replica_capable] = @text == 'true'
1132
+ when 'Name' then @item[:availability_zones] << @text
1133
+ when 'OrderableDBInstanceOption' then @result[:items] << @item
1134
+ end
1135
+ end
1136
+ end
1137
+
1138
+ # --------------------------------------------
1139
+ # DB Security Groups
1140
+ # --------------------------------------------
1141
+
1142
+ class DescribeDbSecurityGroupsParser < RightAWSParser # :nodoc:
1143
+ def reset
1144
+ @result = { :db_security_groups => [] }
1145
+ end
1146
+ def tagstart(name, attributes)
1147
+ case name
1148
+ when 'DBSecurityGroup' then @item = { :ec2_security_groups => [], :ip_ranges => [] }
1149
+ when 'IPRange' then @ip_range = {}
1150
+ when 'EC2SecurityGroup' then @ec2_security_group = {}
1151
+ end
1152
+ end
1153
+ def tagend(name)
1154
+ case name
1155
+ when 'Marker' then @result[:marker] = @text
1156
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1157
+ when 'DBSecurityGroupDescription' then @item[:description ] = @text
1158
+ when 'OwnerId' then @item[:owner_id] = @text
1159
+ when 'DBSecurityGroupName' then @item[:name] = @text
1160
+ when 'EC2SecurityGroupName' then @ec2_security_group[:name] = @text
1161
+ when 'EC2SecurityGroupOwnerId' then @ec2_security_group[:owner_id] = @text
1162
+ when 'CIDRIP' then @ip_range[:cidrip] = @text
1163
+ when 'IPRange' then @item[:ip_ranges] << @ip_range
1164
+ when 'EC2SecurityGroup' then @item[:ec2_security_groups] << @ec2_security_group
1165
+ when 'DBSecurityGroup'
1166
+ # Sort the ip_ranges and ec2_security_groups
1167
+ @item[:ip_ranges].sort!{ |i1,i2| "#{i1[:cidrip]}" <=> "#{i2[:cidrip]}" }
1168
+ @item[:ec2_security_groups].sort!{ |i1,i2| "#{i1[:owner_id]}#{i1[:name]}" <=> "#{i2[:owner_id]}#{i2[:name]}" }
1169
+ @result[:db_security_groups] << @item
1170
+ else
1171
+ case full_tag_name
1172
+ when %r{IPRange/Status$} then @ip_range[:status] = @text
1173
+ when %r{EC2SecurityGroup/Status$} then @ec2_security_group[:status] = @text
1174
+ end
1175
+ end
1176
+ end
1177
+ end
1178
+
1179
+ # --------------------------------------------
1180
+ # DB Security Groups
1181
+ # --------------------------------------------
1182
+
1183
+ class DescribeDbParameterGroupsParser < RightAWSParser # :nodoc:
1184
+ def reset
1185
+ @result = { :db_parameter_groups => [] }
1186
+ end
1187
+ def tagstart(name, attributes)
1188
+ case name
1189
+ when 'DBParameterGroup',
1190
+ 'ModifyDBParameterGroupResult' then @item = { }
1191
+ end
1192
+ end
1193
+ def tagend(name)
1194
+ case name
1195
+ when 'Marker' then @result[:marker] = @text
1196
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1197
+ when 'DBParameterGroupName' then @item[:name] = @text
1198
+ when 'Description' then @item[:description] = @text
1199
+ when 'DBParameterGroupFamily' then @item[:db_parameter_group_family] = @text
1200
+ when 'DBParameterGroup',
1201
+ 'ModifyDBParameterGroupResult' then @result[:db_parameter_groups] << @item
1202
+ end
1203
+ end
1204
+ end
1205
+
1206
+ class DescribeDbParametersParser < RightAWSParser # :nodoc:
1207
+ def reset
1208
+ @result = { :parameters => [] }
1209
+ end
1210
+ def tagstart(name, attributes)
1211
+ case name
1212
+ when 'Parameter' then @item = {}
1213
+ end
1214
+ end
1215
+ def tagend(name)
1216
+ case name
1217
+ when 'Marker' then @result[:marker] = @text
1218
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1219
+ when 'DBParameterGroupName' then @result[:group_name] = @text # DescribeDbParametersResponse
1220
+ when 'DBParameterGroupFamily' then @result[:db_parameter_group_family] = @text # DescribeDBEngineDefaultParametersResponse
1221
+ when 'DataType' then @item[:data_type] = @text
1222
+ when 'Source' then @item[:source] = @text
1223
+ when 'Description' then @item[:description] = @text
1224
+ when 'IsModifiable' then @item[:is_modifiable] = (@text == 'true')
1225
+ when 'ApplyType' then @item[:apply_type] = @text
1226
+ when 'ApplyMethod' then @item[:apply_method] = @text
1227
+ when 'MinimumEngineVersion' then @item[:minimum_engine_version] = @text
1228
+ when 'AllowedValues' then @item[:allowed_values] = @text
1229
+ when 'ParameterName' then @item[:name] = @text
1230
+ when 'ParameterValue' then @item[:value] = @text
1231
+ when 'Parameter' then @result[:parameters] << @item
1232
+ end
1233
+ end
1234
+ end
1235
+
1236
+ # --------------------------------------------
1237
+ # DB Snapshots
1238
+ # --------------------------------------------
1239
+
1240
+ class DescribeDbSnapshotsParser < RightAWSParser # :nodoc:
1241
+ def reset
1242
+ @result = { :db_snapshots => [] }
1243
+ end
1244
+ def tagstart(name, attributes)
1245
+ case name
1246
+ when 'DBSnapshot' then @item = {}
1247
+ end
1248
+ end
1249
+ def tagend(name)
1250
+ case name
1251
+ when 'Marker' then @result[:marker] = @text
1252
+ when 'MaxRecords' then @result[:max_records] = @text.to_i # ?
1253
+ when 'Engine' then @item[:engine] = @text
1254
+ when 'EngineVersion' then @item[:engine_version] = @text
1255
+ when 'InstanceCreateTime' then @item[:instance_create_time] = @text
1256
+ when 'Port' then @item[:endpoint_port] = @text.to_i
1257
+ when 'Status' then @item[:status] = @text
1258
+ when 'AvailabilityZone' then @item[:availability_zone] = @text
1259
+ when 'MasterUsername' then @item[:master_username] = @text
1260
+ when 'AllocatedStorage' then @item[:allocated_storage] = @text.to_i
1261
+ when 'SnapshotCreateTime' then @item[:create_time] = @text
1262
+ when 'DBInstanceIdentifier' then @item[:instance_aws_id] = @text
1263
+ when 'DBSnapshotIdentifier' then @item[:aws_id] = @text
1264
+ when 'LicenseModel' then @item[:license_model] = @text
1265
+ when 'DBSnapshot' then @result[:db_snapshots] << @item
1266
+ end
1267
+ end
1268
+ end
1269
+
1270
+ # --------------------------------------------
1271
+ # DB Events
1272
+ # --------------------------------------------
1273
+
1274
+ class DescribeEventsParser < RightAWSParser # :nodoc:
1275
+ def reset
1276
+ @result = { :events => [] }
1277
+ end
1278
+ def tagstart(name, attributes)
1279
+ case name
1280
+ when 'Event' then @item = {}
1281
+ end
1282
+ end
1283
+ def tagend(name)
1284
+ case name
1285
+ when 'Marker' then @result[:marker] = @text
1286
+ when 'MaxRecords' then @result[:max_records] = @text.to_i # ?
1287
+ when 'Date' then @item[:date] = @text
1288
+ when 'SourceIdentifier' then @item[:aws_id] = @text
1289
+ when 'SourceType' then @item[:source_type] = @text
1290
+ when 'Message' then @item[:message] = @text
1291
+ when 'Event' then @result[:events] << @item
1292
+ end
1293
+ end
1294
+ end
1295
+
1296
+ # --------------------------------------------
1297
+ # DB Events
1298
+ # --------------------------------------------
1299
+
1300
+ class DescribeDBEngineVersionsParser < RightAWSParser # :nodoc:
1301
+ def reset
1302
+ @result = { :db_engine_versions => [] }
1303
+ end
1304
+ def tagstart(name, attributes)
1305
+ case name
1306
+ when 'DBEngineVersion' then @item = {}
1307
+ end
1308
+ end
1309
+ def tagend(name)
1310
+ case name
1311
+ when 'Marker' then @result[:marker] = @text
1312
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1313
+ when 'DBParameterGroupFamily' then @item[:db_parameter_group_family] = @text
1314
+ when 'Engine' then @item[:engine] = @text
1315
+ when 'EngineVersion' then @item[:engine_version] = @text
1316
+ when 'DBEngineDescription' then @item[:db_engine_description] = @text
1317
+ when 'DBEngineVersionDescription' then @item[:db_engine_version_description] = @text
1318
+ when 'DBEngineVersion' then @result[:db_engine_versions] << @item
1319
+ end
1320
+ end
1321
+ end
1322
+
1323
+ # --------------------------------------------
1324
+ # DB Reserved Instances
1325
+ # --------------------------------------------
1326
+
1327
+ class DescribeReservedDBInstancesOfferingsParser < RightAWSParser # :nodoc:
1328
+ def reset
1329
+ @result = { :reserved_db_instances_offerings => [] }
1330
+ end
1331
+ def tagstart(name, attributes)
1332
+ case name
1333
+ when 'ReservedDBInstancesOffering' then @item = {}
1334
+ end
1335
+ end
1336
+ def tagend(name)
1337
+ case name
1338
+ when 'Marker' then @result[:marker] = @text
1339
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1340
+ when 'CurrencyCode' then @item[:currency_code] = @text
1341
+ when 'DBInstanceClass' then @item[:instance_class] = @text
1342
+ when 'Duration' then @item[:duration] = @text.to_i
1343
+ when 'FixedPrice' then @item[:fixed_price] = @text.to_f
1344
+ when 'UsagePrice' then @item[:usage_price] = @text.to_f
1345
+ when 'MultiAZ' then @item[:multi_az] = (@text == 'true')
1346
+ when 'ProductDescription' then @item[:product_description] = @text
1347
+ when 'ReservedDBInstancesOfferingId' then @item[:aws_id] = @text
1348
+ when 'ReservedDBInstancesOffering' then @result[:reserved_db_instances_offerings] << @item
1349
+ end
1350
+ end
1351
+ end
1352
+
1353
+ class DescribeReservedDBInstancesParser < RightAWSParser # :nodoc:
1354
+ def reset
1355
+ @result = { :reserved_db_instances => [] }
1356
+ end
1357
+ def tagstart(name, attributes)
1358
+ case name
1359
+ when 'ReservedDBInstance' then @item = {}
1360
+ end
1361
+ end
1362
+ def tagend(name)
1363
+ case name
1364
+ when 'Marker' then @result[:marker] = @text
1365
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1366
+ when 'DBInstanceClass' then @item[:instance_class] = @text
1367
+ when 'CurrencyCode' then @item[:currency_code] = @text
1368
+ when 'Duration' then @item[:duration] = @text.to_i
1369
+ when 'FixedPrice' then @item[:fixed_price] = @text.to_f
1370
+ when 'UsagePrice' then @item[:usage_price] = @text.to_f
1371
+ when 'MultiAZ' then @item[:multi_az] = (@text == 'true')
1372
+ when 'ProductDescription' then @item[:product_description] = @text
1373
+ when 'ReservedDBInstancesOfferingId' then @item[:offering_aws_id] = @text
1374
+ when 'ReservedDBInstanceId' then @item[:aws_id] = @text
1375
+ when 'State' then @item[:state] = @text
1376
+ when 'DBInstanceCount' then @item[:instance_count] = @text.to_i
1377
+ when 'StartTime' then @item[:start_time] = @text
1378
+ when 'ReservedDBInstance' then @result[:reserved_db_instances] << @item
1379
+ end
1380
+ end
1381
+ end
1382
+
1383
+ end
1384
+ end