right_aws 2.0.0 → 2.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 (50) hide show
  1. data/History.txt +22 -1
  2. data/Manifest.txt +11 -1
  3. data/README.txt +0 -4
  4. data/Rakefile +19 -25
  5. data/lib/acf/right_acf_interface.rb +199 -135
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +4 -4
  8. data/lib/acf/right_acf_streaming_interface.rb +19 -26
  9. data/lib/acw/right_acw_interface.rb +1 -2
  10. data/lib/as/right_as_interface.rb +6 -7
  11. data/lib/awsbase/right_awsbase.rb +287 -91
  12. data/lib/awsbase/support.rb +2 -82
  13. data/lib/awsbase/version.rb +9 -0
  14. data/lib/ec2/right_ec2.rb +101 -38
  15. data/lib/ec2/right_ec2_ebs.rb +71 -58
  16. data/lib/ec2/right_ec2_images.rb +82 -42
  17. data/lib/ec2/right_ec2_instances.rb +74 -44
  18. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  19. data/lib/ec2/right_ec2_reserved_instances.rb +50 -46
  20. data/lib/ec2/right_ec2_security_groups.rb +148 -32
  21. data/lib/ec2/right_ec2_spot_instances.rb +53 -27
  22. data/lib/ec2/right_ec2_tags.rb +139 -0
  23. data/lib/ec2/right_ec2_vpc.rb +151 -139
  24. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  25. data/lib/elb/right_elb_interface.rb +93 -18
  26. data/lib/iam/right_iam_access_keys.rb +71 -0
  27. data/lib/iam/right_iam_groups.rb +195 -0
  28. data/lib/iam/right_iam_interface.rb +341 -0
  29. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  30. data/lib/iam/right_iam_users.rb +251 -0
  31. data/lib/rds/right_rds_interface.rb +513 -202
  32. data/lib/right_aws.rb +12 -12
  33. data/lib/route_53/right_route_53_interface.rb +630 -0
  34. data/lib/s3/right_s3.rb +9 -12
  35. data/lib/s3/right_s3_interface.rb +10 -11
  36. data/lib/sdb/active_sdb.rb +18 -33
  37. data/lib/sdb/right_sdb_interface.rb +36 -4
  38. data/lib/sqs/right_sqs.rb +1 -2
  39. data/lib/sqs/right_sqs_gen2.rb +0 -1
  40. data/lib/sqs/right_sqs_gen2_interface.rb +4 -5
  41. data/lib/sqs/right_sqs_interface.rb +6 -7
  42. data/right_aws.gemspec +91 -0
  43. data/test/awsbase/test_helper.rb +2 -0
  44. data/test/awsbase/test_right_awsbase.rb +12 -0
  45. data/test/s3/test_right_s3.rb +1 -1
  46. data/test/sdb/test_active_sdb.rb +1 -1
  47. data/test/sdb/test_batch_put_attributes.rb +54 -0
  48. data/test/sqs/test_right_sqs.rb +0 -6
  49. data/test/sqs/test_right_sqs_gen2.rb +1 -1
  50. metadata +109 -58
@@ -1,7 +1,3 @@
1
- # If ActiveSupport is loaded, then great - use it. But we don't
2
- # want a dependency on it, so if it's not present, define the few
3
- # extensions that we want to use...
4
- unless defined? ActiveSupport::CoreExtensions
5
1
  # These are ActiveSupport-;like extensions to do a few handy things in the gems
6
2
  # Derived from ActiveSupport, so the AS copyright notice applies:
7
3
  #
@@ -32,84 +28,8 @@ unless defined? ActiveSupport::CoreExtensions
32
28
  #
33
29
  class String #:nodoc:
34
30
 
35
- # Constantize tries to find a declared constant with the name specified
36
- # in the string. It raises a NameError when the name is not in CamelCase
37
- # or is not initialized.
38
- #
39
- # Examples
40
- # "Module".constantize #=> Module
41
- # "Class".constantize #=> Class
42
- def constantize()
43
- unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
44
- raise NameError, "#{self.inspect} is not a valid constant name!"
45
- end
46
-
47
- Object.module_eval("::#{$1}", __FILE__, __LINE__)
48
- end
49
-
50
- def camelize()
51
- self.dup.split(/_/).map{ |word| word.capitalize }.join('')
52
- end
53
-
54
- end
55
-
56
-
57
- class Object #:nodoc:
58
- # "", " ", nil, [], and {} are blank
59
- def blank?
60
- if respond_to?(:empty?) && respond_to?(:strip)
61
- empty? or strip.empty?
62
- elsif respond_to?(:empty?)
63
- empty?
64
- else
65
- !self
66
- end
31
+ def right_underscore
32
+ self.gsub(/[A-Z]/){|match| "#{$`=='' ? '' : '_'}#{match.downcase}" }
67
33
  end
