right_aws 1.9.0 → 3.1.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 (70) hide show
  1. data/History.txt +164 -13
  2. data/Manifest.txt +28 -1
  3. data/README.txt +12 -10
  4. data/Rakefile +56 -29
  5. data/lib/acf/right_acf_interface.rb +343 -172
  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/right_awsbase.rb +755 -115
  12. data/lib/awsbase/support.rb +2 -78
  13. data/lib/awsbase/version.rb +9 -0
  14. data/lib/ec2/right_ec2.rb +274 -1294
  15. data/lib/ec2/right_ec2_ebs.rb +514 -0
  16. data/lib/ec2/right_ec2_images.rb +444 -0
  17. data/lib/ec2/right_ec2_instances.rb +797 -0
  18. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  19. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  20. data/lib/ec2/right_ec2_reserved_instances.rb +243 -0
  21. data/lib/ec2/right_ec2_security_groups.rb +496 -0
  22. data/lib/ec2/right_ec2_spot_instances.rb +422 -0
  23. data/lib/ec2/right_ec2_tags.rb +139 -0
  24. data/lib/ec2/right_ec2_vpc.rb +598 -0
  25. data/lib/ec2/right_ec2_vpc2.rb +382 -0
  26. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  27. data/lib/elb/right_elb_interface.rb +573 -0
  28. data/lib/emr/right_emr_interface.rb +728 -0
  29. data/lib/iam/right_iam_access_keys.rb +71 -0
  30. data/lib/iam/right_iam_groups.rb +195 -0
  31. data/lib/iam/right_iam_interface.rb +341 -0
  32. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  33. data/lib/iam/right_iam_users.rb +251 -0
  34. data/lib/rds/right_rds_interface.rb +1657 -0
  35. data/lib/right_aws.rb +30 -13
  36. data/lib/route_53/right_route_53_interface.rb +641 -0
  37. data/lib/s3/right_s3.rb +108 -41
  38. data/lib/s3/right_s3_interface.rb +349 -118
  39. data/lib/sdb/active_sdb.rb +388 -54
  40. data/lib/sdb/right_sdb_interface.rb +323 -64
  41. data/lib/sns/right_sns_interface.rb +286 -0
  42. data/lib/sqs/right_sqs.rb +1 -2
  43. data/lib/sqs/right_sqs_gen2.rb +73 -17
  44. data/lib/sqs/right_sqs_gen2_interface.rb +146 -73
  45. data/lib/sqs/right_sqs_interface.rb +12 -22
  46. data/right_aws.gemspec +91 -0
  47. data/test/README.mdown +39 -0
  48. data/test/acf/test_right_acf.rb +11 -19
  49. data/test/awsbase/test_helper.rb +2 -0
  50. data/test/awsbase/test_right_awsbase.rb +11 -0
  51. data/test/ec2/test_right_ec2.rb +32 -1
  52. data/test/elb/test_helper.rb +2 -0
  53. data/test/elb/test_right_elb.rb +43 -0
  54. data/test/rds/test_helper.rb +2 -0
  55. data/test/rds/test_right_rds.rb +120 -0
  56. data/test/route_53/fixtures/a_record.xml +18 -0
  57. data/test/route_53/fixtures/alias_record.xml +18 -0
  58. data/test/route_53/test_helper.rb +2 -0
  59. data/test/route_53/test_right_route_53.rb +141 -0
  60. data/test/s3/test_right_s3.rb +176 -42
  61. data/test/s3/test_right_s3_stubbed.rb +6 -4
  62. data/test/sdb/test_active_sdb.rb +120 -19
  63. data/test/sdb/test_batch_put_attributes.rb +54 -0
  64. data/test/sdb/test_right_sdb.rb +71 -16
  65. data/test/sns/test_helper.rb +2 -0
  66. data/test/sns/test_right_sns.rb +153 -0
  67. data/test/sqs/test_right_sqs.rb +0 -6
  68. data/test/sqs/test_right_sqs_gen2.rb +104 -49
  69. data/test/ts_right_aws.rb +1 -0
  70. metadata +181 -22
