aboisvert_aws 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. data/History.txt +329 -0
  2. data/Manifest.txt +61 -0
  3. data/README.txt +163 -0
  4. data/Rakefile +130 -0
  5. data/lib/acf/right_acf_interface.rb +549 -0
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +248 -0
  10. data/lib/as/right_as_interface.rb +698 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +1343 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +541 -0
  16. data/lib/ec2/right_ec2_ebs.rb +481 -0
  17. data/lib/ec2/right_ec2_images.rb +444 -0
  18. data/lib/ec2/right_ec2_instances.rb +788 -0
  19. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  20. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  21. data/lib/ec2/right_ec2_reserved_instances.rb +184 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +491 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +422 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +590 -0
  26. data/lib/ec2/right_ec2_vpc2.rb +381 -0
  27. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  28. data/lib/elb/right_elb_interface.rb +573 -0
  29. data/lib/emr/right_emr_interface.rb +727 -0
  30. data/lib/iam/right_iam_access_keys.rb +71 -0
  31. data/lib/iam/right_iam_groups.rb +195 -0
  32. data/lib/iam/right_iam_interface.rb +341 -0
  33. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  34. data/lib/iam/right_iam_users.rb +251 -0
  35. data/lib/rds/right_rds_interface.rb +1384 -0
  36. data/lib/right_aws.rb +86 -0
  37. data/lib/route_53/right_route_53_interface.rb +640 -0
  38. data/lib/s3/right_s3.rb +1138 -0
  39. data/lib/s3/right_s3_interface.rb +1278 -0
  40. data/lib/sdb/active_sdb.rb +1107 -0
  41. data/lib/sdb/right_sdb_interface.rb +762 -0
  42. data/lib/sns/right_sns_interface.rb +286 -0
  43. data/lib/sqs/right_sqs.rb +387 -0
  44. data/lib/sqs/right_sqs_gen2.rb +342 -0
  45. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  46. data/lib/sqs/right_sqs_interface.rb +593 -0
  47. data/right_aws.gemspec +90 -0
  48. data/test/README.mdown +39 -0
  49. data/test/acf/test_helper.rb +2 -0
  50. data/test/acf/test_right_acf.rb +138 -0
  51. data/test/awsbase/test_helper.rb +2 -0
  52. data/test/awsbase/test_right_awsbase.rb +11 -0
  53. data/test/ec2/test_helper.rb +2 -0
  54. data/test/ec2/test_right_ec2.rb +107 -0
  55. data/test/elb/test_helper.rb +2 -0
  56. data/test/elb/test_right_elb.rb +43 -0
  57. data/test/http_connection.rb +87 -0
  58. data/test/rds/test_helper.rb +2 -0
  59. data/test/rds/test_right_rds.rb +120 -0
  60. data/test/route_53/fixtures/a_record.xml +18 -0
  61. data/test/route_53/fixtures/alias_record.xml +18 -0
  62. data/test/route_53/test_helper.rb +2 -0
  63. data/test/route_53/test_right_route_53.rb +141 -0
  64. data/test/s3/test_helper.rb +2 -0
  65. data/test/s3/test_right_s3.rb +528 -0
  66. data/test/s3/test_right_s3_stubbed.rb +97 -0
  67. data/test/sdb/test_active_sdb.rb +357 -0
  68. data/test/sdb/test_batch_put_attributes.rb +54 -0
  69. data/test/sdb/test_helper.rb +3 -0
  70. data/test/sdb/test_right_sdb.rb +253 -0
  71. data/test/sns/test_helper.rb +2 -0
  72. data/test/sns/test_right_sns.rb +153 -0
  73. data/test/sqs/test_helper.rb +2 -0
  74. data/test/sqs/test_right_sqs.rb +285 -0
  75. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  76. data/test/test_credentials.rb +37 -0
  77. data/test/ts_right_aws.rb +15 -0
  78. metadata +257 -0