68
- end
69
-
70
- class NilClass #:nodoc:
71
- def blank?
72
- true
73
- end
74
- end
75
-
76
- class FalseClass #:nodoc:
77
- def blank?
78
- true
79
- end
80
- end
81
-
82
- class TrueClass #:nodoc:
83
- def blank?
84
- false
85
- end
86
- end
87
-
88
- class Array #:nodoc:
89
- alias_method :blank?, :empty?
90
- end
91
-
92
- class Hash #:nodoc:
93
- alias_method :blank?, :empty?
94
34
 
95
- # Return a new hash with all keys converted to symbols.
96
- def symbolize_keys
97
- inject({}) do |options, (key, value)|
98
- options[key.to_sym] = value
99
- options
100
- end
101
- end
102
- end
103
-
104
- class String #:nodoc:
105
- def blank?
106
- empty? || strip.empty?
107
- end
108
- end
109
-
110
- class Numeric #:nodoc:
111
- def blank?
112
- false
113
- end
114
35
  end
115
- end
@@ -0,0 +1,9 @@
1
+ module RightAws #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 2 unless defined?(MAJOR)
4
+ MINOR = 1 unless defined?(MINOR)
5
+ TINY = 0 unless defined?(TINY)
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
8
+ end
9
+ end
@@ -68,7 +68,7 @@ module RightAws
68
68
  include RightAwsBaseInterface
69
69
 
70
70
  # Amazon EC2 API version being used
71
- API_VERSION = "2009-11-30"
71
+ API_VERSION = "2010-08-31"
72
72
  DEFAULT_HOST = "ec2.amazonaws.com"
73
73
  DEFAULT_PATH = '/'
74
74
  DEFAULT_PROTOCOL = 'https'
@@ -81,7 +81,9 @@ module RightAws
81
81
  # Amazon EC2 Instance Types : http://www.amazon.com/b?ie=UTF8&node=370375011
82
82
  # Default EC2 instance type (platform)
83
83
  DEFAULT_INSTANCE_TYPE = 'm1.small'
84
- INSTANCE_TYPES = ['m1.small','c1.medium','m1.large','m1.xlarge','c1.xlarge', 'm2.xlarge', 'm2.2xlarge', 'm2.4xlarge']
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']
85
87
 
86
88
  @@bench = AwsBenchmarkingBlock.new
87
89
  def self.bench_xml
@@ -105,7 +107,6 @@ module RightAws
105
107
  # * <tt>:region</tt>: EC2 region (North America by default)
106
108
  # * <tt>:port</tt>: EC2 service port, default: DEFAULT_PORT
107
109
  # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
108
- # * <tt>:multi_thread</tt>: true=HTTP connection per thread, false=per process
109
110
  # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
110
111
  # * <tt>:signature_version</tt>: The signature version : '0','1' or '2'(default)
111
112
  # * <tt>:cache</tt>: true/false: caching for: ec2_describe_images, describe_instances,
@@ -124,9 +125,9 @@ module RightAws
124
125
  aws_secret_access_key|| ENV['AWS_SECRET_ACCESS_KEY'],
125
126
  params)
126
127
  # Eucalyptus supports some yummy features but Amazon does not
127
- if @params[:eucalyptus]
128
- @params[:port_based_group_ingress] = true unless @params.has_key?(:port_based_group_ingress)
129
- end
128
+ #if @params[:eucalyptus]
129
+ # @params[:port_based_group_ingress] = true unless @params.has_key?(:port_based_group_ingress)
130
+ #end
130
131
  end
131
132
 
132
133
  def generate_request(action, params={}) #:nodoc:
@@ -139,26 +140,60 @@ module RightAws
139
140
  request_info_impl(:ec2_connection, @@bench, request, parser)
140
141
  end