@@ -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,1657 @@
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 = "2012-09-17"
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.t1.micro',
38
+ 'db.m1.small',
39
+ 'db.m1.medium',
40
+ 'db.m1.large',
41
+ 'db.m1.xlarge',
42
+ 'db.m2.xlarge',
43
+ 'db.m2.2xlarge',
44
+ 'db.m2.4xlarge']
45
+ LICENSE_MODELS = ['bring-your-own-license', 'license-included', 'general-public-license']
46
+
47
+ @@bench = AwsBenchmarkingBlock.new
48
+ def self.bench_xml
49
+ @@bench.xml
50
+ end
51
+ def self.bench_service
52
+ @@bench.service
53
+ end
54
+
55
+ # Create a new handle to a RDS account. All handles share the same per process or per thread
56
+ # HTTP connection to RDS. Each handle is for a specific account. The params have the
57
+ # following options:
58
+ # * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol). Example: 'https://rds.amazonaws.com'
59
+ # * <tt>:server</tt>: RDS service host, default: DEFAULT_HOST
60
+ # * <tt>:port</tt>: RDS service port, default: DEFAULT_PORT
61
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
62
+ # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
63
+ #
64
+ # rds = RightAws::RdsInterface.new('xxxxxxxxxxxxxxxxxxxxx','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
65
+ # {:logger => Logger.new('/tmp/x.log')}) #=> #<RightAws::RdsInterface::0xb7b3c30c>
66
+ #
67
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
68
+ init({ :name => 'RDS',
69
+ :default_host => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).host : DEFAULT_HOST,
70
+ :default_port => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).port : DEFAULT_PORT,
71
+ :default_service => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).path : DEFAULT_PATH,
72
+ :default_protocol => ENV['RDS_URL'] ? URI.parse(ENV['RDS_URL']).scheme : DEFAULT_PROTOCOL,
73
+ :default_api_version => ENV['RDS_API_VERSION'] || API_VERSION },
74
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
75
+ aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
76
+ params)
77
+ end
78
+
79
+ #-----------------------------------------------------------------
80
+ # Requests
81
+ #-----------------------------------------------------------------
82
+
83
+ # Generates request hash for REST API.
84
+ def generate_request(action, params={}) #:nodoc:
85
+ generate_request_impl(:get, action, params )
86
+ end
87
+
88
+ # Sends request to Amazon and parses the response.
89
+ # Raises AwsError if any banana happened.
90
+ def request_info(request, parser, &block) # :nodoc:
91
+ request_info_impl(:rds_connection, @@bench, request, parser, &block)
92
+ end
93
+
94
+ # Incrementally lists something.
95
+ def incrementally_list_items(action, parser_class, params={}, &block) # :nodoc:
96
+ params = params.dup
97
+ params['MaxRecords'] = params.delete(:max_records) if params[:max_records]
98
+ params['Marker'] = params.delete(:marker) if params[:marker]
99
+ last_response = nil
100
+ loop do
101
+ link = generate_request(action, params)
102
+ last_response = request_info( link, parser_class.new(:logger => @logger))
103
+ params['Marker'] = last_response[:marker]
104
+ break unless block && block.call(last_response) && !last_response[:marker].right_blank?
105
+ end
106
+ last_response
107
+ end
108
+
109
+ #-----------------------------------------------------------------
110
+ # API Calls:
111
+ #-----------------------------------------------------------------
112
+
113
+ # --------------------------------------------
114
+ # DB Instances
115
+ # --------------------------------------------
116
+
117
+ # List DB instances.
118
+ #
119
+ # Optional params: +:aws_id+, +:max_records+, +:marker+
120
+ #
121
+ # # Get a list of DB instances. The response is an +Array+ of instances.
122
+ # rds.describe_db_instances #=>
123
+ # [{:instance_class=>"db.m1.small",
124
+ # :status=>"creating",
125
+ # :backup_retention_period=>1,
126
+ # :read_replica_db_instance_identifiers=>["kd-delete-me-01-replica-01"],
127
+ # :master_username=>"username",
128
+ # :preferred_maintenance_window=>"sun:05:00-sun:09:00",
129
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
130
+ # :multi_az=>true,
131
+ # :engine=>"mysql",
132
+ # :auto_minor_version_upgrade=>false,
133
+ # :allocated_storage=>25,
134
+ # :availability_zone=>"us-east-1d",
135
+ # :aws_id=>"kd-delete-me-01",
136
+ # :preferred_backup_window=>"03:00-05:00",
137
+ # :engine_version=>"5.1.50",
138
+ # :pending_modified_values=>{:master_user_password=>"****"},
139
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}]}]
140
+ #
141
+ # # Retrieve a custom DB instance.
142
+ # # The response is an +Array+ with a single instance record.
143
+ # rds.describe_db_instances("kd-test-n3")
144
+ #
145
+ # # Incrementally a list DB instances. Every response part is a +Hash+.
146
+ # rds.describe_db_instances(:max_records => 30) do |x|
147
+ # puts x.inspect #=>
148
+ # {:db_instances=>
149
+ # [{:instance_class=>"db.m1.small",
150
+ # :status=>"creating",
151
+ # :backup_retention_period=>1,
152
+ # :read_replica_db_instance_identifiers=>["kd-delete-me-01-replica-01"],
153
+ # :master_username=>"username",
154
+ # :preferred_maintenance_window=>"sun:05:00-sun:09:00",
155
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
156
+ # :multi_az=>true,
157
+ # :engine=>"mysql",
158
+ # :auto_minor_version_upgrade=>false,
159
+ # :allocated_storage=>25,
160
+ # :availability_zone=>"us-east-1d",
161
+ # :aws_id=>"kd-delete-me-01",
162
+ # :preferred_backup_window=>"03:00-05:00",
163
+ # :engine_version=>"5.1.50",
164
+ # :pending_modified_values=>{:master_user_password=>"****"},
165
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}]}]}
166
+ # true
167
+ # end
168
+ #
169
+ def describe_db_instances(*params, &block)
170
+ item, params = AwsUtils::split_items_and_params(params)
171
+ params = params.dup
172
+ params['DBInstanceIdentifier'] = item.first unless item.right_blank?
173
+ result = []
174
+ incrementally_list_items('DescribeDBInstances', DescribeDbInstancesParser, params) do |response|
175
+ result += response[:db_instances]
176
+ block ? block.call(response) : true
177
+ end
178
+ result
179
+ end
180
+
181
+ # Create a new RDS instance of the type and size specified by you. The default storage engine for RDS Instances is InnoDB.
182
+ #
183
+ # Mandatory arguments: +aws_id+, +master_username+, +master_user_password+
184
+ # Optional params: +:allocated_storage+ (25 by def), +:instance_class+, +:engine+ ('MySQL' by def),
185
+ # +:endpoint_port+, +:db_name+, +:db_security_groups+, +:db_parameter_group+, +:availability_zone+, +:preferred_maintenance_window+
186
+ # +:backup_retention_period+, +:preferred_backup_window+, +:multi_az+, +:engine_version+, +:auto_minor_version_upgrade+,
187
+ # +:license_model+, +:iops+, +:db_subnet_group_name+, +:character_set_name+, +:option_group_name+
188
+ #
189
+ # rds.create_db_instance('kd-delete-me-01', 'username', 'password',
190
+ # :instance_class => 'db.m1.small',
191
+ # :multi_az => true,
192
+ # :auto_minor_version_upgrade => false ) #=>
193
+ # {:instance_class=>"db.m1.small",
194
+ # :multi_az=>true,
195
+ # :status=>"creating",
196
+ # :backup_retention_period=>1,
197
+ # :read_replica_db_instance_identifiers=>[],
198
+ # :master_username=>"username",
199
+ # :preferred_maintenance_window=>"sun:05:00-sun:09:00",
200
+ # :auto_minor_version_upgrade=>false,
201
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
202
+ # :engine=>"mysql",
203
+ # :allocated_storage=>25,
204
+ # :aws_id=>"kd-delete-me-01",
205
+ # :preferred_backup_window=>"03:00-05:00",
206
+ # :engine_version=>"5.1.50",
207
+ # :pending_modified_values=>{:master_user_password=>"****"},
208
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}]}
209
+ #
210
+ def create_db_instance(aws_id, master_username, master_user_password, params={})
211
+ request_hash = {}
212
+ # Mandatory
213
+ request_hash['DBInstanceIdentifier'] = aws_id
214
+ request_hash['MasterUsername'] = master_username
215
+ request_hash['MasterUserPassword'] = master_user_password
216
+ # Mandatory with default values
217
+ request_hash['DBInstanceClass'] = params[:instance_class].right_blank? ? DEFAULT_INSTANCE_CLASS : params[:instance_class].to_s
218
+ request_hash['AllocatedStorage'] = params[:allocated_storage].right_blank? ? 25 : params[:allocated_storage]
219
+ request_hash['Engine'] = params[:engine].right_blank? ? 'mysql' : params[:engine]
220
+ # Optional
221
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
222
+ request_hash['DBName'] = params[:db_name] unless params[:db_name].right_blank?
223
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
224
+ request_hash['MultiAZ'] = params[:multi_az].to_s unless params[:multi_az].nil?
225
+ request_hash['PreferredMaintenanceWindow'] = params[:preferred_maintenance_window] unless params[:preferred_maintenance_window].right_blank?
226
+ request_hash['BackupRetentionPeriod'] = params[:backup_retention_period] unless params[:backup_retention_period].right_blank?
227
+ request_hash['PreferredBackupWindow'] = params[:preferred_backup_window] unless params[:preferred_backup_window].right_blank?
228
+ request_hash['DBParameterGroupName'] = params[:db_parameter_group] unless params[:db_parameter_group].right_blank?
229
+ request_hash['EngineVersion'] = params[:engine_version] unless params[:engine_version].right_blank?
230
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade].to_s unless params[:auto_minor_version_upgrade].nil?
231
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
232
+ request_hash['CharacterSetName'] = params[:character_set_name] unless params[:character_set_name].right_blank?
233
+ request_hash['DBSubnetGroupName'] = params[:db_subnet_group_name] unless params[:db_subnet_group_name].right_blank?
234
+ request_hash['Iops'] = params[:iops] unless params[:iops].right_blank?
235
+ request_hash['OptionGroupName'] = params[:option_group_name] unless params[:option_group_name].right_blank?
236
+ request_hash.merge!(amazonize_list('DBSecurityGroups.member', params[:db_security_groups]))
237
+ link = generate_request('CreateDBInstance', request_hash)
238
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
239
+ end
240
+
241
+ # Modify a DB instance.
242
+ #
243
+ # Mandatory arguments: +aws_id+.
244
+ # Optional params: +:master_user_password+, +:instance_class+, +:db_security_groups+,
245
+ # +:db_parameter_group+, +:preferred_maintenance_window+, +:allocated_storage+, +:apply_immediately+,
246
+ # +:backup_retention_period+, +:preferred_backup_window+, +:multi_az+, +:engine_version+,
247
+ # +:auto_minor_version_upgrade+, +:allow_major_version_upgrade+, +:iops+, +::option_group_name+
248
+ #
249
+ # rds.modify_db_instance('kd-delete-me-01',
250
+ # :master_user_password => 'newpassword',
251
+ # :instance_class => 'db.m1.large',
252
+ # :multi_az => false,
253
+ # :allocated_storage => 30,
254
+ # :allow_major_version_upgrade => true,
255
+ # :auto_minor_version_upgrade => true,
256
+ # :preferred_maintenance_window => 'sun:06:00-sun:10:00',
257
+ # :preferred_backup_window => '02:00-04:00',
258
+ # :apply_immediately => true,
259
+ # :backup_retention_period => 2) #=>
260
+ # {:engine_version=>"5.1.50",
261
+ # :aws_id=>"kd-delete-me-01",
262
+ # :multi_az=>true,
263
+ # :status=>"available",
264
+ # :read_replica_db_instance_identifiers=>[],
265
+ # :availability_zone=>"us-east-1d",
266
+ # :auto_minor_version_upgrade=>true,
267
+ # :master_username=>"username",
268
+ # :preferred_maintenance_window=>"sun:06:00-sun:10:00",
269
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
270
+ # :create_time=>"2010-11-17T10:21:59.720Z",
271
+ # :preferred_backup_window=>"02:00-04:00",
272
+ # :engine=>"mysql",
273
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}],
274
+ # :endpoint_address=>"kd-delete-me-01.chxspydgchoo.us-east-1.rds.amazonaws.com",
275
+ # :instance_class=>"db.m1.small",
276
+ # :latest_restorable_time=>"2010-11-17T10:27:17.089Z",
277
+ # :backup_retention_period=>2,
278
+ # :pending_modified_values=>
279
+ # {:multi_az=>false, :master_user_password=>"****", :allocated_storage=>30, :instance_class=>"db.m1.large"},
280
+ # :allocated_storage=>25}
281
+ #
282
+ def modify_db_instance(aws_id, params={})
283
+ request_hash = {}
284
+ # Mandatory
285
+ request_hash['DBInstanceIdentifier'] = aws_id
286
+ # Optional
287
+ request_hash['MasterUserPassword'] = params[:master_user_password] unless params[:master_user_password].right_blank?
288
+ request_hash['DBInstanceClass'] = params[:instance_class].to_s.capitalize unless params[:instance_class].right_blank?
289
+ request_hash['PreferredMaintenanceWindow'] = params[:preferred_maintenance_window] unless params[:preferred_maintenance_window].right_blank?
290
+ request_hash['BackupRetentionPeriod'] = params[:backup_retention_period] unless params[:backup_retention_period].right_blank?
291
+ request_hash['PreferredBackupWindow'] = params[:preferred_backup_window] unless params[:preferred_backup_window].right_blank?
292
+ request_hash['AllocatedStorage'] = params[:allocated_storage] unless params[:allocated_storage].right_blank?
293
+ request_hash['MultiAZ'] = params[:multi_az].to_s unless params[:multi_az].nil?
294
+ request_hash['EngineVersion'] = params[:engine_version] unless params[:engine_version].right_blank?
295
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade].to_s unless params[:auto_minor_version_upgrade].nil?
296
+ request_hash['AllowMajorVersionUpgrade'] = params[:allow_major_version_upgrade].to_s unless params[:allow_major_version_upgrade].nil?
297
+ request_hash['ApplyImmediately'] = params[:apply_immediately].to_s unless params[:apply_immediately].right_blank?
298
+ request_hash.merge!(amazonize_list('DBSecurityGroups.member', params[:db_security_groups]))
299
+ request_hash['DBParameterGroupName'] = params[:db_parameter_group] unless params[:db_parameter_group].right_blank?
300
+ request_hash['Iops'] = params[:iops] unless params[:iops].right_blank?
301
+ request_hash['OptionGroupName'] = params[:option_group_name] unless params[:option_group_name].right_blank?
302
+ link = generate_request('ModifyDBInstance', request_hash)
303
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
304
+ end
305
+
306
+ # Reboot Db instance.
307
+ #
308
+ # Options: +:force_failover+
309
+ #
310
+ # rds.reboot_db_instance('kd-my-awesome-db') #=>
311
+ # {:status=>"rebooting",
312
+ # :pending_modified_values=>{},
313
+ # :allocated_storage=>42,
314
+ # :master_username=>"kd",
315
+ # :db_security_groups=>[],
316
+ # :instance_class=>"Medium",
317
+ # :availability_zone=>"us-east-1a",
318
+ # :aws_id=>"kd-my-awesome-db",
319
+ # :create_time=>"2009-08-28T08:34:21.858Z",
320
+ # :engine=>"MySQL5.1",
321
+ # :preferred_maintenance_window=>"Sun:05:00-Sun:09:00"}
322
+ #
323
+ # P.S. http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_RebootDBInstance.html
324
+ #
325
+ def reboot_db_instance(aws_id, params={})
326
+ params = params.dup
327
+ params['DBInstanceIdentifier'] = aws_id
328
+ params['ForceFailover'] = !!params[:force_failover] if params.has_key?(:force_failover)
329
+ link = generate_request('RebootDBInstance', params)
330
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
331
+ end
332
+
333
+ # Delete a DB instance
334
+ #
335
+ # Mandatory arguments: aws_id
336
+ # Optional params: :skip_final_snapshot ('false' by def),
337
+ # :snapshot_aws_id ('{instance_aws_id}-final-snapshot-YYYYMMDDHHMMSS')
338
+ #
339
+ # rds.delete_db_instance('my-awesome-db-g2') #=> true
340
+ #
341
+ def delete_db_instance(aws_id, params={})
342
+ request_hash = {}
343
+ request_hash['DBInstanceIdentifier'] = aws_id
344
+ request_hash['SkipFinalSnapshot'] = params.has_key?(:skip_final_snapshot) ? params[:skip_final_snapshot].to_s : 'false'
345
+ if request_hash['SkipFinalSnapshot'] == 'false' && params[:snapshot_aws_id].right_blank?
346
+ params = params.dup
347
+ params[:snapshot_aws_id] = "#{aws_id}-final-snapshot-#{Time.now.utc.strftime('%Y%m%d%H%M%S')}"
348
+ end
349
+ request_hash['FinalDBSnapshotIdentifier'] = params[:snapshot_aws_id] unless params[:snapshot_aws_id].right_blank?
350
+ link = generate_request('DeleteDBInstance', request_hash)
351
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
352
+ end
353
+
354
+ # --------------------------------------------
355
+ # DB SecurityGroups
356
+ # --------------------------------------------
357
+ #
358
+ # rds.describe_db_security_groups #=>
359
+ # [{:owner_id=>"82...25",
360
+ # :description=>"Default",
361
+ # :ec2_security_groups=>[],
362
+ # :ip_ranges=>[],
363
+ # :name=>"Default"},
364
+ # {:owner_id=>"82...25",
365
+ # :description=>"kd",
366
+ # :ec2_security_groups=>[],
367
+ # :ip_ranges=>[],
368
+ # :name=>"kd2"},
369
+ # {:owner_id=>"82...25",
370
+ # :description=>"kd",
371
+ # :ec2_security_groups=>
372
+ # [{:status=>"Authorized", :owner_id=>"82...23", :name=>"default"},
373
+ # {:status=>"Authorized", :owner_id=>"82...24", :name=>"default1"},
374
+ # {:status=>"Authorized", :owner_id=>"82...25", :name=>"default"},
375
+ # {:status=>"Authorized", :owner_id=>"82...26", :name=>"default"},
376
+ # {:status=>"Authorized", :owner_id=>"82...26", :name=>"default1"},
377
+ # {:status=>"Authorized", :owner_id=>"82...29", :name=>"default22"}],
378
+ # :ip_ranges=>
379
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
380
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
381
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
382
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
383
+ # {:status=>"Authorized", :cidrip=>"131.0.0.1/8"}],
384
+ # :name=>"kd3"}]
385
+ #
386
+ # # get a custom group
387
+ # rds.describe_db_security_groups('kd3')
388
+ #
389
+ def describe_db_security_groups(*db_security_group_name, &block)
390
+ items, params = AwsUtils::split_items_and_params(db_security_group_name)
391
+ params['DBSecurityGroupName'] = items.first unless items.right_blank?
392
+ result = []
393
+ incrementally_list_items('DescribeDBSecurityGroups', DescribeDbSecurityGroupsParser, params) do |response|
394
+ result += response[:db_security_groups]
395
+ block ? block.call(response) : true
396
+ end
397
+ result
398
+ end
399
+
400
+ # Create a database security group so that ingress to an RDS Instance can be controlled.
401
+ # A new security group cannot have the same name as an existing group.
402
+ #
403
+ # Options: :vpc_id
404
+ #
405
+ # ds.create_db_security_group('kd3', 'kd') #=>
406
+ # {:ec2_security_groups=>[],
407
+ # :description=>"kd",
408
+ # :ip_ranges=>[],
409
+ # :name=>"kd3",
410
+ # :owner_id=>"82...25"}
411
+ #
412
+ def create_db_security_group(db_security_group_name, db_security_group_description, params={})
413
+ request_hash = { 'DBSecurityGroupName' => db_security_group_name,
414
+ 'DBSecurityGroupDescription' => db_security_group_description }
415
+ request_hash['EC2VpcId'] = params[:vpc_id] unless params[:vpc_id].right_blank?
416
+ link = generate_request('CreateDBSecurityGroup', request_hash)
417
+ request_info(link, DescribeDbSecurityGroupsParser.new(:logger => @logger))[:db_security_groups].first
418
+ end
419
+
420
+ def modify_db_security_group_ingress(action, db_security_group_name, params={}) # :nodoc:
421
+ request_hash = { 'DBSecurityGroupName' => db_security_group_name}
422
+ request_hash['CIDRIP'] = params[:cidrip] unless params[:cidrip].right_blank?
423
+ request_hash['EC2SecurityGroupName'] = params[:ec2_security_group_name] unless params[:ec2_security_group_name].right_blank?
424
+ request_hash['EC2SecurityGroupOwnerId'] = params[:ec2_security_group_owner] unless params[:ec2_security_group_owner].right_blank?
425
+ request_hash['EC2SecurityGroupId'] = params[:ec2_security_group_id] unless params[:ec2_security_group_id].right_blank?
426
+ link = generate_request(action, request_hash)
427
+ request_info(link, DescribeDbSecurityGroupsParser.new(:logger => @logger))[:db_security_groups].first
428
+ end
429
+
430
+ # Authorize an ingress. Params: +:cidrip+ or (+:ec2_security_group_name+ and +:ec2_security_group_owner+)
431
+ #
432
+ # rds.authorize_db_security_group_ingress('kd3', :cidrip => '131.0.0.1/8')
433
+ # {:owner_id=>"82...25",
434
+ # :ec2_security_groups=>[],
435
+ # :description=>"kd",
436
+ # :ip_ranges=>
437
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
438
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
439
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
440
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
441
+ # {:status=>"Authorizing", :cidrip=>"131.0.0.1/8"}],
442
+ # :name=>"kd3"}
443
+ #
444
+ # rds.authorize_db_security_group_ingress('kd3',:ec2_security_group_owner => '82...27',
445
+ # :ec2_security_group_name => 'default') #=>
446
+ # {:owner_id=>"82...25",
447
+ # :ec2_security_groups=>
448
+ # [{:status=>"Authorized", :owner_id=>"82...25", :name=>"g1"},
449
+ # {:status=>"Authorized", :owner_id=>"82...26", :name=>"g2"},
450
+ # {:status=>"Authorizing", :owner_id=>"82...27", :name=>"default"}],
451
+ # :ip_ranges=>
452
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
453
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
454
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
455
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
456
+ # {:status=>"Authorized", :cidrip=>"131.0.0.1/8"}],
457
+ # :name=>"kd3"}
458
+ #
459
+ def authorize_db_security_group_ingress(db_security_group_name, params={})
460
+ modify_db_security_group_ingress('AuthorizeDBSecurityGroupIngress', db_security_group_name, params)
461
+ end
462
+
463
+ # Revoke an ingress.
464
+ # Optional params: +:cidrip+ or (+:ec2_security_group_name+ and +:ec2_security_group_owner+)
465
+ #
466
+ # rds.revoke_db_security_group_ingress('kd3', :ec2_security_group_owner => '82...25',
467
+ # :ec2_security_group_name => 'default') #=>
468
+ # {:owner_id=>"82...25",
469
+ # :ec2_security_groups=>
470
+ # [{:status=>"Revoking", :owner_id=>"826693181925", :name=>"default"}],
471
+ # :name=>"kd3",
472
+ # :description=>"kd",
473
+ # :ip_ranges=>
474
+ # [{:status=>"Authorized", :cidrip=>"127.0.0.1/8"},
475
+ # {:status=>"Authorized", :cidrip=>"128.0.0.1/8"},
476
+ # {:status=>"Authorized", :cidrip=>"129.0.0.1/8"},
477
+ # {:status=>"Authorized", :cidrip=>"130.0.0.1/8"},
478
+ # {:status=>"Authorized", :cidrip=>"131.0.0.1/8"}]}
479
+ #
480
+ def revoke_db_security_group_ingress(db_security_group_name, params={})
481
+ modify_db_security_group_ingress('RevokeDBSecurityGroupIngress', db_security_group_name, params)
482
+ end
483
+
484
+ # Delete a database security group. Database security group must not be associated with any
485
+ # RDS Instances.
486
+ #
487
+ # rds.delete_db_security_group('kd3') #=> true
488
+ #
489
+ def delete_db_security_group(db_security_group_name)
490
+ link = generate_request('DeleteDBSecurityGroup', 'DBSecurityGroupName' => db_security_group_name)
491
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
492
+ end
493
+
494
+ # --------------------------------------------
495
+ # DB ParameterGroups
496
+ # --------------------------------------------
497
+
498
+ # Describe DBParameterGroups.
499
+ #
500
+ # rds.describe_db_parameter_groups #=>
501
+ # [{:engine=>"MySQL5.1",
502
+ # :description=>"Default parameter group for MySQL5.1",
503
+ # :name=>"default.MySQL5.1"}]
504
+ #
505
+ # # List parameter groups by 20
506
+ # rds.describe_db_parameter_groups(:max_records=>20) do |response|
507
+ # puts response.inspect
508
+ # true
509
+ # end
510
+ #
511
+ def describe_db_parameter_groups(*db_parameter_group_name, &block)
512
+ items, params = AwsUtils::split_items_and_params(db_parameter_group_name)
513
+ params['DBParameterGroupName'] = items.first unless items.right_blank?
514
+ result = []
515
+ incrementally_list_items('DescribeDBParameterGroups', DescribeDbParameterGroupsParser, params) do |response|
516
+ result += response[:db_parameter_groups]
517
+ block ? block.call(response) : true
518
+ end
519
+ result
520
+ end
521
+
522
+ # Creates a database parameter group so that configuration of an RDS Instance can be controlled.
523
+ #
524
+ # rds.create_db_parameter_group('my-new-group-1','My new group') #=> {}
525
+ #
526
+ # TODO: this call returns an empty hash, but should be a parameter group data - ask Amazon guys.
527
+ #
528
+ def create_db_parameter_group(db_parameter_group_name, db_parameter_group_description, db_parameter_group_family='mysql5.1', params={})
529
+ params['DBParameterGroupName'] = db_parameter_group_name
530
+ params['Description'] = db_parameter_group_description
531
+ params['DBParameterGroupFamily'] = db_parameter_group_family
532
+ link = generate_request('CreateDBParameterGroup', params )
533
+ request_info(link, DescribeDbParameterGroupsParser.new(:logger => @logger))[:db_parameter_groups].first
534
+ end
535
+
536
+ # Modify DBParameterGroup paramaters. Up to 20 params can be midified at once.
537
+ #
538
+ # rds.modify_db_parameter_group('kd1', 'max_allowed_packet' => 2048) #=> true
539
+ #
540
+ # rds.modify_db_parameter_group('kd1', 'max_allowed_packet' => {:value => 2048, :method => 'immediate') #=> true
541
+ #
542
+ def modify_db_parameter_group(db_parameter_group_name, params={}) # :nodoc:
543
+ request_hash = { 'DBParameterGroupName' => db_parameter_group_name}
544
+ parameters = []
545
+ params.each do |key, value|
546
+ method = 'pending-reboot'
547
+ if value.is_a?(Hash)
548
+ method = value[:method] unless value[:method].right_blank?
549
+ value = value[:value]
550
+ end
551
+ parameters << [key, value, method]
552
+ end
553
+ request_hash.merge!( amazonize_list(['Parameters.member.?.ParameterName',
554
+ 'Parameters.member.?.ParameterValue',
555
+ 'Parameters.member.?.ApplyMethod'],
556
+ parameters ))
557
+ link = generate_request('ModifyDBParameterGroup', request_hash)
558
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
559
+ end
560
+
561
+ # Delete DBParameter Group.
562
+ #
563
+ # rds.delete_db_parameter_group('kd1') #=> true
564
+ #
565
+ def delete_db_parameter_group(db_parameter_group_name)
566
+ link = generate_request('DeleteDBParameterGroup', 'DBParameterGroupName' => db_parameter_group_name)
567
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
568
+ end
569
+
570
+ # Modify the parameters of a DBParameterGroup to the engine/system default value.
571
+ #
572
+ # # Reset all parameters
573
+ # rds.reset_db_parameter_group('kd2', :all ) #=> true
574
+ #
575
+ # # Reset custom parameters
576
+ # rds.reset_db_parameter_group('kd2', 'max_allowed_packet', 'auto_increment_increment' ) #=> true
577
+ # rds.reset_db_parameter_group('kd2', 'max_allowed_packet', 'auto_increment_increment' => 'immediate' ) #=> true
578
+ #
579
+ def reset_db_parameter_group(db_parameter_group_name, *params)
580
+ params = params.flatten
581
+ request_hash = { 'DBParameterGroupName' => db_parameter_group_name }
582
+ if params.first.to_s == 'all'
583
+ request_hash['ResetAllParameters'] = true
584
+ else
585
+ tmp = []
586
+ params.each{ |item| tmp |= item.to_a }
587
+ params = []
588
+ tmp.each do |key, method|
589
+ method = 'pending-reboot' unless method
590
+ params << [key, method]
591
+ end
592
+ request_hash.merge!( amazonize_list(['Parameters.member.?.ParameterName',
593
+ 'Parameters.member.?.ApplyMethod'],
594
+ params ))
595
+ end
596
+ link = generate_request('ResetDBParameterGroup', request_hash)
597
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
598
+ end
599
+
600
+ # Get the detailed parameters list for a particular DBParameterGroup.
601
+ #
602
+ # rds.describe_db_parameters('kd1') #=>
603
+ # [{:is_modifiable=>true,
604
+ # :apply_type=>"static",
605
+ # :source=>"engine-default",
606
+ # :allowed_values=>"ON,OFF",
607
+ # :description=>"Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded",
608
+ # :name=>"allow-suspicious-udfs",
609
+ # :data_type=>"boolean"},
610
+ # {:is_modifiable=>true,
611
+ # :apply_type=>"dynamic",
612
+ # :source=>"engine-default",
613
+ # :allowed_values=>"1-65535",
614
+ # :description=>"Intended for use with master-to-master replication, and can be used to control the operation of AUTO_INCREMENT columns",
615
+ # :name=>"auto_increment_increment",
616
+ # :data_type=>"integer"}, ... ]
617
+ #
618
+ # # List parameters by 20
619
+ # rds.describe_db_parameters('kd1', :max_records=>20) do |response|
620
+ # puts response.inspect
621
+ # true
622
+ # end
623
+ #
624
+ def describe_db_parameters(*db_parameter_group_name, &block)
625
+ item, params = AwsUtils::split_items_and_params(db_parameter_group_name)
626
+ params['DBParameterGroupName'] = item
627
+ result = []
628
+ incrementally_list_items('DescribeDBParameters', DescribeDbParametersParser, params) do |response|
629
+ result += response[:parameters]
630
+ block ? block.call(response) : true
631
+ end
632
+ result
633
+ end
634
+
635
+ # Describe a default parameters for the parameter group family.
636
+ #
637
+ # rds.describe_engine_default_parameters('MySQL5.1') #=>
638
+ # [{:is_modifiable=>true,
639
+ # :apply_type=>"static",
640
+ # :source=>"engine-default",
641
+ # :allowed_values=>"ON,OFF",
642
+ # :description=>"Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded",
643
+ # :name=>"allow-suspicious-udfs",
644
+ # :data_type=>"boolean"},
645
+ # {:is_modifiable=>true,
646
+ # :apply_type=>"dynamic",
647
+ # :source=>"engine-default",
648
+ # :allowed_values=>"1-65535",
649
+ # :description=>"Intended for use with master-to-master replication, and can be used to control the operation of AUTO_INCREMENT columns",
650
+ # :name=>"auto_increment_increment",
651
+ # :data_type=>"integer"}, ... ]
652
+ #
653
+ def describe_engine_default_parameters(*db_parameter_group_family, &block)
654
+ db_parameter_group_family = ['MySQL5.1'] if db_parameter_group_family.right_blank?
655
+ item, params = AwsUtils::split_items_and_params(db_parameter_group_family)
656
+ params['DBParameterGroupFamily'] = item if item
657
+ result = []
658
+ incrementally_list_items('DescribeEngineDefaultParameters', DescribeDbParametersParser, params) do |response|
659
+ result += response[:parameters]
660
+ block ? block.call(response) : true
661
+ end
662
+ result
663
+ end
664
+
665
+ # Describe a list of orderable DB Instance options for the specified engine.
666
+ # Optionals: +:instance_class+, +:engine_version+ , +:license_model+, +:vpc+
667
+ #
668
+ # rds.describe_orderable_db_instance_options('oracle-ee', :engine_version => '11.2.0.2.v2') #=>
669
+ # [{:read_replica_capable=>false,
670
+ # :instance_class=>"db.m1.large",
671
+ # :availability_zones=>["us-east-1a", "us-east-1b", "us-east-1d"],
672
+ # :engine=>"oracle-ee",
673
+ # :license_model=>"bring-your-own-license",
674
+ # :engine_version=>"11.2.0.2.v2",
675
+ # :multi_az_capable=>"false"}, ... ]
676
+ #
677
+ def describe_orderable_db_instance_options(engine, params={}, &block)
678
+ request_hash = { 'Engine' => engine }
679
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
680
+ request_hash['EngineVersion'] = params[:engine_version] unless params[:engine_version].right_blank?
681
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
682
+ request_hash['Vpc'] = !!params[:vpc] if params.has_key?(:vpc)
683
+ result = []
684
+ incrementally_list_items('DescribeOrderableDBInstanceOptions', DescribeOrderableDBInstanceOptionsParser, request_hash) do |response|
685
+ result += response[:items]
686
+ block ? block.call(response) : true
687
+ end
688
+ result
689
+ end
690
+
691
+ # --------------------------------------------
692
+ # DB Snapshots
693
+ # --------------------------------------------
694
+
695
+ # Get DBSecurityGroup details for a particular customer or for a particular DBSecurityGroup if a name is specified.
696
+ # Optional params: +:instance_aws_id+
697
+ #
698
+ # # all snapshots
699
+ # rds.describe_db_snapshots #=>
700
+ # [{:status=>"Available",
701
+ # :instance_aws_id=>"kd-test-n1",
702
+ # :allocated_storage=>25,
703
+ # :availability_zone=>"us-east-1b",
704
+ # :aws_id=>"kd-test-n1-final-snapshot-at-20090630131215",
705
+ # :engine=>"MySQL5.1",
706
+ # :endpoint_port=>3306,
707
+ # :instance_create_time=>"2009-06-30T12:48:15.590Z",
708
+ # :master_username=>"payless",
709
+ # :snapshot_time=>"2009-06-30T13:16:48.496Z"}, ...]
710
+ #
711
+ # # all snapshots for a custom instance
712
+ # rds.describe_db_snapshots(:instance_aws_id => 'kd-test-n3') #=>
713
+ # [{:status=>"Available",
714
+ # :instance_aws_id=>"kd-test-n3",
715
+ # :allocated_storage=>25,
716
+ # :availability_zone=>"us-east-1a",
717
+ # :aws_id=>"kd-test-n3-final-snapshot-20090713074916",
718
+ # :engine=>"MySQL5.1",
719
+ # :endpoint_port=>3306,
720
+ # :instance_create_time=>"2009-06-30T12:51:32.540Z",
721
+ # :master_username=>"payless",
722
+ # :snapshot_time=>"2009-07-13T07:52:35.542Z"}]
723
+ #
724
+ # # a snapshot by id
725
+ # rds.describe_db_snapshots('my-awesome-db-final-snapshot-20090713075554') #=>
726
+ # [{:status=>"Available",
727
+ # :allocated_storage=>25,
728
+ # :engine=>"MySQL5.1",
729
+ # :instance_aws_id=>"my-awesome-db",
730
+ # :availability_zone=>"us-east-1a",
731
+ # :instance_create_time=>"2009-07-13T07:53:08.912Z",
732
+ # :endpoint_port=>3306,
733
+ # :master_username=>"medium",
734
+ # :aws_id=>"my-awesome-db-final-snapshot-20090713075554",
735
+ # :snapshot_time=>"2009-07-13T07:59:17.537Z"}]
736
+ #
737
+ def describe_db_snapshots(params={}, &block)
738
+ item, params = AwsUtils::split_items_and_params(params)
739
+ params['DBSnapshotIdentifier'] = item if item
740
+ params['DBInstanceIdentifier'] = params.delete(:instance_aws_id) unless params[:instance_aws_id].right_blank?
741
+ result = []
742
+ incrementally_list_items('DescribeDBSnapshots', DescribeDbSnapshotsParser, params) do |response|
743
+ result += response[:db_snapshots]
744
+ block ? block.call(response) : true
745
+ end
746
+ result
747
+ end
748
+
749
+ # Create a DBSnapshot. The source DBInstance must be in Available state
750
+ #
751
+ # rds.create_db_snapshot('remove-me-tomorrow-2', 'my-awesome-db-g7' ) #=>
752
+ # {:status=>"PendingCreation",
753
+ # :allocated_storage=>50,
754
+ # :availability_zone=>"us-east-1b",
755
+ # :engine=>"MySQL5.1",
756
+ # :aws_id=>"remove-me-tomorrow-2",
757
+ # :instance_create_time=>"2009-07-13T09:35:39.243Z",
758
+ # :endpoint_port=>3306,
759
+ # :instance_aws_id=>"my-awesome-db-g7",
760
+ # :db_master_username=>"username"}
761
+ #
762
+ def create_db_snapshot(aws_id, instance_aws_id)
763
+ link = generate_request('CreateDBSnapshot', 'DBSnapshotIdentifier' => aws_id,
764
+ 'DBInstanceIdentifier' => instance_aws_id)
765
+ request_info(link, DescribeDbSnapshotsParser.new(:logger => @logger))[:db_snapshots].first
766
+ end
767
+
768
+ # Create a new RDS instance from a DBSnapshot. The source DBSnapshot must be
769
+ # in the "Available" state. The new RDS instance is created with the Default security group.
770
+ #
771
+ # Optional params: +:instance_class+, +:endpoint_port+, +:availability_zone+, +:multi_az+,
772
+ # +:auto_minor_version_upgrade+, +:license_model+, +:db_name+, +:engine+, +:db_subnet_group_name+,
773
+ # +:iops+, +:option_group_name+
774
+ #
775
+ # rds.restore_db_instance_from_db_snapshot('ahahahaha-final-snapshot-20090828081159', 'q1') #=>
776
+ # {:status=>"creating",
777
+ # :pending_modified_values=>{},
778
+ # :allocated_storage=>42,
779
+ # :db_security_groups=>[],
780
+ # :master_username=>"kd",
781
+ # :availability_zone=>"us-east-1a",
782
+ # :aws_id=>"q1",
783
+ # :create_time=>"2009-08-29T18:07:01.510Z",
784
+ # :instance_class=>"Medium",
785
+ # :preferred_maintenance_window=>"Sun:05:00-Sun:09:00",
786
+ # :engine=>"MySQL",
787
+ # :engine_version=>"5.1.49"}
788
+ #
789
+ def restore_db_instance_from_db_snapshot(snapshot_aws_id, instance_aws_id, params={})
790
+ request_hash = { 'DBSnapshotIdentifier' => snapshot_aws_id,
791
+ 'DBInstanceIdentifier' => instance_aws_id }
792
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
793
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
794
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
795
+ request_hash['MultiAZ'] = params[:multi_az] unless params[:multi_az].nil?
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
+ request_hash['DBSubnetGroupName'] = params[:db_subnet_group_name] unless params[:db_subnet_group_name].right_blank?
801
+ request_hash['Iops'] = params[:iops] unless params[:iops].right_blank?
802
+ request_hash['OptionGroupName'] = params[:option_group_name] unless params[:option_group_name].right_blank?
803
+ link = generate_request('RestoreDBInstanceFromDBSnapshot', request_hash)
804
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
805
+ end
806
+
807
+ # Create a new RDS instance from a point-in-time system snapshot. The target
808
+ # database is created from the source database restore point with the same configuration as
809
+ # the original source database, except that the new RDS instance is created with the default
810
+ # security group.
811
+ #
812
+ # Optional params: +:instance_class+, +:endpoint_port+, +:availability_zone+, +:multi_az+, +:restore_time+,
813
+ # +:auto_minor_version_upgrade+, +:use_latest_restorable_time+, +:license_model+, +:db_name+, +:engine+
814
+ # +:db_subnet_group_name+, +:iops+, +:option_group_name+
815
+ #
816
+ def restore_db_instance_to_point_in_time(instance_aws_id, new_instance_aws_id, params={})
817
+ request_hash = { 'SourceDBInstanceIdentifier' => instance_aws_id,
818
+ 'TargetDBInstanceIdentifier' => new_instance_aws_id}
819
+ request_hash['UseLatestRestorableTime'] = params[:use_latest_restorable_time].to_s unless params[:use_latest_restorable_time].nil?
820
+ request_hash['RestoreTime'] = params[:restore_time] unless params[:restore_time].right_blank?
821
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
822
+ request_hash['MultiAZ'] = params[:multi_az] unless params[:multi_az].nil?
823
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
824
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
825
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade] unless params[:auto_minor_version_upgrade].nil?
826
+ request_hash['LicenseModel'] = params[:license_model] unless params[:license_model].right_blank?
827
+ request_hash['DBName'] = params[:db_name] unless params[:db_name].right_blank?
828
+ request_hash['Engine'] = params[:engine] unless params[:enginel].right_blank?
829
+ request_hash['DBSubnetGroupName'] = params[:db_subnet_group_name] unless params[:db_subnet_group_name].right_blank?
830
+ request_hash['Iops'] = params[:iops] unless params[:iops].right_blank?
831
+ request_hash['OptionGroupName'] = params[:option_group_name] unless params[:option_group_name].right_blank?
832
+ link = generate_request('RestoreDBInstanceToPointInTime', request_hash)
833
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
834
+ end
835
+
836
+ # Delete a DBSnapshot. The DBSnapshot must be in the Available state to be deleted.
837
+ #
838
+ # rds.delete_db_snapshot('remove-me-tomorrow-1') #=>
839
+ # {:status=>"Deleted",
840
+ # :allocated_storage=>50,
841
+ # :instance_create_time=>"2009-07-13T09:27:01.053Z",
842
+ # :availability_zone=>"us-east-1a",
843
+ # :db_master_username=>"username",
844
+ # :aws_id=>"remove-me-tomorrow-1",
845
+ # :snapshot_time=>"2009-07-13T10:59:30.227Z",
846
+ # :endpoint_port=>3306,
847
+ # :instance_aws_id=>"my-awesome-db-g5",
848
+ # :engine=>"MySQL5.1"}
849
+ #
850
+ def delete_db_snapshot(aws_id)
851
+ link = generate_request('DeleteDBSnapshot', 'DBSnapshotIdentifier' => aws_id)
852
+ request_info(link, DescribeDbSnapshotsParser.new(:logger => @logger))[:db_snapshots].first
853
+ end
854
+
855
+ # --------------------------------------------
856
+ # DB Events
857
+ # --------------------------------------------
858
+
859
+ # Get events related to RDS instances and DBSecurityGroups for the past 14 days.
860
+ # Optional params: +:duration+, +:start_time+, +:end_time+, +:aws_id+,
861
+ # +:source_type+('db-instance', 'db-security-group', 'db-snapshot', 'db-parameter-group')
862
+ #
863
+ # # get all enevts
864
+ # rds.describe_events #=>
865
+ # [{:aws_id=>"my-awesome-db-g4",
866
+ # :source_type=>"DBInstance",
867
+ # :message=>"Started user snapshot for database instance:my-awesome-db-g4",
868
+ # :date=>"2009-07-13T10:54:13.661Z"},
869
+ # {:aws_id=>"my-awesome-db-g5",
870
+ # :source_type=>"DBInstance",
871
+ # :message=>"Started user snapshot for database instance:my-awesome-db-g5",
872
+ # :date=>"2009-07-13T10:55:13.674Z"},
873
+ # {:aws_id=>"my-awesome-db-g7",
874
+ # :source_type=>"DBInstance",
875
+ # :message=>"Started user snapshot for database instance:my-awesome-db-g7",
876
+ # :date=>"2009-07-13T10:56:34.226Z"}]
877
+ #
878
+ # # get all events since yesterday
879
+ # rds.describe_events(:start_date => 1.day.ago)
880
+ #
881
+ # # get last 60 min events
882
+ # rds.describe_events(:duration => 60)
883
+ #
884
+ def describe_events(params={}, &block)
885
+ params = params.dup
886
+ params['SourceIdentifier'] = params.delete(:aws_id) unless params[:aws_id].right_blank?
887
+ params['SourceType'] = params.delete(:source_type) unless params[:source_type].right_blank?
888
+ params['Duration'] = params.delete(:duration) unless params[:duration].right_blank?
889
+ params['StartDate'] = fix_date(params.delete(:start_date)) unless params[:start_date].right_blank?
890
+ params['EndDate'] = fix_date(params.delete(:end_date)) unless params[:end_date].right_blank?
891
+ result = []
892
+ incrementally_list_items('DescribeEvents', DescribeEventsParser, params) do |response|
893
+ result += response[:events]
894
+ block ? block.call(response) : true
895
+ end
896
+ result
897
+ end
898
+
899
+ def fix_date(date) # :nodoc:
900
+ date = Time.at(date) if date.is_a?(Fixnum)
901
+ date = date.utc.strftime('%Y-%m-%dT%H:%M:%SZ') if date.is_a?(Time)
902
+ date
903
+ end
904
+
905
+ # --------------------------------------------
906
+ # DB Engine Versions
907
+ # --------------------------------------------
908
+
909
+ # Get a list of the available DB engines.
910
+ # Optional params: +:db_parameter_group_family+, +:default_only+, +:engine+, +:engine_version+. +:engine_version+
911
+ #
912
+ # rds.describe_db_engine_versions #=>
913
+ # [{:db_parameter_group_family=>"mysql5.1",
914
+ # :engine=>"mysql",
915
+ # :db_engine_description=>"MySQL Community Edition",
916
+ # :db_engine_version_description=>"Mysql 5.1.45",
917
+ # :engine_version=>"5.1.45"},
918
+ # {:db_parameter_group_family=>"oracle-se1-11.2",
919
+ # :engine=>"oracle-se1",
920
+ # :db_engine_description=>"Oracle Database Standard Edition One",
921
+ # :db_engine_version_description=>
922
+ # "Oracle Standard Edition One - DB Engine Version 11.2.0.2.v2",
923
+ # :engine_version=>"11.2.0.2.v2"}]
924
+ #
925
+ # rds.describe_db_engine_versions(:list_supported_character_sets => true) #=>
926
+ # [{:db_parameter_group_family=>"mysql5.1",
927
+ # :engine=>"mysql",
928
+ # :db_engine_description=>"MySQL Community Edition",
929
+ # :engine_version=>"5.1.45",
930
+ # :db_engine_version_description=>"MySQL 5.1.45"},
931
+ # {:db_parameter_group_family=>"oracle-ee-11.2",
932
+ # :engine=>"oracle-ee",
933
+ # :supported_character_sets=>
934
+ # [{:name=>"AL32UTF8",
935
+ # :description=>"Unicode 5.0 UTF-8 Universal character set"},
936
+ # {:name=>"JA16EUC", :description=>"EUC 24-bit Japanese"},
937
+ # {:name=>"JA16EUCTILDE",
938
+ # :description=>
939
+ # "The same as JA16EUC except for the way that the wave dash and the tilde are mapped to and from Unicode."},
940
+ # {:name=>"JA16SJIS", :description=>"Shift-JIS 16-bit Japanese"},
941
+ # {:name=>"WE8ISO8859P9",
942
+ # :description=>"ISO 8859-9 West European and Turkish"},
943
+ # {:name=>"US7ASCII", :description=>"ASCII 7-bit American"}],
944
+ # :db_engine_description=>"Oracle Database Enterprise Edition",
945
+ # :default_character_set=>
946
+ # {:name=>"AL32UTF8",
947
+ # :description=>"Unicode 5.0 UTF-8 Universal character set"},
948
+ # :engine_version=>"11.2.0.2.v3",
949
+ # :db_engine_version_description=>"Oracle 11.2.0.2.v3"}, ... ]
950
+ #
951
+ # P.S. http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_DescribeDBEngineVersions.html
952
+ #
953
+ def describe_db_engine_versions(params={}, &block)
954
+ params = params.dup
955
+ params['DBParameterGroupFamily'] = params.delete(:db_parameter_group_family) unless params[:db_parameter_group_family].right_blank?
956
+ params['DefaultOnly'] = params.delete(:default_only).to_s unless params[:default_only].nil?
957
+ params['Engine'] = params.delete(:engine) unless params[:engine].right_blank?
958
+ params['EngineVersion'] = params.delete(:engine_version) unless params[:engine_version].right_blank?
959
+ params['ListSupportedCharacterSets'] = !!params.delete(:list_supported_character_sets) if params.has_key?(:list_supported_character_sets)
960
+ result = []
961
+ incrementally_list_items('DescribeDBEngineVersions', DescribeDBEngineVersionsParser, params) do |response|
962
+ result += response[:db_engine_versions]
963
+ block ? block.call(response) : true
964
+ end
965
+ result
966
+ end
967
+
968
+ # --------------------------------------------
969
+ # DB Replicas
970
+ # --------------------------------------------
971
+
972
+ # Create a DB Instance that acts as a Read Replica of a source DB Instance.
973
+ #
974
+ # Optional params: +:endpoint_port+, +:availability_zone+, +:instance_class+, +:auto_minor_version_upgrade+,
975
+ # +:iops+, +:option_group_name+
976
+ #
977
+ # rds.create_db_instance_read_replica('kd-delete-me-01-replica-01', 'kd-delete-me-01',
978
+ # :instance_class => 'db.m1.small',
979
+ # :endpoint_port => '11000',
980
+ # :auto_minor_version_upgrade => false ) #=>
981
+ # {:auto_minor_version_upgrade=>false,
982
+ # :read_replica_source_db_instance_identifier=>"kd-delete-me-01",
983
+ # :status=>"creating",
984
+ # :backup_retention_period=>0,
985
+ # :allocated_storage=>30,
986
+ # :read_replica_db_instance_identifiers=>[],
987
+ # :engine_version=>"5.1.50",
988
+ # :aws_id=>"kd-delete-me-01-replica-01",
989
+ # :multi_az=>false,
990
+ # :preferred_maintenance_window=>"sun:06:00-sun:10:00",
991
+ # :master_username=>"username",
992
+ # :preferred_backup_window=>"02:00-04:00",
993
+ # :db_parameter_group=>{:status=>"in-sync", :name=>"default.mysql5.1"},
994
+ # :engine=>"mysql",
995
+ # :db_security_groups=>[{:status=>"active", :name=>"default"}],
996
+ # :instance_class=>"db.m1.small",
997
+ # :pending_modified_values=>{}}
998
+ #
999
+ def create_db_instance_read_replica(aws_id, source_db_instance_identifier, params={})
1000
+ request_hash = { 'DBInstanceIdentifier' => aws_id,
1001
+ 'SourceDBInstanceIdentifier' => source_db_instance_identifier}
1002
+ request_hash['Port'] = params[:endpoint_port] unless params[:endpoint_port].right_blank?
1003
+ request_hash['AvailabilityZone'] = params[:availability_zone] unless params[:availability_zone].right_blank?
1004
+ request_hash['DBInstanceClass'] = params[:instance_class] unless params[:instance_class].right_blank?
1005
+ request_hash['AutoMinorVersionUpgrade'] = params[:auto_minor_version_upgrade].to_s unless params[:auto_minor_version_upgrade].nil?
1006
+ request_hash['Iops'] = params[:iops] unless params[:iops].right_blank?
1007
+ request_hash['OptionGroupName'] = params[:option_group_name] unless params[:option_group_name].right_blank?
1008
+ link = generate_request('CreateDBInstanceReadReplica', request_hash)
1009
+ request_info(link, DescribeDbInstancesParser.new(:logger => @logger))[:db_instances].first
1010
+ end
1011
+
1012
+
1013
+ #---------------------------------------------
1014
+ # Reserved Instances
1015
+ #---------------------------------------------
1016
+
1017
+ # Lists available reserved DB Instance offerings.
1018
+ # Options: :aws_id, :instance_class, :duration, :product_description, :multi_az
1019
+ #
1020
+ # rds.describe_reserved_db_instances_offerings #=>
1021
+ # [{:recurring_charges=>[],
1022
+ # :offering_type=>"Medium Utilization",
1023
+ # :duration=>94608000,
1024
+ # :currency_code=>"USD",
1025
+ # :fixed_price=>82.0,
1026
+ # :product_description=>"oracle-se(byol)",
1027
+ # :usage_price=>0.01,
1028
+ # :aws_id=>"248e7b75-01ff-4f1d-8fad-918b76337c13",
1029
+ # :multi_az=>false,
1030
+ # :instance_class=>"db.t1.micro"},
1031
+ # {:recurring_charges=>[{:frequency=>"Hourly", :amount=>"0.24"}],
1032
+ # :offering_type=>"Heavy Utilization",
1033
+ # :duration=>31536000,
1034
+ # :currency_code=>"USD",
1035
+ # :fixed_price=>1040.0,
1036
+ # :product_description=>"sqlserver-web(li)",
1037
+ # :usage_price=>0.0,
1038
+ # :aws_id=>"248e7b75-05eb-46df-a7b8-4117b5001667",
1039
+ # :multi_az=>false,
1040
+ # :instance_class=>"db.m2.xlarge"}, ... ]
1041
+ #
1042
+ # rds.describe_reserved_db_instances_offerings(:aws_id => "248e7b75-49a7-4cd7-9a9b-354f4906a9b1") #=>
1043
+ # [{:duration=>94608000,
1044
+ # :multi_az=>true,
1045
+ # :fixed_price=>700.0,
1046
+ # :usage_price=>0.092,
1047
+ # :currency_code=>"USD",
1048
+ # :aws_id=>"248e7b75-49a7-4cd7-9a9b-354f4906a9b1",
1049
+ # :instance_class=>"db.m1.small",
1050
+ # :product_description=>"mysql"}]
1051
+ #
1052
+ # rds.describe_reserved_db_instances_offerings(:instance_class => "db.m1.small")
1053
+ # rds.describe_reserved_db_instances_offerings(:duration => 31536000)
1054
+ # rds.describe_reserved_db_instances_offerings(:product_description => 'mysql')
1055
+ # rds.describe_reserved_db_instances_offerings(:multi_az => true)
1056
+ #
1057
+ def describe_reserved_db_instances_offerings(params={}, &block)
1058
+ params = params.dup
1059
+ params['ReservedDBInstancesOfferingId'] = params.delete(:aws_id) unless params[:aws_id].right_blank?
1060
+ params['DBInstanceClass'] = params.delete(:instance_class) unless params[:instance_class].right_blank?
1061
+ params['Duration'] = params.delete(:duration) unless params[:duration].right_blank?
1062
+ params['ProductDescription'] = params.delete(:product_description) unless params[:product_description].right_blank?
1063
+ params['MultiAZ'] = params.delete(:multi_az).to_s unless params[:multi_az].nil?
1064
+ result = []
1065
+ incrementally_list_items('DescribeReservedDBInstancesOfferings', DescribeReservedDBInstancesOfferingsParser, params) do |response|
1066
+ result += response[:reserved_db_instances_offerings]
1067
+ block ? block.call(response) : true
1068
+ end
1069
+ result
1070
+ end
1071
+
1072
+ # Returns information about reserved DB Instances for this account, or about
1073
+ # a specified reserved DB Instance.
1074
+ # Options: :aws_id, :offering_aws_id, :instance_class, :duration, :product_description, :multi_az
1075
+ #
1076
+ # rds.describe_reserved_db_instances
1077
+ # rds.describe_reserved_db_instances(:aws_id => "myreservedinstance")
1078
+ # rds.describe_reserved_db_instances(:offering_aws_id => "248e7b75-49a7-4cd7-9a9b-354f4906a9b1")
1079
+ # rds.describe_reserved_db_instances(:instance_class => "db.m1.small")
1080
+ # rds.describe_reserved_db_instances(:duration => 31536000)
1081
+ # rds.describe_reserved_db_instances(:product_description => 'mysql')
1082
+ # rds.describe_reserved_db_instances_offerings(:multi_az => true)
1083
+ #
1084
+ def describe_reserved_db_instances(params={}, &block)
1085
+ params = params.dup
1086
+ params['ReservedDBInstancesId'] = params.delete(:aws_id) unless params[:aws_id].right_blank?
1087
+ params['ReservedDBInstancesOfferingId'] = params.delete(:offering_aws_id) unless params[:offering_aws_id].right_blank?
1088
+ params['DBInstanceClass'] = params.delete(:instance_class) unless params[:instance_class].right_blank?
1089
+ params['Duration'] = params.delete(:duration) unless params[:duration].right_blank?
1090
+ params['ProductDescription'] = params.delete(:product_description) unless params[:product_description].right_blank?
1091
+ params['MultiAZ'] = params.delete(:multi_az).to_s unless params[:multi_az].nil?
1092
+ result = []
1093
+ incrementally_list_items('DescribeReservedDBInstances', DescribeReservedDBInstancesParser, params) do |response|
1094
+ result += response[:reserved_db_instances]
1095
+ block ? block.call(response) : true
1096
+ end
1097
+ result
1098
+ end
1099
+
1100
+ # Purchases a reserved DB Instance offering.
1101
+ # Options: :aws_id, :count
1102
+ def purchase_reserved_db_instances_offering(offering_aws_id, params={})
1103
+ request_hash = { 'ReservedDBInstancesOfferingId' => offering_aws_id }
1104
+ request_hash['ReservedDBInstanceId'] = params[:aws_id] unless params[:aws_id].right_blank?
1105
+ request_hash['DBInstanceCount'] = params[:count] unless params[:count].right_blank?
1106
+ link = generate_request('PurchaseReservedDBInstancesOffering', request_hash)
1107
+ request_info(link, DescribeReservedDBInstancesParser.new(:logger => @logger))[:reserved_db_instances].first
1108
+ end
1109
+
1110
+ #---------------------------------------------
1111
+ # Subnet Groups
1112
+ #---------------------------------------------
1113
+
1114
+ # Lists available DB Subnet Groups.
1115
+ # Options: :name, :max_records, :marker
1116
+ #
1117
+ # rds.describe_db_subnet_groups #=>
1118
+ # [{:subnets=>
1119
+ # [{:availability_zone=>
1120
+ # {:name=>"us-east-1d", :provisioned_iops_capable=>false},
1121
+ # :status=>"Active",
1122
+ # :subnet_id=>"subnet-5259d03a"},
1123
+ # {:availability_zone=>
1124
+ # {:name=>"us-east-1a", :provisioned_iops_capable=>false},
1125
+ # :status=>"Active",
1126
+ # :subnet_id=>"subnet-eb518f83"}],
1127
+ # :vpc_id=>"vpc-10518f78",
1128
+ # :status=>"Complete",
1129
+ # :description=>"delete me please",
1130
+ # :name=>"kd-subnet-group"},
1131
+ # {:subnets=>
1132
+ # [{:availability_zone=>
1133
+ # {:name=>"us-east-1a", :provisioned_iops_capable=>false},
1134
+ # :status=>"Active",
1135
+ # :subnet_id=>"subnet-eb518f83"},
1136
+ # {:availability_zone=>
1137
+ # {:name=>"us-east-1d", :provisioned_iops_capable=>false},
1138
+ # :status=>"Active",
1139
+ # :subnet_id=>"subnet-5259d03a"}],
1140
+ # :vpc_id=>"vpc-10518f78",
1141
+ # :status=>"Complete",
1142
+ # :description=>"delete me please",
1143
+ # :name=>"kd-subnet-group-1"}]
1144
+ #
1145
+ # P.S. http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_DescribeDBSubnetGroups.html
1146
+ #
1147
+ def describe_db_subnet_groups(params={}, &block)
1148
+ params = params.dup
1149
+ params['DBSubnetGroupName'] = params.delete(:name) unless params[:name].right_blank?
1150
+ result = []
1151
+ incrementally_list_items('DescribeDBSubnetGroups', DescribeDBSubnetGroupsParser, params) do |response|
1152
+ result += response[:subnet_groups]
1153
+ block ? block.call(response) : true
1154
+ end
1155
+ result
1156
+ end
1157
+
1158
+ def get_db_subnet_group(group_name, &block)
1159
+ describe_db_subnet_groups(:name => group_name, &block)
1160
+ end
1161
+
1162
+ # Create a new DB Subnet Group.
1163
+ #
1164
+ # rds.create_db_subnet_group('kd-subnet-group-1', ['subnet-5259d03a', 'subnet-eb518f83'], 'delete me please') #=>
1165
+ # {:subnets=>
1166
+ # [{:availability_zone=>
1167
+ # {:name=>"us-east-1a", :provisioned_iops_capable=>false},
1168
+ # :status=>"Active",
1169
+ # :subnet_id=>"subnet-eb518f83"},
1170
+ # {:availability_zone=>
1171
+ # {:name=>"us-east-1d", :provisioned_iops_capable=>false},
1172
+ # :status=>"Active",
1173
+ # :subnet_id=>"subnet-5259d03a"}],
1174
+ # :vpc_id=>"vpc-10518f78",
1175
+ # :status=>"Complete",
1176
+ # :description=>"delete me please",
1177
+ # :name=>"kd-subnet-group-1"}
1178
+ #
1179
+ # P.S. http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_CreateDBSubnetGroup.html
1180
+ #
1181
+ def create_db_subnet_group(subnet_group_name, subnets, subnet_group_description = '-')
1182
+ request_hash = { 'DBSubnetGroupName' => subnet_group_name,
1183
+ 'DBSubnetGroupDescription' => subnet_group_description }
1184
+ request_hash.merge!(amazonize_list('SubnetIds.member', subnets))
1185
+ link = generate_request('CreateDBSubnetGroup', request_hash)
1186
+ request_info(link, DescribeDBSubnetGroupsParser.new(:logger => @logger))[:subnet_groups].first
1187
+ end
1188
+
1189
+ # Modify an existing DB Subnet Group.
1190
+ #
1191
+ # rds.modify_db_subnet_group('kd-subnet-group', ['subnet-5259d03a', 'subnet-eb518f83'], 'hahaha!') #=>
1192
+ # {:subnets=>
1193
+ # [{:availability_zone=>
1194
+ # {:name=>"us-east-1d", :provisioned_iops_capable=>false},
1195
+ # :status=>"Active",
1196
+ # :subnet_id=>"subnet-5259d03a"},
1197
+ # {:availability_zone=>
1198
+ # {:name=>"us-east-1a", :provisioned_iops_capable=>false},
1199
+ # :status=>"Active",
1200
+ # :subnet_id=>"subnet-eb518f83"}],
1201
+ # :vpc_id=>"vpc-10518f78",
1202
+ # :status=>"Complete",
1203
+ # :description=>"hahaha!",
1204
+ # :name=>"kd-subnet-group"}
1205
+ #
1206
+ # P.S. http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_ModifyDBSubnetGroup.html
1207
+ #
1208
+ def modify_db_subnet_group(subnet_group_name, subnets, subnet_group_description = '')
1209
+ request_hash = { 'DBSubnetGroupName' => subnet_group_name}
1210
+ request_hash['DBSubnetGroupDescription'] = subnet_group_description unless subnet_group_description.right_blank?
1211
+ request_hash.merge!(amazonize_list('SubnetIds.member', subnets))
1212
+ link = generate_request('ModifyDBSubnetGroup', request_hash)
1213
+ request_info(link, DescribeDBSubnetGroupsParser.new(:logger => @logger))[:subnet_groups].first
1214
+ end
1215
+
1216
+ # Delete a DB Subnet Group.
1217
+ #
1218
+ # rds.delete_db_subnet_group("kd-subnet-group-1") #=> true
1219
+ #
1220
+ # P.S. http://docs.amazonwebservices.com/AmazonRDS/latest/APIReference/API_DeleteDBSubnetGroup.html
1221
+ #
1222
+ def delete_db_subnet_group(name)
1223
+ link = generate_request('DeleteDBSubnetGroup', 'DBSubnetGroupName' => name)
1224
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
1225
+ end
1226
+
1227
+ # --------------------------------------------
1228
+ # Parsers
1229
+ # --------------------------------------------
1230
+
1231
+ # --------------------------------------------
1232
+ # DB Instances
1233
+ # --------------------------------------------
1234
+
1235
+ class DescribeDbInstancesParser < RightAWSParser # :nodoc:
1236
+ def reset
1237
+ @result = { :db_instances => [] }
1238
+ end
1239
+ def tagstart(name, attributes)
1240
+ case name
1241
+ when 'DBInstance' then @item = { :db_security_groups => [],
1242
+ :pending_modified_values => {},
1243
+ :read_replica_db_instance_identifiers => [],
1244
+ :option_group_membership => {} }
1245
+ when 'DBSecurityGroup' then @db_security_group = {}
1246
+ when 'DBSubnetGroup' then @item[:db_subnet_group] = {}
1247
+ when 'Subnet' then @subnet = { :availability_zone => {} }
1248
+ when 'DBParameterGroup',
1249
+ 'DBParameterGroupStatus' then @db_parameter_group = {}
1250
+ end
1251
+ end
1252
+ def tagend(name)
1253
+ case name
1254
+ when 'Marker' then @result[:marker] = @text
1255
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1256
+ when 'DBInstanceIdentifier' then @item[:aws_id] = @text
1257
+ when 'InstanceCreateTime' then @item[:create_time] = @text
1258
+ when 'Engine' then @item[:engine] = @text
1259
+ when 'DBInstanceStatus' then @item[:status] = @text
1260
+ when 'Address' then @item[:endpoint_address] = @text
1261
+ when 'Port' then @item[:endpoint_port] = @text.to_i
1262
+ when 'MasterUsername' then @item[:master_username] = @text
1263
+ when 'AvailabilityZone' then @item[:availability_zone] = @text
1264
+ when 'LatestRestorableTime' then @item[:latest_restorable_time] = @text
1265
+ when 'LicenseModel' then @item[:license_model] = @text
1266
+ when 'DBName' then @item[:db_name] = @text
1267
+ when 'Iops' then @item[:iops] = @text
1268
+ when 'CharacterSetName' then @item[:character_set_name] = @text
1269
+ when 'ReadReplicaSourceDBInstanceIdentifier' then @item[:read_replica_source_db_instance_identifier] = @text
1270
+ when 'ReadReplicaDBInstanceIdentifier' then @item[:read_replica_db_instance_identifiers] << @text
1271
+ when 'DBParameterGroupName' then @db_parameter_group[:name] = @text
1272
+ when 'ParameterApplyStatus' then @db_parameter_group[:status] = @text
1273
+ when 'DBSecurityGroup' then @item[:db_security_groups] << @db_security_group
1274
+ when 'DBParameterGroup',
1275
+ 'DBParameterGroupStatus' then @item[:db_parameter_group] = @db_parameter_group
1276
+ when 'DBInstance' then @result[:db_instances] << @item
1277
+ else
1278
+ case full_tag_name
1279
+ when %r{DBInstance/DBInstanceClass$} then @item[:instance_class] = @text
1280
+ when %r{DBInstance/AllocatedStorage$} then @item[:allocated_storage] = @text.to_i
1281
+ when %r{DBInstance/MultiAZ$} then @item[:multi_az] = (@text == 'true')
1282
+ when %r{DBInstance/BackupRetentionPeriod$} then @item[:backup_retention_period] = @text.to_i
1283
+ when %r{DBInstance/PreferredMaintenanceWindow$} then @item[:preferred_maintenance_window] = @text
1284
+ when %r{DBInstance/PreferredBackupWindow$} then @item[:preferred_backup_window] = @text
1285
+ when %r{DBInstance/EngineVersion$} then @item[:engine_version] = @text
1286
+ when %r{DBInstance/AutoMinorVersionUpgrade$} then @item[:auto_minor_version_upgrade] = (@text == 'true')
1287
+ when %r{DBInstance/AllowMajorVersionUpgrade$} then @item[:allow_major_version_upgrade] = (@text == 'true')
1288
+ when %r{PendingModifiedValues/DBInstanceClass$} then @item[:pending_modified_values][:instance_class] = @text
1289
+ when %r{PendingModifiedValues/AllocatedStorage$} then @item[:pending_modified_values][:allocated_storage] = @text.to_i
1290
+ when %r{PendingModifiedValues/MasterUserPassword$} then @item[:pending_modified_values][:master_user_password] = @text
1291
+ when %r{PendingModifiedValues/MultiAZ$} then @item[:pending_modified_values][:multi_az] = (@text == 'true')
1292
+ when %r{PendingModifiedValues/BackupRetentionPeriod$} then @item[:pending_modified_values][:backup_retention_period] = @text.to_i
1293
+ when %r{PendingModifiedValues/PreferredMaintenanceWindow$} then @item[:pending_modified_values][:preferred_maintenance_window] = @text
1294
+ when %r{PendingModifiedValues/PreferredBackupWindow$} then @item[:pending_modified_values][:preferred_backup_window] = @text
1295
+ when %r{PendingModifiedValues/EngineVersion$} then @item[:pending_modified_values][:engine_version] = @text
1296
+ when %r{PendingModifiedValues/AutoMinorVersionUpgrade$} then @item[:pending_modified_values][:auto_minor_version_upgrade] = (@text == 'true')
1297
+ when %r{PendingModifiedValues/AllowMajorVersionUpgrade$} then @item[:pending_modified_values][:allow_major_version_upgrade] = (@text == 'true')
1298
+ when %r{OptionGroupMembership/Status$} then @item[:option_group_membership][:status] = @text
1299
+ when %r{OptionGroupMembership/OptionGroupName$} then @item[:option_group_membership][:name] = @text
1300
+ when %r{DBSecurityGroup/Status$} then @db_security_group[:status] = @text
1301
+ when %r{DBSecurityGroup/DBSecurityGroupName$} then @db_security_group[:name] = @text
1302
+ when %r{DBSubnetGroup/DBSubnetGroupDescription$} then @item[:db_subnet_group][:description] = @text
1303
+ when %r{DBSubnetGroup/DBSubnetGroupName$} then @item[:db_subnet_group][:name] = @text
1304
+ when %r{DBSubnetGroup/SubnetGroupStatus$} then @item[:db_subnet_group][:status] = @text
1305
+ when %r{Subnet/SubnetIdentifier$} then @subnet[:subnet_id] = @text
1306
+ when %r{Subnet/SubnetStatus$} then @subnet[:status] = @text
1307
+ when %r{Subnet/AvailabilityZone/Name$} then @subnet[:availability_zone][:name] = @text
1308
+ when %r{Subnet/AvailabilityZone/ProvisionedIopsCapable$} then @subnet[:availability_zone][:provisioned_iops_capable] = @text == 'true'
1309
+ when %r{DBSubnetGroup/Subnet$} then (@item[:db_subnet_group][:subnets] ||= []) << @subnet
1310
+ when %r{DBSubnetGroup/VpcId$} then @item[:db_subnet_group][:vpc_id] = @text
1311
+ end
1312
+ end
1313
+ end
1314
+ end
1315
+
1316
+ class DescribeOrderableDBInstanceOptionsParser < RightAWSParser # :nodoc:
1317
+ def reset
1318
+ @result = { :items => [] }
1319
+ end
1320
+ def tagstart(name, attributes)
1321
+ case name
1322
+ when 'OrderableDBInstanceOption' then @item = { :availability_zones => [] }
1323
+ end
1324
+ end
1325
+ def tagend(name)
1326
+ case name
1327
+ when 'Marker' then @result[:marker] = @text
1328
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1329
+ when 'DBInstanceClass' then @item[:instance_class] = @text
1330
+ when 'Engine' then @item[:engine] = @text
1331
+ when 'EngineVersion' then @item[:engine_version] = @text
1332
+ when 'LicenseModel' then @item[:license_model] = @text
1333
+ when 'MultiAZCapable' then @item[:multi_az_capable] = @text
1334
+ when 'ReadReplicaCapable' then @item[:read_replica_capable] = @text == 'true'
1335
+ when 'Vpc' then @item[:vpc] = @text == 'true'
1336
+ when 'Name' then @item[:availability_zones] << @text
1337
+ when 'OrderableDBInstanceOption' then @result[:items] << @item
1338
+ end
1339
+ end
1340
+ end
1341
+
1342
+ # --------------------------------------------
1343
+ # DB Security Groups
1344
+ # --------------------------------------------
1345
+
1346
+ class DescribeDbSecurityGroupsParser < RightAWSParser # :nodoc:
1347
+ def reset
1348
+ @result = { :db_security_groups => [] }
1349
+ end
1350
+ def tagstart(name, attributes)
1351
+ case name
1352
+ when 'DBSecurityGroup' then @item = { :ec2_security_groups => [], :ip_ranges => [] }
1353
+ when 'IPRange' then @ip_range = {}
1354
+ when 'EC2SecurityGroup' then @ec2_security_group = {}
1355
+ end
1356
+ end
1357
+ def tagend(name)
1358
+ case name
1359
+ when 'Marker' then @result[:marker] = @text
1360
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1361
+ when 'DBSecurityGroupDescription' then @item[:description ] = @text
1362
+ when 'OwnerId' then @item[:owner_id] = @text
1363
+ when 'DBSecurityGroupName' then @item[:name] = @text
1364
+ when 'EC2SecurityGroupId' then @ec2_security_group[:group_id] = @text
1365
+ when 'EC2SecurityGroupName' then @ec2_security_group[:name] = @text
1366
+ when 'EC2SecurityGroupOwnerId' then @ec2_security_group[:owner_id] = @text
1367
+ when 'CIDRIP' then @ip_range[:cidrip] = @text
1368
+ when 'IPRange' then @item[:ip_ranges] << @ip_range
1369
+ when 'EC2SecurityGroup' then @item[:ec2_security_groups] << @ec2_security_group
1370
+ when 'VpcId' then @item[:vpc_id] = @text
1371
+ when 'DBSecurityGroup'
1372
+ # Sort the ip_ranges and ec2_security_groups
1373
+ @item[:ip_ranges].sort!{ |i1,i2| "#{i1[:cidrip]}" <=> "#{i2[:cidrip]}" }
1374
+ @item[:ec2_security_groups].sort!{ |i1,i2| "#{i1[:owner_id]}#{i1[:name]}" <=> "#{i2[:owner_id]}#{i2[:name]}" }
1375
+ @result[:db_security_groups] << @item
1376
+ else
1377
+ case full_tag_name
1378
+ when %r{IPRange/Status$} then @ip_range[:status] = @text
1379
+ when %r{EC2SecurityGroup/Status$} then @ec2_security_group[:status] = @text
1380
+ end
1381
+ end
1382
+ end
1383
+ end
1384
+
1385
+ # --------------------------------------------
1386
+ # DB Security Groups
1387
+ # --------------------------------------------
1388
+
1389
+ class DescribeDbParameterGroupsParser < RightAWSParser # :nodoc:
1390
+ def reset
1391
+ @result = { :db_parameter_groups => [] }
1392
+ end
1393
+ def tagstart(name, attributes)
1394
+ case name
1395
+ when 'DBParameterGroup',
1396
+ 'ModifyDBParameterGroupResult' then @item = { }
1397
+ end
1398
+ end
1399
+ def tagend(name)
1400
+ case name
1401
+ when 'Marker' then @result[:marker] = @text
1402
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1403
+ when 'DBParameterGroupName' then @item[:name] = @text
1404
+ when 'Description' then @item[:description] = @text
1405
+ when 'DBParameterGroupFamily' then @item[:db_parameter_group_family] = @text
1406
+ when 'DBParameterGroup',
1407
+ 'ModifyDBParameterGroupResult' then @result[:db_parameter_groups] << @item
1408
+ end
1409
+ end
1410
+ end
1411
+
1412
+ class DescribeDbParametersParser < RightAWSParser # :nodoc:
1413
+ def reset
1414
+ @result = { :parameters => [] }
1415
+ end
1416
+ def tagstart(name, attributes)
1417
+ case name
1418
+ when 'Parameter' then @item = {}
1419
+ end
1420
+ end
1421
+ def tagend(name)
1422
+ case name
1423
+ when 'Marker' then @result[:marker] = @text
1424
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1425
+ when 'DBParameterGroupName' then @result[:group_name] = @text # DescribeDbParametersResponse
1426
+ when 'DBParameterGroupFamily' then @result[:db_parameter_group_family] = @text # DescribeDBEngineDefaultParametersResponse
1427
+ when 'DataType' then @item[:data_type] = @text
1428
+ when 'Source' then @item[:source] = @text
1429
+ when 'Description' then @item[:description] = @text
1430
+ when 'IsModifiable' then @item[:is_modifiable] = (@text == 'true')
1431
+ when 'ApplyType' then @item[:apply_type] = @text
1432
+ when 'ApplyMethod' then @item[:apply_method] = @text
1433
+ when 'MinimumEngineVersion' then @item[:minimum_engine_version] = @text
1434
+ when 'AllowedValues' then @item[:allowed_values] = @text
1435
+ when 'ParameterName' then @item[:name] = @text
1436
+ when 'ParameterValue' then @item[:value] = @text
1437
+ when 'Parameter' then @result[:parameters] << @item
1438
+ end
1439
+ end
1440
+ end
1441
+
1442
+ # --------------------------------------------
1443
+ # DB Snapshots
1444
+ # --------------------------------------------
1445
+
1446
+ class DescribeDbSnapshotsParser < RightAWSParser # :nodoc:
1447
+ def reset
1448
+ @result = { :db_snapshots => [] }
1449
+ end
1450
+ def tagstart(name, attributes)
1451
+ case name
1452
+ when 'DBSnapshot' then @item = {}
1453
+ end
1454
+ end
1455
+ def tagend(name)
1456
+ case name
1457
+ when 'Marker' then @result[:marker] = @text
1458
+ when 'MaxRecords' then @result[:max_records] = @text.to_i # ?
1459
+ when 'Engine' then @item[:engine] = @text
1460
+ when 'EngineVersion' then @item[:engine_version] = @text
1461
+ when 'InstanceCreateTime' then @item[:instance_create_time] = @text
1462
+ when 'Port' then @item[:endpoint_port] = @text.to_i
1463
+ when 'Status' then @item[:status] = @text
1464
+ when 'AvailabilityZone' then @item[:availability_zone] = @text
1465
+ when 'MasterUsername' then @item[:master_username] = @text
1466
+ when 'AllocatedStorage' then @item[:allocated_storage] = @text.to_i
1467
+ when 'SnapshotCreateTime' then @item[:create_time] = @text
1468
+ when 'DBInstanceIdentifier' then @item[:instance_aws_id] = @text
1469
+ when 'DBSnapshotIdentifier' then @item[:aws_id] = @text
1470
+ when 'LicenseModel' then @item[:license_model] = @text
1471
+ when 'Iops' then @item[:iops] = @text
1472
+ when 'SnapshotType' then @item[:snapshot_type] = @text
1473
+ when 'VpcId' then @item[:vpc_id] = @text
1474
+ when 'DBSnapshot' then @result[:db_snapshots] << @item
1475
+ end
1476
+ end
1477
+ end
1478
+
1479
+ # --------------------------------------------
1480
+ # DB Events
1481
+ # --------------------------------------------
1482
+
1483
+ class DescribeEventsParser < RightAWSParser # :nodoc:
1484
+ def reset
1485
+ @result = { :events => [] }
1486
+ end
1487
+ def tagstart(name, attributes)
1488
+ case name
1489
+ when 'Event' then @item = {}
1490
+ end
1491
+ end
1492
+ def tagend(name)
1493
+ case name
1494
+ when 'Marker' then @result[:marker] = @text
1495
+ when 'MaxRecords' then @result[:max_records] = @text.to_i # ?
1496
+ when 'Date' then @item[:date] = @text
1497
+ when 'SourceIdentifier' then @item[:aws_id] = @text
1498
+ when 'SourceType' then @item[:source_type] = @text
1499
+ when 'Message' then @item[:message] = @text
1500
+ when 'Event' then @result[:events] << @item
1501
+ end
1502
+ end
1503
+ end
1504
+
1505
+ # --------------------------------------------
1506
+ # DB Engine Versions
1507
+ # --------------------------------------------
1508
+
1509
+ class DescribeDBEngineVersionsParser < RightAWSParser # :nodoc:
1510
+ def reset
1511
+ @result = { :db_engine_versions => [] }
1512
+ end
1513
+ def tagstart(name, attributes)
1514
+ case name
1515
+ when 'DBEngineVersion' then @item = {}
1516
+ else
1517
+ case full_tag_name
1518
+ when %r{DefaultCharacterSet$} then @item[:default_character_set] = {}
1519
+ when %r{SupportedCharacterSets/CharacterSet$} then @set = {}
1520
+ end
1521
+ end
1522
+ end
1523
+ def tagend(name)
1524
+ case name
1525
+ when 'Marker' then @result[:marker] = @text
1526
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1527
+ when 'DBParameterGroupFamily' then @item[:db_parameter_group_family] = @text
1528
+ when 'Engine' then @item[:engine] = @text
1529
+ when 'EngineVersion' then @item[:engine_version] = @text
1530
+ when 'DBEngineDescription' then @item[:db_engine_description] = @text
1531
+ when 'DBEngineVersionDescription' then @item[:db_engine_version_description] = @text
1532
+ when 'DBEngineVersion' then @result[:db_engine_versions] << @item
1533
+ else
1534
+ case full_tag_name
1535
+ when %r{DefaultCharacterSet/CharacterSetDescription$} then @item[:default_character_set][:description] = @text
1536
+ when %r{DefaultCharacterSet/CharacterSetName$} then @item[:default_character_set][:name] = @text
1537
+ when %r{SupportedCharacterSets/CharacterSet/CharacterSetDescription$} then @set[:description] = @text
1538
+ when %r{SupportedCharacterSets/CharacterSet/CharacterSetName$} then @set[:name] = @text
1539
+ when %r{SupportedCharacterSets/CharacterSet$} then (@item[:supported_character_sets] ||= []) << @set
1540
+ end
1541
+ end
1542
+ end
1543
+ end
1544
+
1545
+ # --------------------------------------------
1546
+ # DB Reserved Instances
1547
+ # --------------------------------------------
1548
+
1549
+ class DescribeReservedDBInstancesOfferingsParser < RightAWSParser # :nodoc:
1550
+ def reset
1551
+ @result = { :reserved_db_instances_offerings => [] }
1552
+ end
1553
+ def tagstart(name, attributes)
1554
+ case name
1555
+ when 'ReservedDBInstancesOffering' then @item = { :recurring_charges => [] }
1556
+ when 'RecurringCharge' then @recurring_charge = {}
1557
+ end
1558
+ end
1559
+ def tagend(name)
1560
+ case name
1561
+ when 'Marker' then @result[:marker] = @text
1562
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1563
+ when 'CurrencyCode' then @item[:currency_code] = @text
1564
+ when 'DBInstanceClass' then @item[:instance_class] = @text
1565
+ when 'Duration' then @item[:duration] = @text.to_i
1566
+ when 'FixedPrice' then @item[:fixed_price] = @text.to_f
1567
+ when 'UsagePrice' then @item[:usage_price] = @text.to_f
1568
+ when 'MultiAZ' then @item[:multi_az] = (@text == 'true')
1569
+ when 'ProductDescription' then @item[:product_description] = @text
1570
+ when 'OfferingType' then @item[:offering_type] = @text
1571
+ when 'ReservedDBInstancesOfferingId' then @item[:aws_id] = @text
1572
+ when 'RecurringCharge' then @item[:recurring_charges] << @recurring_charge
1573
+ when 'ReservedDBInstancesOffering' then @result[:reserved_db_instances_offerings] << @item
1574
+ else
1575
+ case full_tag_name
1576
+ when %r{RecurringCharge/RecurringChargeAmount$} then @recurring_charge[:amount] = @text
1577
+ when %r{RecurringCharge/RecurringChargeFrequency$} then @recurring_charge[:frequency] = @text
1578
+ end
1579
+ end
1580
+ end
1581
+ end
1582
+
1583
+ class DescribeReservedDBInstancesParser < RightAWSParser # :nodoc:
1584
+ def reset
1585
+ @result = { :reserved_db_instances => [] }
1586
+ end
1587
+ def tagstart(name, attributes)
1588
+ case name
1589
+ when 'ReservedDBInstance' then @item = { :recurring_charges => [] }
1590
+ when 'RecurringCharge' then @recurring_charge = {}
1591
+ end
1592
+ end
1593
+ def tagend(name)
1594
+ case name
1595
+ when 'Marker' then @result[:marker] = @text
1596
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1597
+ when 'DBInstanceClass' then @item[:instance_class] = @text
1598
+ when 'CurrencyCode' then @item[:currency_code] = @text
1599
+ when 'Duration' then @item[:duration] = @text.to_i
1600
+ when 'FixedPrice' then @item[:fixed_price] = @text.to_f
1601
+ when 'UsagePrice' then @item[:usage_price] = @text.to_f
1602
+ when 'MultiAZ' then @item[:multi_az] = (@text == 'true')
1603
+ when 'ProductDescription' then @item[:product_description] = @text
1604
+ when 'ReservedDBInstancesOfferingId' then @item[:offering_aws_id] = @text
1605
+ when 'ReservedDBInstanceId' then @item[:aws_id] = @text
1606
+ when 'State' then @item[:state] = @text
1607
+ when 'DBInstanceCount' then @item[:instance_count] = @text.to_i
1608
+ when 'StartTime' then @item[:start_time] = @text
1609
+ when 'OfferingType' then @item[:offering_type] = @text
1610
+ when 'RecurringCharge' then @item[:recurring_charges] << @recurring_charge
1611
+ when 'ReservedDBInstance' then @result[:reserved_db_instances] << @item
1612
+ else
1613
+ case full_tag_name
1614
+ when %r{RecurringCharge/RecurringChargeAmount$} then @recurring_charge[:amount] = @text
1615
+ when %r{RecurringCharge/RecurringChargeFrequency$} then @recurring_charge[:frequency] = @text
1616
+ end
1617
+ end
1618
+ end
1619
+ end
1620
+
1621
+ # --------------------------------------------
1622
+ # DB Subnet Groups
1623
+ # --------------------------------------------
1624
+
1625
+ class DescribeDBSubnetGroupsParser < RightAWSParser # :nodoc:
1626
+ def reset
1627
+ @result = { :subnet_groups => [] }
1628
+ end
1629
+ def tagstart(name, attributes)
1630
+ case name
1631
+ when 'DBSubnetGroup' then @item = { :subnets => [] }
1632
+ when 'Subnet' then @subnet = { :availability_zone => {}}
1633
+ end
1634
+ end
1635
+ def tagend(name)
1636
+ case name
1637
+ when 'Marker' then @result[:marker] = @text
1638
+ when 'MaxRecords' then @result[:max_records] = @text.to_i
1639
+ when 'DBSubnetGroupName' then @item[:name] = @text
1640
+ when 'DBSubnetGroupDescription' then @item[:description] = @text
1641
+ when 'SubnetGroupStatus' then @item[:status] = @text
1642
+ when 'Subnet' then @item[:subnets] << @subnet
1643
+ when 'VpcId' then @item[:vpc_id] = @text
1644
+ when 'DBSubnetGroup' then @result[:subnet_groups] << @item
1645
+ else
1646
+ case full_tag_name
1647
+ when %r{Subnet/SubnetIdentifier$} then @subnet[:subnet_id] = @text
1648
+ when %r{Subnet/SubnetStatus$} then @subnet[:status] = @text
1649
+ when %r{AvailabilityZone/Name$} then @subnet[:availability_zone][:name] = @text
1650
+ when %r{AvailabilityZone/ProvisionedIopsCapable$} then @subnet[:availability_zone][:provisioned_iops_capable] = @text == 'true'
1651
+ end
1652
+ end
1653
+ end
1654
+ end
1655
+
1656
+ end
1657
+ end