@@ -0,0 +1,35 @@
1
+ # These are ActiveSupport-;like extensions to do a few handy things in the gems
2
+ # Derived from ActiveSupport, so the AS copyright notice applies:
3
+ #
4
+ #
5
+ #
6
+ # Copyright (c) 2005 David Heinemeier Hansson
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining
9
+ # a copy of this software and associated documentation files (the
10
+ # "Software"), to deal in the Software without restriction, including
11
+ # without limitation the rights to use, copy, modify, merge, publish,
12
+ # distribute, sublicense, and/or sell copies of the Software, and to
13
+ # permit persons to whom the Software is furnished to do so, subject to
14
+ # the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be
17
+ # included in all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #++
27
+ #
28
+ #
29
+ class String #:nodoc:
30
+
31
+ def right_underscore
32
+ self.gsub(/[A-Z]/){|match| "#{$`=='' ? '' : '_'}#{match.downcase}" }
33
+ end
34
+
35
+ end
@@ -0,0 +1,9 @@
1
+ module RightAws #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 3 unless defined?(MAJOR)
4
+ MINOR = 0 unless defined?(MINOR)
5
+ TINY = 0 unless defined?(TINY)
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
8
+ end
9
+ end
@@ -0,0 +1,541 @@
1
+ #
2
+ # Copyright (c) 2007-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
+ # = RightAWS::EC2 -- RightScale Amazon EC2 interface
27
+ # The RightAws::EC2 class provides a complete interface to Amazon's
28
+ # Elastic Compute Cloud service, as well as the associated EBS (Elastic Block
29
+ # Store).
30
+ # For explanations of the semantics
31
+ # of each call, please refer to Amazon's documentation at
32
+ # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=87
33
+ #
34
+ # Examples:
35
+ #
36
+ # Create an EC2 interface handle:
37
+ #
38
+ # @ec2 = RightAws::Ec2.new(aws_access_key_id,
39
+ # aws_secret_access_key)
40
+ # Create a new SSH key pair:
41
+ # @key = 'right_ec2_awesome_test_key'
42
+ # new_key = @ec2.create_key_pair(@key)
43
+ # keys = @ec2.describe_key_pairs
44
+ #
45
+ # Create a security group:
46
+ # @group = 'right_ec2_awesome_test_security_group'
47
+ # @ec2.create_security_group(@group,'My awesome test group')
48
+ # group = @ec2.describe_security_groups([@group])[0]
49
+ #
50
+ # Configure a security group:
51
+ # @ec2.authorize_security_group_named_ingress(@group, account_number, 'default')
52
+ # @ec2.authorize_security_group_IP_ingress(@group, 80,80,'udp','192.168.1.0/8')
53
+ #
54
+ # Describe the available images:
55
+ # images = @ec2.describe_images
56
+ #
57
+ # Launch an instance:
58
+ # ec2.run_instances('ami-9a9e7bf3', 1, 1, ['default'], @key, 'SomeImportantUserData', 'public')
59
+ #
60
+ #
61
+ # Describe running instances:
62
+ # @ec2.describe_instances
63
+ #
64
+ # Error handling: all operations raise an RightAws::AwsError in case
65
+ # of problems. Note that transient errors are automatically retried.
66
+
67
+ class Ec2 < RightAwsBase
68
+ include RightAwsBaseInterface
69
+
70
+ # Amazon EC2 API version being used
71
+ API_VERSION = "2011-02-28"
72
+ DEFAULT_HOST = "ec2.amazonaws.com"
73
+ DEFAULT_PATH = '/'
74
+ DEFAULT_PROTOCOL = 'https'
75
+ DEFAULT_PORT = 443
76
+
77
+ # Default addressing type (public=NAT, direct=no-NAT) used when launching instances.
78
+ DEFAULT_ADDRESSING_TYPE = 'public'
79
+ DNS_ADDRESSING_SET = ['public','direct']
80
+
81
+ # Amazon EC2 Instance Types : http://www.amazon.com/b?ie=UTF8&node=370375011
82
+ # Default EC2 instance type (platform)
83
+ DEFAULT_INSTANCE_TYPE = 'm1.small'
84
+ INSTANCE_TYPES = ['t1.micro','m1.small','c1.medium','m1.large','m1.xlarge',
85
+ 'c1.xlarge', 'm2.xlarge', 'm2.2xlarge', 'm2.4xlarge',
86
+ 'cc1.4xlarge', 'cg1.4xlarge']
87
+
88
+ @@bench = AwsBenchmarkingBlock.new
89
+ def self.bench_xml
90
+ @@bench.xml
91
+ end
92
+ def self.bench_ec2
93
+ @@bench.service
94
+ end
95
+
96
+ # Current API version (sometimes we have to check it outside the GEM).
97
+ @@api = ENV['EC2_API_VERSION'] || API_VERSION
98
+ def self.api
99
+ @@api
100
+ end
101
+
102
+ # Create a new handle to an EC2 account. All handles share the same per process or per thread
103
+ # HTTP connection to Amazon EC2. Each handle is for a specific account. The params have the
104
+ # following options:
105
+ # * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol and :region). Example: 'https://eu-west-1.ec2.amazonaws.com/'
106
+ # * <tt>:server</tt>: EC2 service host, default: DEFAULT_HOST
107
+ # * <tt>:region</tt>: EC2 region (North America by default)
108
+ # * <tt>:port</tt>: EC2 service port, default: DEFAULT_PORT
109
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
110
+ # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
111
+ # * <tt>:signature_version</tt>: The signature version : '0','1' or '2'(default)
112
+ # * <tt>:cache</tt>: true/false: caching for: ec2_describe_images, describe_instances,
113
+ # describe_images_by_owner, describe_images_by_executable_by, describe_availability_zones,
114
+ # describe_security_groups, describe_key_pairs, describe_addresses,
115
+ # describe_volumes, describe_snapshots methods, default: false.
116
+ #
117
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
118
+ init({ :name => 'EC2',
119
+ :default_host => ENV['EC2_URL'] ? URI.parse(ENV['EC2_URL']).host : DEFAULT_HOST,
120
+ :default_port => ENV['EC2_URL'] ? URI.parse(ENV['EC2_URL']).port : DEFAULT_PORT,
121
+ :default_service => ENV['EC2_URL'] ? URI.parse(ENV['EC2_URL']).path : DEFAULT_PATH,
122
+ :default_protocol => ENV['EC2_URL'] ? URI.parse(ENV['EC2_URL']).scheme : DEFAULT_PROTOCOL,
123
+ :default_api_version => @@api },
124
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'] ,
125
+ aws_secret_access_key|| ENV['AWS_SECRET_ACCESS_KEY'],
126
+ params)
127
+ # Eucalyptus supports some yummy features but Amazon does not
128
+ #if @params[:eucalyptus]
129
+ # @params[:port_based_group_ingress] = true unless @params.has_key?(:port_based_group_ingress)
130
+ #end
131
+ end
132
+
133
+ def generate_request(action, params={}, custom_options={}) #:nodoc:
134
+ generate_request_impl(:get, action, params, custom_options)
135
+ end
136
+
137
+ # Sends request to Amazon and parses the response
138
+ # Raises AwsError if any banana happened
139
+ def request_info(request, parser) #:nodoc:
140
+ request_info_impl(:ec2_connection, @@bench, request, parser)
141
+ end
142
+
143
+ def describe_resources_with_list_and_options(remote_function_name, remote_item_name, parser_class, list_and_options, &block) # :nodoc:
144
+ # 'RemoteFunctionName' -> :remote_funtion_name
145
+ cache_name = remote_function_name.right_underscore.to_sym
146
+ list, options = AwsUtils::split_items_and_params(list_and_options)
147
+ # Resource IDs to fetch
148
+ request_hash = amazonize_list(remote_item_name, list)
149
+ # Other custom options
150
+ options.each do |key, values|
151
+ next if values.right_blank?
152
+ case key
153
+ when :filters then
154
+ request_hash.merge!(amazonize_list(['Filter.?.Name', 'Filter.?.Value.?'], values))
155
+ else
156
+ request_hash.merge!(amazonize_list(key.to_s.right_camelize, values))
157
+ end
158
+ end
159
+ cache_for = (list.right_blank? && options.right_blank?) ? cache_name : nil
160
+ link = generate_request(remote_function_name, request_hash)
161
+ request_cache_or_info(cache_for, link, parser_class, @@bench, cache_for, &block)
162
+ rescue Exception
163
+ on_exception
164
+ end
165
+
166
+ #-----------------------------------------------------------------
167
+ # Keys
168
+ #-----------------------------------------------------------------
169
+
170
+ # Retrieve a list of SSH keys.
171
+ #
172
+ # Accepts a list of ssh keys and/or a set of filters as the last parameter.
173
+ #
174
+ # Filters: fingerprint, key-name
175
+ #
176
+ # Returns an array of keys or an exception. Each key is represented as a two-element hash.
177
+ #
178
+ # ec2.describe_key_pairs #=>
179
+ # [{:aws_fingerprint=> "01:02:03:f4:25:e6:97:e8:9b:02:1a:26:32:4e:58:6b:7a:8c:9f:03", :aws_key_name=>"key-1"},
180
+ # {:aws_fingerprint=> "1e:29:30:47:58:6d:7b:8c:9f:08:11:20:3c:44:52:69:74:80:97:08", :aws_key_name=>"key-2"},
181
+ # ..., {...} ]
182
+ #
183
+ # ec2.describe_key_pairs(:filters => {'fingerprint' => ["53:0b:73:c9:c8:18:98:6e:bc:98:9e:51:97:04:74:4b:07:f9:00:00",
184
+ # "9f:57:a5:bb:4b:e8:a7:f8:3c:fe:d6:db:41:f5:7e:97:b5:b2:00:00"]})
185
+ #
186
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeKeyPairs.html
187
+ #
188
+ def describe_key_pairs(*list_and_options)
189
+ describe_resources_with_list_and_options('DescribeKeyPairs', 'KeyName', QEc2DescribeKeyPairParser, list_and_options)
190
+ end
191
+
192
+ # Import new SSH key. Returns a hash of the key's data or an exception.
193
+ #
194
+ # ec2.import_key_pair('my_awesome_key', 'C:\keys\myfavoritekeypair_public.ppk') #=>
195
+ # {:aws_key_name => "my_awesome_key",
196
+ # :aws_fingerprint => "01:02:03:f4:25:e6:97:e8:9b:02:1a:26:32:4e:58:6b:7a:8c:9f:03"}
197
+ #
198
+ def import_key_pair(name, public_key_material)
199
+ link = generate_request("ImportKeyPair",
200
+ 'KeyName' => name.to_s,
201
+ 'PublicKeyMaterial' => Base64.encode64(public_key_material.to_s))
202
+ request_info(link, QEc2ImportKeyPairParser.new(:logger => @logger))
203
+ rescue Exception
204
+ on_exception
205
+ end
206
+
207
+ # Create new SSH key. Returns a hash of the key's data or an exception.
208
+ #
209
+ # ec2.create_key_pair('my_awesome_key') #=>
210
+ # {:aws_key_name => "my_awesome_key",
211
+ # :aws_fingerprint => "01:02:03:f4:25:e6:97:e8:9b:02:1a:26:32:4e:58:6b:7a:8c:9f:03",
212
+ # :aws_material => "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAK...Q8MDrCbuQ=\n-----END RSA PRIVATE KEY-----"}
213
+ #
214
+ def create_key_pair(name)
215
+ link = generate_request("CreateKeyPair",
216
+ 'KeyName' => name.to_s)
217
+ request_info(link, QEc2CreateKeyPairParser.new(:logger => @logger))
218
+ rescue Exception
219
+ on_exception
220
+ end
221
+
222
+ # Delete a key pair. Returns +true+ or an exception.
223
+ #
224
+ # ec2.delete_key_pair('my_awesome_key') #=> true
225
+ #
226
+ def delete_key_pair(name)
227
+ link = generate_request("DeleteKeyPair",
228
+ 'KeyName' => name.to_s)
229
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
230
+ rescue Exception
231
+ on_exception
232
+ end
233
+
234
+ #-----------------------------------------------------------------
235
+ # Elastic IPs
236
+ #-----------------------------------------------------------------
237
+
238
+ # Acquire a new elastic IP address for use with your account.
239
+ # Options: :domain.
240
+ # Returns allocated IP address or or an exception.
241
+ #
242
+ # ec2.allocate_address #=>
243
+ # { :public_ip => "50.19.214.224",
244
+ # :domain => "standard"}
245
+ #
246
+ # ec2.allocate_address(:domain => 'vpc') #=>
247
+ # { :allocation_id => "eipalloc-c6abfeaf",
248
+ # :domain => "vpc",
249
+ # :public_ip => "184.72.112.39"}
250
+ #
251
+ def allocate_address(options={})
252
+ request_hash = {}
253
+ request_hash['Domain'] = options[:domain] unless options[:domain].right_blank?
254
+ link = generate_request("AllocateAddress", request_hash)
255
+ request_info(link, QEc2AllocateAddressParser.new(:logger => @logger))
256
+ rescue Exception
257
+ on_exception
258
+ end
259
+
260
+ # Associate an elastic IP address with an instance.
261
+ # Options: :public_ip, :allocation_id.
262
+ # Returns a hash of data or an exception.
263
+ #
264
+ # ec2.associate_address('i-d630cbbf', :public_ip => '75.101.154.140') #=>
265
+ # { :return => true }
266
+ #
267
+ # ec2.associate_address(inst, :allocation_id => "eipalloc-c6abfeaf") #=>
268
+ # { :return => true,
269
+ # :association_id => 'eipassoc-fc5ca095'}
270
+ #
271
+ def associate_address(instance_id, options={})
272
+ request_hash = { "InstanceId" => instance_id.to_s }
273
+ request_hash['PublicIp'] = options[:public_ip] unless options[:public_ip].right_blank?
274
+ request_hash['AllocationId'] = options[:allocation_id] unless options[:allocation_id].right_blank?
275
+ link = generate_request("AssociateAddress", request_hash)
276
+ request_info(link, QEc2AssociateAddressParser.new(:logger => @logger))
277
+ rescue Exception
278
+ on_exception
279
+ end
280
+
281
+ # List elastic IPs by public addresses.
282
+ #
283
+ # Accepts a list of addresses and/or a set of filters as the last parameter.
284
+ #
285
+ # Filters: instance-id, public-ip
286
+ #
287
+ # Returns an array of 2 keys (:instance_id and :public_ip) hashes:
288
+ #
289
+ # ec2.describe_addresses #=> [{:instance_id=>"i-75ebd41b", :domain=>"standard", :public_ip=>"50.17.211.96"},
290
+ # :domain=>"vpc", :public_ip=>"184.72.112.39", :allocation_id=>"eipalloc-c6abfeaf"}]
291
+ #
292
+ # ec2.describe_addresses('75.101.154.140') #=> [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.154.140", :domain=>"standard"}]
293
+ #
294
+ # ec2.describe_addresses(:filters => { 'public-ip' => "75.101.154.140" })
295
+ #
296
+ # P.S. http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAddresses.html
297
+ #
298
+ def describe_addresses(*list_and_options)
299
+ describe_resources_with_list_and_options('DescribeAddresses', 'PublicIp', QEc2DescribeAddressesParser, list_and_options)
300
+ end
301
+
302
+
303
+ # List elastic IPs by allocation ids.
304
+ #
305
+ # Accepts a list of allocations and/or a set of filters as the last parameter.
306
+ #
307
+ # describe_addresses_by_allocation_ids("eipalloc-c6abfeaf") #=>
308
+ # [{:domain=>"vpc",
309
+ # :public_ip=>"184.72.112.39",
310
+ # :allocation_id=>"eipalloc-c6abfeaf"}]
311
+ #
312
+ # P.S. http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAddresses.html
313
+ #
314
+ def describe_addresses_by_allocation_ids(*list_and_options)
315
+ describe_resources_with_list_and_options('DescribeAddresses', 'AllocationId', QEc2DescribeAddressesParser, list_and_options)
316
+ end
317
+
318
+ # Disassociate the specified elastic IP address from the instance to which it is assigned.
319
+ # Options: :public_ip, :association_id.
320
+ # Returns +true+ or an exception.
321
+ #
322
+ # ec2.disassociate_address(:public_ip => '75.101.154.140') #=> true
323
+ #
324
+ def disassociate_address(options = {})
325
+ request_hash = {}
326
+ request_hash['PublicIp'] = options[:public_ip] unless options[:public_ip].right_blank?
327
+ request_hash['AssociationId'] = options[:association_id] unless options[:association_id].right_blank?
328
+ link = generate_request("DisassociateAddress", request_hash)
329
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
330
+ rescue Exception
331
+ on_exception
332
+ end
333
+
334
+ # Release an elastic IP address associated with your account.
335
+ # Options: :public_ip, :allocation_id.
336
+ # Returns +true+ or an exception.
337
+ #
338
+ # ec2.release_address(:public_ip => '75.101.154.140') #=> true
339
+ #
340
+ def release_address(options = {})
341
+ request_hash = {}
342
+ request_hash['PublicIp'] = options[:public_ip] unless options[:public_ip].right_blank?
343
+ request_hash['AllocationId'] = options[:allocation_id] unless options[:allocation_id].right_blank?
344
+ link = generate_request("ReleaseAddress", request_hash)
345
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
346
+ rescue Exception
347
+ on_exception
348
+ end
349
+
350
+ #-----------------------------------------------------------------
351
+ # Availability zones
352
+ #-----------------------------------------------------------------
353
+
354
+ # Describes availability zones that are currently available to the account and their states.
355
+ #
356
+ # Accepts a list of availability zones and/or a set of filters as the last parameter.
357
+ #
358
+ # Filters: message, region-name, state, zone-name
359
+ #
360
+ # Returns an array of 2 keys (:zone_name and :zone_state) hashes:
361
+ #
362
+ # ec2.describe_availability_zones #=> [{:region_name=>"us-east-1",
363
+ # :zone_name=>"us-east-1a",
364
+ # :zone_state=>"available"}, ... ]
365
+ #
366
+ # ec2.describe_availability_zones('us-east-1c') #=> [{:region_name=>"us-east-1",
367
+ # :zone_state=>"available",
368
+ # :zone_name=>"us-east-1c"}]
369
+ #
370
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAvailabilityZones.html
371
+ #
372
+ def describe_availability_zones(*list_and_options)
373
+ describe_resources_with_list_and_options('DescribeAvailabilityZones', 'ZoneName', QEc2DescribeAvailabilityZonesParser, list_and_options)
374
+ end
375
+
376
+ #-----------------------------------------------------------------
377
+ # Regions
378
+ #-----------------------------------------------------------------
379
+
380
+ # Describe regions.
381
+ #
382
+ # Accepts a list of regions and/or a set of filters as the last parameter.
383
+ #
384
+ # Filters: endpoint, region-name
385
+ #
386
+ # ec2.describe_regions #=>
387
+ # [{:region_endpoint=>"ec2.eu-west-1.amazonaws.com", :region_name=>"eu-west-1"},
388
+ # {:region_endpoint=>"ec2.us-east-1.amazonaws.com", :region_name=>"us-east-1"},
389
+ # {:region_endpoint=>"ec2.ap-northeast-1.amazonaws.com", :region_name=>"ap-northeast-1"},
390
+ # {:region_endpoint=>"ec2.us-west-1.amazonaws.com", :region_name=>"us-west-1"},
391
+ # {:region_endpoint=>"ec2.ap-southeast-1.amazonaws.com", :region_name=>"ap-southeast-1"}]
392
+ #
393
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeRegions.html
394
+ #
395
+ def describe_regions(*list_and_options)
396
+ describe_resources_with_list_and_options('DescribeRegions', 'RegionName', QEc2DescribeRegionsParser, list_and_options)
397
+ end
398
+
399
+ #-----------------------------------------------------------------
400
+ # PARSERS: Key Pair
401
+ #-----------------------------------------------------------------
402
+
403
+ class QEc2DescribeKeyPairParser < RightAWSParser #:nodoc:
404
+ def tagstart(name, attributes)
405
+ @item = {} if name == 'item'
406
+ end
407
+ def tagend(name)
408
+ case name
409
+ when 'keyName' then @item[:aws_key_name] = @text
410
+ when 'keyFingerprint' then @item[:aws_fingerprint] = @text
411
+ when 'item' then @result << @item
412
+ end
413
+ end
414
+ def reset
415
+ @result = [];
416
+ end
417
+ end
418
+
419
+ class QEc2CreateKeyPairParser < RightAWSParser #:nodoc:
420
+ def tagstart(name, attributes)
421
+ @result = {} if name == 'CreateKeyPairResponse'
422
+ end
423
+ def tagend(name)
424
+ case name
425
+ when 'keyName' then @result[:aws_key_name] = @text
426
+ when 'keyFingerprint' then @result[:aws_fingerprint] = @text
427
+ when 'keyMaterial' then @result[:aws_material] = @text
428
+ end
429
+ end
430
+ end
431
+
432
+ class QEc2ImportKeyPairParser < RightAWSParser #:nodoc:
433
+ def tagstart(name, attributes)
434
+ @result = {} if name == 'ImportKeyPairResponse'
435
+ end
436
+ def tagend(name)
437
+ case name
438
+ when 'keyName' then @result[:aws_key_name] = @text
439
+ when 'keyFingerprint' then @result[:aws_fingerprint] = @text
440
+ end
441
+ end
442
+ end
443
+
444
+ #-----------------------------------------------------------------
445
+ # PARSERS: Elastic IPs
446
+ #-----------------------------------------------------------------
447
+
448
+ class QEc2AllocateAddressParser < RightAWSParser #:nodoc:
449
+ def tagend(name)
450
+ case name
451
+ when 'publicIp' then @result[:public_ip] = @text
452
+ when 'allocationId' then @result[:allocation_id] = @text
453
+ when 'domain' then @result[:domain] = @text
454
+ end
455
+ end
456
+ def reset
457
+ @result = {}
458
+ end
459
+ end
460
+
461
+ class QEc2AssociateAddressParser < RightAWSParser #:nodoc:
462
+ def tagend(name)
463
+ case name
464
+ when 'return' then @result[:return] = @text == 'true'
465
+ when 'associationId' then @result[:association_id] = @text
466
+ end
467
+ end
468
+ def reset
469
+ @result = {}
470
+ end
471
+ end
472
+
473
+ class QEc2DescribeAddressesParser < RightAWSParser #:nodoc:
474
+ def tagstart(name, attributes)
475
+ @item = {} if name == 'item'
476
+ end
477
+ def tagend(name)
478
+ case name
479
+ when 'instanceId' then (@item[:instance_id] = @text unless @text.right_blank?)
480
+ when 'publicIp' then @item[:public_ip] = @text
481
+ when 'allocationId' then @item[:allocation_id] = @text
482
+ when 'associationId' then @item[:association_id] = @text
483
+ when 'domain' then @item[:domain] = @text
484
+ when 'item' then @result << @item
485
+ end
486
+ end
487
+ def reset
488
+ @result = []
489
+ end
490
+ end
491
+
492
+ #-----------------------------------------------------------------
493
+ # PARSERS: AvailabilityZones
494
+ #-----------------------------------------------------------------
495
+
496
+ class QEc2DescribeAvailabilityZonesParser < RightAWSParser #:nodoc:
497
+ def tagstart(name, attributes)
498
+ case full_tag_name
499
+ when %r{/availabilityZoneInfo/item$} then @item = {}
500
+ end
501
+ end
502
+ def tagend(name)
503
+ case name
504
+ when 'regionName' then @item[:region_name] = @text
505
+ when 'zoneName' then @item[:zone_name] = @text
506
+ when 'zoneState' then @item[:zone_state] = @text
507
+ else
508
+ case full_tag_name
509
+ when %r{/messageSet/item/message$} then (@item[:messages] ||= []) << @text
510
+ when %r{/availabilityZoneInfo/item$} then @result << @item
511
+ end
512
+ end
513
+ end
514
+ def reset
515
+ @result = []
516
+ end
517
+ end
518
+
519
+ #-----------------------------------------------------------------
520
+ # PARSERS: Regions
521
+ #-----------------------------------------------------------------
522
+
523
+ class QEc2DescribeRegionsParser < RightAWSParser #:nodoc:
524
+ def tagstart(name, attributes)
525
+ @item = {} if name == 'item'
526
+ end
527
+ def tagend(name)
528
+ case name
529
+ when 'regionName' then @item[:region_name] = @text
530
+ when 'regionEndpoint' then @item[:region_endpoint] = @text
531
+ when 'item' then @result << @item
532
+ end
533
+ end
534
+ def reset
535
+ @result = []
536
+ end
537
+ end
538
+
539
+ end
540
+
541
+ end