141
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
+ request_hash = amazonize_list(remote_item_name, list)
148
+ request_hash.merge!(amazonize_list(['Filter.?.Name', 'Filter.?.Value.?'], options[:filters])) unless options[:filters].right_blank?
149
+ cache_for = (list.right_blank? && options[:filters].right_blank?) ? cache_name : nil
150
+ link = generate_request(remote_function_name, request_hash)
151
+ request_cache_or_info(cache_for, link, parser_class, @@bench, cache_for, &block)
152
+ rescue Exception
153
+ on_exception
154
+ end
155
+
142
156
  #-----------------------------------------------------------------
143
157
  # Keys
144
158
  #-----------------------------------------------------------------
145
159
 
146
- # Retrieve a list of SSH keys. Returns an array of keys or an exception. Each key is
147
- # represented as a two-element hash.
160
+ # Retrieve a list of SSH keys.
161
+ #
162
+ # Accepts a list of ssh keys and/or a set of filters as the last parameter.
163
+ #
164
+ # Filters: fingerprint, key-name
165
+ #
166
+ # Returns an array of keys or an exception. Each key is represented as a two-element hash.
148
167
  #
149
168
  # ec2.describe_key_pairs #=>
150
169
  # [{: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"},
151
170
  # {: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"},
152
171
  # ..., {...} ]
153
172
  #
154
- def describe_key_pairs(*key_pairs)
155
- key_pairs = key_pairs.flatten
156
- link = generate_request("DescribeKeyPairs", amazonize_list('KeyName', key_pairs))
157
- request_cache_or_info :describe_key_pairs, link, QEc2DescribeKeyPairParser, @@bench, key_pairs.blank?
173
+ # 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",
174
+ # "9f:57:a5:bb:4b:e8:a7:f8:3c:fe:d6:db:41:f5:7e:97:b5:b2:00:00"]})
175
+ #
176
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeKeyPairs.html
177
+ #
178
+ def describe_key_pairs(*list_and_options)
179
+ describe_resources_with_list_and_options('DescribeKeyPairs', 'KeyName', QEc2DescribeKeyPairParser, list_and_options)
180
+ end
181
+
182
+ # Import new SSH key. Returns a hash of the key's data or an exception.
183
+ #
184
+ # ec2.import_key_pair('my_awesome_key', 'C:\keys\myfavoritekeypair_public.ppk') #=>
185
+ # {:aws_key_name => "my_awesome_key",
186
+ # :aws_fingerprint => "01:02:03:f4:25:e6:97:e8:9b:02:1a:26:32:4e:58:6b:7a:8c:9f:03"}
187
+ #
188
+ def import_key_pair(name, public_key_material)
189
+ link = generate_request("ImportKeyPair",
190
+ 'KeyName' => name.to_s,
191
+ 'PublicKeyMaterial' => Base64.encode64(public_key_material.to_s))
192
+ request_info(link, QEc2ImportKeyPairParser.new(:logger => @logger))
158
193
  rescue Exception
159
194
  on_exception
160
195
  end
161
-
196
+
162
197
  # Create new SSH key. Returns a hash of the key's data or an exception.
163
198
  #
164
199
  # ec2.create_key_pair('my_awesome_key') #=>
@@ -167,7 +202,7 @@ module RightAws
167
202
  # :aws_material => "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAK...Q8MDrCbuQ=\n-----END RSA PRIVATE KEY-----"}
168
203
  #
169
204
  def create_key_pair(name)
170
- link = generate_request("CreateKeyPair",
205
+ link = generate_request("CreateKeyPair",
171
206
  'KeyName' => name.to_s)
172
207
  request_info(link, QEc2CreateKeyPairParser.new(:logger => @logger))
173
208
  rescue Exception
@@ -217,6 +252,11 @@ module RightAws
217
252
  end
218
253
 
219
254
  # List elastic IP addresses assigned to your account.
255
+ #
256
+ # Accepts a list of addresses and/or a set of filters as the last parameter.
257
+ #
258
+ # Filters: instance-id, public-ip
259
+ #
220
260
  # Returns an array of 2 keys (:instance_id and :public_ip) hashes:
221
261
  #
222
262
  # ec2.describe_addresses #=> [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.154.140"},
@@ -224,12 +264,12 @@ module RightAws
224
264
  #
225
265
  # ec2.describe_addresses('75.101.154.140') #=> [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.154.140"}]
226
266
  #
227
- def describe_addresses(*addresses)
228
- addresses = addresses.flatten
229
- link = generate_request("DescribeAddresses", amazonize_list('PublicIp', addresses))
230
- request_cache_or_info :describe_addresses, link, QEc2DescribeAddressesParser, @@bench, addresses.blank?
231
- rescue Exception
232
- on_exception
267
+ # ec2.describe_addresses(:filters => { 'public-ip' => "75.101.154.140" })
268
+ #
269
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAddresses.html
270
+ #
271
+ def describe_addresses(*list_and_options)
272
+ describe_resources_with_list_and_options('DescribeAddresses', 'PublicIp', QEc2DescribeAddressesParser, list_and_options)
233
273
  end
234
274
 
235
275
  # Disassociate the specified elastic IP address from the instance to which it is assigned.
@@ -263,6 +303,11 @@ module RightAws
263
303
  #-----------------------------------------------------------------
264
304
 
265
305
  # Describes availability zones that are currently available to the account and their states.
306
+ #
307
+ # Accepts a list of availability zones and/or a set of filters as the last parameter.
308
+ #
309
+ # Filters: message, region-name, state, zone-name
310
+ #
266
311
  # Returns an array of 2 keys (:zone_name and :zone_state) hashes:
267
312
  #
268
313
  # ec2.describe_availability_zones #=> [{:region_name=>"us-east-1",
@@ -273,12 +318,10 @@ module RightAws
273
318
  # :zone_state=>"available",
274
319
  # :zone_name=>"us-east-1c"}]
275
320
  #
276
- def describe_availability_zones(*availability_zones)
277
- availability_zones = availability_zones.flatten
278
- link = generate_request("DescribeAvailabilityZones", amazonize_list('ZoneName', availability_zones))
279
- request_cache_or_info :describe_availability_zones, link, QEc2DescribeAvailabilityZonesParser, @@bench, availability_zones.blank?
280
- rescue Exception
281
- on_exception
321
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAvailabilityZones.html
322
+ #
323
+ def describe_availability_zones(*list_and_options)
324
+ describe_resources_with_list_and_options('DescribeAvailabilityZones', 'ZoneName', QEc2DescribeAvailabilityZonesParser, list_and_options)
282
325
  end
283
326
 
284
327
  #-----------------------------------------------------------------
@@ -287,14 +330,16 @@ module RightAws
287
330
 
288
331
  # Describe regions.
289
332
  #
333
+ # Accepts a list of regions and/or a set of filters as the last parameter.
334
+ #
335
+ # Filters: endpoint, region-name
336
+ #
290
337
  # ec2.describe_regions #=> ["eu-west-1", "us-east-1"]
291
338
  #
292
- def describe_regions(*regions)
293
- regions = regions.flatten
294
- link = generate_request("DescribeRegions", amazonize_list('RegionName', regions))
295
- request_cache_or_info :describe_regions, link, QEc2DescribeRegionsParser, @@bench, regions.blank?
296
- rescue Exception
297
- on_exception
339
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeRegions.html
340
+ #
341
+ def describe_regions(*list_and_options)
342
+ describe_resources_with_list_and_options('DescribeRegions', 'RegionName', QEc2DescribeRegionsParser, list_and_options)
298
343
  end
299
344
 
300
345
  #-----------------------------------------------------------------
@@ -330,6 +375,18 @@ module RightAws
330
375
  end
331
376
  end
332
377
 
378
+ class QEc2ImportKeyPairParser < RightAWSParser #:nodoc:
379
+ def tagstart(name, attributes)
380
+ @result = {} if name == 'ImportKeyPairResponse'
381
+ end
382
+ def tagend(name)
383
+ case name
384
+ when 'keyName' then @result[:aws_key_name] = @text
385
+ when 'keyFingerprint' then @result[:aws_fingerprint] = @text
386
+ end
387
+ end
388
+ end
389
+
333
390
  #-----------------------------------------------------------------
334
391
  # PARSERS: Elastic IPs
335
392
  #-----------------------------------------------------------------
@@ -346,7 +403,7 @@ module RightAws
346
403
  end
347
404
  def tagend(name)
348
405
  case name
349
- when 'instanceId' then @address[:instance_id] = @text.blank? ? nil : @text
406
+ when 'instanceId' then @address[:instance_id] = @text.right_blank? ? nil : @text
350
407
  when 'publicIp' then @address[:public_ip] = @text
351
408
  when 'item' then @result << @address
352
409
  end
@@ -362,14 +419,20 @@ module RightAws
362
419
 
363
420
  class QEc2DescribeAvailabilityZonesParser < RightAWSParser #:nodoc:
364
421
  def tagstart(name, attributes)
365
- @zone = {} if name == 'item'
422
+ case full_tag_name
423
+ when %r{/availabilityZoneInfo/item$} then @item = {}
424
+ end
366
425
  end
367
426
  def tagend(name)
368
427
  case name
369
- when 'regionName' then @zone[:region_name] = @text
370
- when 'zoneName' then @zone[:zone_name] = @text
371
- when 'zoneState' then @zone[:zone_state] = @text
372
- when 'item' then @result << @zone
428
+ when 'regionName' then @item[:region_name] = @text
429
+ when 'zoneName' then @item[:zone_name] = @text
430
+ when 'zoneState' then @item[:zone_state] = @text
431
+ else
432
+ case full_tag_name
433
+ when %r{/messageSet/item/message$} then (@item[:messages] ||= []) << @text
434
+ when %r{/availabilityZoneInfo/item$} then @result << @item
435
+ end
373
436
  end
374
437
  end
375
438
  def reset
@@ -29,7 +29,12 @@ module RightAws
29
29
  # EBS: Volumes
30
30
  #-----------------------------------------------------------------
31
31
 
32
- # Describe all EBS volumes.
32
+ # Describe EBS volumes.
33
+ #
34
+ # Accepts a list of volumes and/or a set of filters as the last parameter.
35
+ #
36
+ # Filters: attachement.attach-time, attachment.delete-on-termination, attachement.device, attachment.instance-id,
37
+ # attachment.status, availability-zone, create-time, size, snapshot-id, status, tag-key, tag-value, tag:key, volume-id
33
38
  #
34
39
  # ec2.describe_volumes #=>
35
40
  # [{:aws_size => 94,
@@ -49,12 +54,12 @@ module RightAws
49
54
  # :aws_id => "vol-58957031",
50
55
  # :aws_created_at => Wed Jun 18 08:19:21 UTC 2008,}, ... ]
51
56
  #
52
- def describe_volumes(*volumes)
53
- volumes = volumes.flatten
54
- link = generate_request("DescribeVolumes", amazonize_list('VolumeId', volumes))
55
- request_cache_or_info :describe_volumes, link, QEc2DescribeVolumesParser, @@bench, volumes.blank?
56
- rescue Exception
57
- on_exception
57
+ # ec2.describe_volumes(:filters => { 'availability-zone' => 'us-east-1a', 'size' => '10' })
58
+ #
59
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeVolumes.html
60
+ #
61
+ def describe_volumes(*list_and_options)
62
+ describe_resources_with_list_and_options('DescribeVolumes', 'VolumeId', QEc2DescribeVolumesParser, list_and_options)
58
63
  end
59
64
 
60
65
  # Create new EBS volume based on previously created snapshot.
@@ -72,7 +77,7 @@ module RightAws
72
77
  hash = { "Size" => size.to_s,
73
78
  "AvailabilityZone" => zone.to_s }
74
79
  # Get rig of empty snapshot: e8s guys do not like it
75
- hash["SnapshotId"] = snapshot_id.to_s unless snapshot_id.blank?
80
+ hash["SnapshotId"] = snapshot_id.to_s unless snapshot_id.right_blank?
76
81
  link = generate_request("CreateVolume", hash )
77
82
  request_info(link, QEc2CreateVolumeParser.new(:logger => @logger))
78
83
  rescue Exception
@@ -123,8 +128,8 @@ module RightAws
123
128
  #
124
129
  def detach_volume(volume_id, instance_id=nil, device=nil, force=nil)
125
130
  hash = { "VolumeId" => volume_id.to_s }
126
- hash["InstanceId"] = instance_id.to_s unless instance_id.blank?
127
- hash["Device"] = device.to_s unless device.blank?
131
+ hash["InstanceId"] = instance_id.to_s unless instance_id.right_blank?
132
+ hash["Device"] = device.to_s unless device.right_blank?
128
133
  hash["Force"] = 'true' if force
129
134
  #
130
135
  link = generate_request("DetachVolume", hash)
@@ -138,9 +143,14 @@ module RightAws
138
143
  # EBS: Snapshots
139
144
  #-----------------------------------------------------------------
140
145
 
141
- # Describe all EBS snapshots.
146
+ # Describe EBS snapshots.
147
+ #
148
+ # Accepts a list of snapshots and/or a set of filters as the last parameter.
149
+ #
150
+ # Filters: description, owner-alias, owner-id, progress, snapshot-id, start-time, status, tag-key,
151
+ # tag-value, tag:key, volume-id, volume-size
142
152
  #
143
- # ec2.describe_snapshots #=>
153
+ # ec2.describe_snapshots #=>
144
154
  # [ {:aws_volume_id=>"vol-545fac3d",
145
155
  # :aws_description=>"Wikipedia XML Backups (Linux)",
146
156
  # :aws_progress=>"100%",
@@ -158,12 +168,12 @@ module RightAws
158
168
  # :aws_volume_size=>180,
159
169
  # :aws_status=>"completed"}, ...]
160
170
  #
161
- def describe_snapshots(*snapshots)
162
- snapshots = snapshots.flatten
163
- link = generate_request("DescribeSnapshots", amazonize_list('SnapshotId', snapshots))
164
- request_cache_or_info :describe_snapshots, link, QEc2DescribeSnapshotsParser, @@bench, snapshots.blank?
165
- rescue Exception
166
- on_exception
171
+ # ec2.describe_snapshots(:filters => {'tag:MyTag' => 'MyValue'))
172
+ #
173
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeSnapshots.html
174
+ #
175
+ def describe_snapshots(*list_and_options)
176
+ describe_resources_with_list_and_options('DescribeSnapshots', 'SnapshotId', QEc2DescribeSnapshotsParser, list_and_options)
167
177
  end
168
178
 
169
179
  # Create a snapshot of specified volume.
@@ -300,7 +310,7 @@ module RightAws
300
310
  #
301
311
  def modify_snapshot_attribute_create_volume_permission_add_groups(snapshot_id, *user_group)
302
312
  user_group.flatten!
303
- user_group = ['all'] if user_group.blank?
313
+ user_group = ['all'] if user_group.right_blank?
304
314
  modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'add', :user_group => user_group )
305
315
  end
306
316
 
@@ -310,7 +320,7 @@ module RightAws
310
320
  #
311
321
  def modify_snapshot_attribute_create_volume_permission_remove_groups(snapshot_id, *user_group)
312
322
  user_group.flatten!
313
- user_group = ['all'] if user_group.blank?
323
+ user_group = ['all'] if user_group.right_blank?
314
324
  modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'remove', :user_group => user_group )
315
325
  end
316
326
 
@@ -337,7 +347,7 @@ module RightAws
337
347
  when 'status' then @result[:aws_status] = @text
338
348
  when 'createTime' then @result[:aws_created_at] = @text
339
349
  when 'size' then @result[:aws_size] = @text.to_i ###
340
- when 'snapshotId' then @result[:snapshot_id] = @text.blank? ? nil : @text ###
350
+ when 'snapshotId' then @result[:snapshot_id] = @text.right_blank? ? nil : @text ###
341
351
  when 'availabilityZone' then @result[:zone] = @text ###
342
352
  end
343
353
  end
@@ -363,35 +373,30 @@ module RightAws
363
373
 
364
374
  class QEc2DescribeVolumesParser < RightAWSParser #:nodoc:
365
375
  def tagstart(name, attributes)
366
- case name
367
- when 'item'
368
- case @xmlpath
369
- when 'DescribeVolumesResponse/volumeSet' then @volume = {}
370
- end
376
+ case full_tag_name
377
+ when %r{volumeSet/item$} then @item = { :tags => {} }
378
+ when %r{/tagSet/item$} then @aws_tag = {}
371
379
  end
372
380
  end
373
381
  def tagend(name)
374
382
  case name
375
- when 'volumeId'
376
- case @xmlpath
377
- when 'DescribeVolumesResponse/volumeSet/item' then @volume[:aws_id] = @text
378
- end
379
- when 'status'
380
- case @xmlpath
381
- when 'DescribeVolumesResponse/volumeSet/item' then @volume[:aws_status] = @text
382
- when 'DescribeVolumesResponse/volumeSet/item/attachmentSet/item' then @volume[:aws_attachment_status] = @text
383
- end
384
- when 'size' then @volume[:aws_size] = @text.to_i
385
- when 'createTime' then @volume[:aws_created_at] = @text
386
- when 'instanceId' then @volume[:aws_instance_id] = @text
387
- when 'device' then @volume[:aws_device] = @text
388
- when 'attachTime' then @volume[:aws_attached_at] = @text
389
- when 'snapshotId' then @volume[:snapshot_id] = @text.blank? ? nil : @text
390
- when 'availabilityZone' then @volume[:zone] = @text
391
- when 'deleteOnTermination' then @volume[:delete_on_termination] = (@text == 'true')
392
- when 'item'
393
- case @xmlpath
394
- when 'DescribeVolumesResponse/volumeSet' then @result << @volume
383
+ when 'size' then @item[:aws_size] = @text.to_i
384
+ when 'createTime' then @item[:aws_created_at] = @text
385
+ when 'instanceId' then @item[:aws_instance_id] = @text
386
+ when 'device' then @item[:aws_device] = @text
387
+ when 'attachTime' then @item[:aws_attached_at] = @text
388
+ when 'snapshotId' then @item[:snapshot_id] = @text.right_blank? ? nil : @text
389
+ when 'availabilityZone' then @item[:zone] = @text
390
+ when 'deleteOnTermination' then @item[:delete_on_termination] = (@text == 'true')
391
+ else
392
+ case full_tag_name
393
+ when %r{/volumeSet/item/volumeId$} then @item[:aws_id] = @text
394
+ when %r{/volumeSet/item/status$} then @item[:aws_status] = @text
395
+ when %r{/attachmentSet/item/status$} then @item[:aws_attachment_status] = @text
396
+ when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
397
+ when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
398
+ when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
399
+ when %r{/volumeSet/item$} then @result << @item
395
400
  end
396
401
  end
397
402
  end
@@ -406,25 +411,33 @@ module RightAws
406
411
 
407
412
  class QEc2DescribeSnapshotsParser < RightAWSParser #:nodoc:
408
413
  def tagstart(name, attributes)
409
- case name
410
- when *@each then @snapshot = {}
414
+ case full_tag_name
415
+ when %r{CreateSnapshotResponse$},
416
+ %r{/snapshotSet/item$} then @item = { :tags => {} }
417
+ when %r{/tagSet/item$} then @aws_tag = {}
411
418
  end
412
419
  end
413
420
  def tagend(name)
414
421
  case name
415
- when 'volumeId' then @snapshot[:aws_volume_id] = @text
416
- when 'snapshotId' then @snapshot[:aws_id] = @text
417
- when 'status' then @snapshot[:aws_status] = @text
418
- when 'startTime' then @snapshot[:aws_started_at] = @text
419
- when 'progress' then @snapshot[:aws_progress] = @text
420
- when 'description' then @snapshot[:aws_description] = @text
421
- when 'ownerId' then @snapshot[:aws_owner] = @text
422
- when 'volumeSize' then @snapshot[:aws_volume_size] = @text.to_i
423
- when *@each then @result << @snapshot
422
+ when 'volumeId' then @item[:aws_volume_id] = @text
423
+ when 'snapshotId' then @item[:aws_id] = @text
424
+ when 'status' then @item[:aws_status] = @text
425
+ when 'startTime' then @item[:aws_started_at] = @text
426
+ when 'progress' then @item[:aws_progress] = @text
427
+ when 'description' then @item[:aws_description] = @text
428
+ when 'ownerId' then @item[:aws_owner] = @text
429
+ when 'volumeSize' then @item[:aws_volume_size] = @text.to_i
430
+ else
431
+ case full_tag_name
432
+ when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
433
+ when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
434
+ when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
435
+ when %r{CreateSnapshotResponse$},
436
+ %r{/snapshotSet/item$} then @result << @item
437
+ end
424
438
  end
425
439
  end
426
440
  def reset
427
- @each = ['item', 'CreateSnapshotResponse']
428
441
  @result = []
429
442
  end
430
443
  end