right_aws 2.1.0 → 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.
@@ -1,7 +1,7 @@
1
1
  module RightAws #:nodoc:
2
2
  module VERSION #:nodoc:
3
- MAJOR = 2 unless defined?(MAJOR)
4
- MINOR = 1 unless defined?(MINOR)
3
+ MAJOR = 3 unless defined?(MAJOR)
4
+ MINOR = 0 unless defined?(MINOR)
5
5
  TINY = 0 unless defined?(TINY)
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
@@ -68,7 +68,7 @@ module RightAws
68
68
  include RightAwsBaseInterface
69
69
 
70
70
  # Amazon EC2 API version being used
71
- API_VERSION = "2010-08-31"
71
+ API_VERSION = "2011-02-28"
72
72
  DEFAULT_HOST = "ec2.amazonaws.com"
73
73
  DEFAULT_PATH = '/'
74
74
  DEFAULT_PROTOCOL = 'https'
@@ -130,8 +130,8 @@ module RightAws
130
130
  #end
131
131
  end
132
132
 
133
- def generate_request(action, params={}) #:nodoc:
134
- generate_request_impl(:get, action, params )
133
+ def generate_request(action, params={}, custom_options={}) #:nodoc:
134
+ generate_request_impl(:get, action, params, custom_options)
135
135
  end
136
136
 
137
137
  # Sends request to Amazon and parses the response
@@ -144,9 +144,19 @@ module RightAws
144
144
  # 'RemoteFunctionName' -> :remote_funtion_name
145
145
  cache_name = remote_function_name.right_underscore.to_sym
146
146
  list, options = AwsUtils::split_items_and_params(list_and_options)
147
+ # Resource IDs to fetch
147
148
  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
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
150
160
  link = generate_request(remote_function_name, request_hash)
151
161
  request_cache_or_info(cache_for, link, parser_class, @@bench, cache_for, &block)
152
162
  rescue Exception
@@ -226,32 +236,49 @@ module RightAws
226
236
  #-----------------------------------------------------------------
227
237
 
228
238
  # Acquire a new elastic IP address for use with your account.
229
- # Returns allocated IP address or an exception.
239
+ # Options: :domain.
240
+ # Returns allocated IP address or or an exception.
230
241
  #
231
- # ec2.allocate_address #=> '75.101.154.140'
242
+ # ec2.allocate_address #=>
243
+ # { :public_ip => "50.19.214.224",
244
+ # :domain => "standard"}
232
245
  #
233
- def allocate_address
234
- link = generate_request("AllocateAddress")
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)
235
255
  request_info(link, QEc2AllocateAddressParser.new(:logger => @logger))
236
256
  rescue Exception
237
257
  on_exception
238
258
  end
239
259
 
240
260
  # Associate an elastic IP address with an instance.
241
- # Returns +true+ or an exception.
261
+ # Options: :public_ip, :allocation_id.
262
+ # Returns a hash of data or an exception.
242
263
  #
243
- # ec2.associate_address('i-d630cbbf', '75.101.154.140') #=> true
264
+ # ec2.associate_address('i-d630cbbf', :public_ip => '75.101.154.140') #=>
265
+ # { :return => true }
244
266
  #
245
- def associate_address(instance_id, public_ip)
246
- link = generate_request("AssociateAddress",
247
- "InstanceId" => instance_id.to_s,
248
- "PublicIp" => public_ip.to_s)
249
- request_info(link, RightBoolResponseParser.new(:logger => @logger))
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))
250
277
  rescue Exception
251
278
  on_exception
252
279
  end
253
280
 
254
- # List elastic IP addresses assigned to your account.
281
+ # List elastic IPs by public addresses.
255
282
  #
256
283
  # Accepts a list of addresses and/or a set of filters as the last parameter.
257
284
  #
@@ -259,40 +286,62 @@ module RightAws
259
286
  #
260
287
  # Returns an array of 2 keys (:instance_id and :public_ip) hashes:
261
288
  #
262
- # ec2.describe_addresses #=> [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.154.140"},
263
- # {:instance_id=>nil, :public_ip=>"75.101.154.141"}]
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"}]
264
291
  #
265
- # ec2.describe_addresses('75.101.154.140') #=> [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.154.140"}]
292
+ # ec2.describe_addresses('75.101.154.140') #=> [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.154.140", :domain=>"standard"}]
266
293
  #
267
294
  # ec2.describe_addresses(:filters => { 'public-ip' => "75.101.154.140" })
268
295
  #
269
- # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAddresses.html
296
+ # P.S. http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeAddresses.html
270
297
  #
271
298
  def describe_addresses(*list_and_options)
272
299
  describe_resources_with_list_and_options('DescribeAddresses', 'PublicIp', QEc2DescribeAddressesParser, list_and_options)
273
300
  end
274
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
+
275
318
  # Disassociate the specified elastic IP address from the instance to which it is assigned.
319
+ # Options: :public_ip, :association_id.
276
320
  # Returns +true+ or an exception.
277
321
  #
278
- # ec2.disassociate_address('75.101.154.140') #=> true
322
+ # ec2.disassociate_address(:public_ip => '75.101.154.140') #=> true
279
323
  #
280
- def disassociate_address(public_ip)
281
- link = generate_request("DisassociateAddress",
282
- "PublicIp" => public_ip.to_s)
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)
283
329
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
284
330
  rescue Exception
285
331
  on_exception
286
332
  end
287
333
 
288
334
  # Release an elastic IP address associated with your account.
335
+ # Options: :public_ip, :allocation_id.
289
336
  # Returns +true+ or an exception.
290
337
  #
291
- # ec2.release_address('75.101.154.140') #=> true
338
+ # ec2.release_address(:public_ip => '75.101.154.140') #=> true
292
339
  #
293
- def release_address(public_ip)
294
- link = generate_request("ReleaseAddress",
295
- "PublicIp" => public_ip.to_s)
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)
296
345
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
297
346
  rescue Exception
298
347
  on_exception
@@ -334,7 +383,12 @@ module RightAws
334
383
  #
335
384
  # Filters: endpoint, region-name
336
385
  #
337
- # ec2.describe_regions #=> ["eu-west-1", "us-east-1"]
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"}]
338
392
  #
339
393
  # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeRegions.html
340
394
  #
@@ -393,19 +447,41 @@ module RightAws
393
447
 
394
448
  class QEc2AllocateAddressParser < RightAWSParser #:nodoc:
395
449
  def tagend(name)
396
- @result = @text if name == 'publicIp'
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 = {}
397
470
  end
398
471
  end
399
-
472
+
400
473
  class QEc2DescribeAddressesParser < RightAWSParser #:nodoc:
401
474
  def tagstart(name, attributes)
402
- @address = {} if name == 'item'
475
+ @item = {} if name == 'item'
403
476
  end
404
477
  def tagend(name)
405
478
  case name
406
- when 'instanceId' then @address[:instance_id] = @text.right_blank? ? nil : @text
407
- when 'publicIp' then @address[:public_ip] = @text
408
- when 'item' then @result << @address
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
409
485
  end
410
486
  end
411
487
  def reset
@@ -445,8 +521,15 @@ module RightAws
445
521
  #-----------------------------------------------------------------
446
522
 
447
523
  class QEc2DescribeRegionsParser < RightAWSParser #:nodoc:
524
+ def tagstart(name, attributes)
525
+ @item = {} if name == 'item'
526
+ end
448
527
  def tagend(name)
449
- @result << @text if name == 'regionName'
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
450
533
  end
451
534
  def reset
452
535
  @result = []
@@ -145,30 +145,41 @@ module RightAws
145
145
 
146
146
  # Describe EBS snapshots.
147
147
  #
148
- # Accepts a list of snapshots and/or a set of filters as the last parameter.
148
+ # Accepts a list of snapshots and/or options: :restorable_by, :owner and :filters
149
+ #
150
+ # Options: :restorable_by => Array or String, :owner => Array or String, :filters => Hash
149
151
  #
150
152
  # Filters: description, owner-alias, owner-id, progress, snapshot-id, start-time, status, tag-key,
151
153
  # tag-value, tag:key, volume-id, volume-size
152
154
  #
153
155
  # ec2.describe_snapshots #=>
154
- # [ {:aws_volume_id=>"vol-545fac3d",
155
- # :aws_description=>"Wikipedia XML Backups (Linux)",
156
+ # [{:aws_volume_size=>2,
157
+ # :tags=>{},
158
+ # :aws_id=>"snap-d010f6b9",
159
+ # :owner_alias=>"amazon",
156
160
  # :aws_progress=>"100%",
157
- # :aws_started_at=>"2009-09-28T23:49:50.000Z",
158
- # :aws_owner=>"amazon",
159
- # :aws_id=>"snap-8041f2e9",
160
- # :aws_volume_size=>500,
161
- # :aws_status=>"completed"},
162
- # {:aws_volume_id=>"vol-185fac71",
163
- # :aws_description=>"Sloan Digital Sky Survey DR6 Subset (Linux)",
161
+ # :aws_status=>"completed",
162
+ # :aws_description=>
163
+ # "Windows 2003 R2 Installation Media [Deprecated] - Enterprise Edition 64-bit",
164
+ # :aws_owner=>"711940113766",
165
+ # :aws_volume_id=>"vol-351efb5c",
166
+ # :aws_started_at=>"2008-10-20T18:23:59.000Z"},
167
+ # {:aws_volume_size=>2,
168
+ # :tags=>{},
169
+ # :aws_id=>"snap-a310f6ca",
170
+ # :owner_alias=>"amazon",
164
171
  # :aws_progress=>"100%",
165
- # :aws_started_at=>"2009-09-28T23:56:10.000Z",
166
- # :aws_owner=>"amazon",
167
- # :aws_id=>"snap-3740f35e",
168
- # :aws_volume_size=>180,
169
- # :aws_status=>"completed"}, ...]
170
- #
171
- # ec2.describe_snapshots(:filters => {'tag:MyTag' => 'MyValue'))
172
+ # :aws_status=>"completed",
173
+ # :aws_description=>"Windows 2003 R2 Installation Media 64-bit",
174
+ # :aws_owner=>"711940113766",
175
+ # :aws_volume_id=>"vol-001efb69",
176
+ # :aws_started_at=>"2008-10-20T18:25:53.000Z"}, ... ]
177
+ #
178
+ # ec2.describe_snapshots("snap-e676e28a", "snap-e176e281")
179
+ #
180
+ # ec2.describe_snapshots(:restorable_by => ['123456781234'],
181
+ # :owner => ['self', 'amazon'],
182
+ # :filters => {'tag:MyTag' => 'MyValue'})
172
183
  #
173
184
  # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeSnapshots.html
174
185
  #
@@ -176,6 +187,10 @@ module RightAws
176
187
  describe_resources_with_list_and_options('DescribeSnapshots', 'SnapshotId', QEc2DescribeSnapshotsParser, list_and_options)
177
188
  end
178
189
 
190
+ def describe_snapshots_by_restorable_by(*list_and_options)
191
+ describe_resources_with_list_and_options('DescribeSnapshots', 'RestorableBy', QEc2DescribeSnapshotsParser, list_and_options)
192
+ end
193
+
179
194
  # Create a snapshot of specified volume.
180
195
  #
181
196
  # ec2.create_snapshot('vol-898a6fe0', 'KD: WooHoo!!') #=>
@@ -270,18 +285,18 @@ module RightAws
270
285
 
271
286
  # Modify snapshot attribute.
272
287
  #
273
- # attribute : currently, only 'createVolumePermission' is supported.
274
- # operation_type : currently, only 'add' & 'remove' are supported.
275
- # vars:
276
- # :user_group : currently, only 'all' is supported.
277
- # :user_id : an array of user ids
278
- #
279
- def modify_snapshot_attribute(snapshot_id, attribute='createVolumePermission', operation_type='add', vars = {})
280
- params = {'SnapshotId' => snapshot_id,
281
- 'Attribute' => attribute,
282
- 'OperationType' => operation_type}
283
- params.update(amazonize_list('UserId', Array(vars[:user_id]))) if vars[:user_id]
284
- params.update(amazonize_list('UserGroup', Array(vars[:user_group]))) if vars[:user_group]
288
+ # Attribute can take only 'createVolumePermission' value.
289
+ # Value is a Hash {:add_user_ids, :add_groups, :remove_user_ids, :remove_groups }.
290
+ #
291
+ def modify_snapshot_attribute(snapshot_id, attribute, value)
292
+ params = { 'SnapshotId' => snapshot_id }
293
+ case attribute.to_s
294
+ when 'createVolumePermission'
295
+ params.update(amazonize_list('CreateVolumePermission.Add.?.UserId', value[:add_user_ids]))
296
+ params.update(amazonize_list('CreateVolumePermission.Add.?.Group', value[:add_groups]))
297
+ params.update(amazonize_list('CreateVolumePermission.Remove.?.UserId', value[:remove_user_ids]))
298
+ params.update(amazonize_list('CreateVolumePermission.Remove.?.Group', value[:remove_groups]))
299
+ end
285
300
  link = generate_request("ModifySnapshotAttribute", params)
286
301
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
287
302
  rescue Exception
@@ -292,36 +307,36 @@ module RightAws
292
307
  #
293
308
  # ec2.modify_snapshot_attribute_create_volume_permission_add_users('snap-36fe435f', '000000000000', '000000000001') #=> true
294
309
  #
295
- def modify_snapshot_attribute_create_volume_permission_add_users(snapshot_id, *user_id)
296
- modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'add', :user_id => user_id.flatten )
310
+ def modify_snapshot_attribute_create_volume_permission_add_users(snapshot_id, *user_ids)
311
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', :add_user_ids => user_ids.flatten )
297
312
  end
298
313
 
299
314
  # Revoke create volume permission for a list of users.
300
315
  #
301
316
  # ec2.modify_snapshot_attribute_create_volume_permission_remove_users('snap-36fe435f', '000000000000', '000000000001') #=> true
302
317
  #
303
- def modify_snapshot_attribute_create_volume_permission_remove_users(snapshot_id, *user_id)
304
- modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'remove', :user_id => user_id.flatten )
318
+ def modify_snapshot_attribute_create_volume_permission_remove_users(snapshot_id, *user_ids)
319
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', :remove_user_ids => user_ids.flatten )
305
320
  end
306
321
 
307
322
  # Grant create volume permission for user groups (currently only 'all' is supported).
308
323
  #
309
324
  # ec2.modify_snapshot_attribute_create_volume_permission_add_groups('snap-36fe435f') #=> true
310
325
  #
311
- def modify_snapshot_attribute_create_volume_permission_add_groups(snapshot_id, *user_group)
312
- user_group.flatten!
313
- user_group = ['all'] if user_group.right_blank?
314
- modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'add', :user_group => user_group )
326
+ def modify_snapshot_attribute_create_volume_permission_add_groups(snapshot_id, *groups)
327
+ groups.flatten!
328
+ groups = ['all'] if groups.right_blank?
329
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', :add_groups => groups )
315
330
  end
316
331
 
317
332
  # Remove create volume permission for user groups (currently only 'all' is supported).
318
333
  #
319
334
  # ec2.modify_snapshot_attribute_create_volume_permission_remove_groups('snap-36fe435f') #=> true
320
335
  #
321
- def modify_snapshot_attribute_create_volume_permission_remove_groups(snapshot_id, *user_group)
322
- user_group.flatten!
323
- user_group = ['all'] if user_group.right_blank?
324
- modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'remove', :user_group => user_group )
336
+ def modify_snapshot_attribute_create_volume_permission_remove_groups(snapshot_id, *groups)
337
+ groups.flatten!
338
+ groups = ['all'] if groups.right_blank?
339
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', :remove_groups => groups )
325
340
  end
326
341
 
327
342
  # Delete the specified snapshot.
@@ -427,6 +442,7 @@ module RightAws
427
442
  when 'description' then @item[:aws_description] = @text
428
443
  when 'ownerId' then @item[:aws_owner] = @text
429
444
  when 'volumeSize' then @item[:aws_volume_size] = @text.to_i
445
+ when 'ownerAlias' then @item[:owner_alias] = @text
430
446
  else
431
447
  case full_tag_name
432
448
  when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
@@ -180,7 +180,7 @@ module RightAws
180
180
  params['KernelId'] = options[:kernel_id] if options[:kernel_id]
181
181
  params['RamdiskId'] = options[:ramdisk_id] if options[:ramdisk_id]
182
182
  params['RootDeviceName'] = options[:root_device_name] if options[:root_device_name]
183
- params['VirtualizationType'] = options[:virtualization_type] if options[:virtualization_type]
183
+ params['VirtualizationType'] = options[:virtualization_type] if options[:virtualization_type]
184
184
  # params['SnapshotId'] = options[:snapshot_id] if options[:snapshot_id]
185
185
  params.merge!(amazonize_block_device_mappings(options[:block_device_mappings]))
186
186
  link = generate_request("RegisterImage", params)
@@ -201,9 +201,19 @@ module RightAws
201
201
  on_exception
202
202
  end
203
203
 
204
- # Describe image attributes. Currently 'launchPermission', 'productCodes', 'kernel', 'ramdisk' and 'blockDeviceMapping' are supported.
205
- #
206
- # ec2.describe_image_attribute('ami-e444444d') #=> {:groups=>["all"], :users=>["000000000777"]}
204
+ # Describe image attributes.
205
+ #
206
+ # Returns: String (or nil) for 'description', 'kernel', 'ramdisk'; Hash for 'launchPermission'; Array for 'productCodes', 'blockDeviceMapping'
207
+ #
208
+ # ec2.describe_image_attribute('ami-00000000', 'description') #=> 'My cool Image'
209
+ # ec2.describe_image_attribute('ami-00000000', 'launchPermission') #=> {:user_ids=>["443739700000", "115864000000", "309179000000", "857501300000"]}
210
+ # ec2.describe_image_attribute('ami-00000000', 'productCodes') #=> ["8ED10000"]
211
+ # ec2.describe_image_attribute('ami-00000000', 'kernel') #=> "aki-9b00e5f2"
212
+ # ec2.describe_image_attribute('ami-00000000', 'ramdisk') #=> nil
213
+ # ec2.describe_image_attribute('ami-00000000', 'blockDeviceMapping') #=> [{:device_name=>"sda2", :virtual_name=>"ephemeral0"},
214
+ # {:device_name=>"sda1", :virtual_name=>"ami"},
215
+ # {:device_name=>"/dev/sda1", :virtual_name=>"root"},
216
+ # {:device_name=>"sda3", :virtual_name=>"swap"}]
207
217
  #
208
218
  def describe_image_attribute(image_id, attribute='launchPermission')
209
219
  link = generate_request("DescribeImageAttribute",
@@ -232,19 +242,23 @@ module RightAws
232
242
  # instead of modify_image_attribute because the signature of
233
243
  # modify_image_attribute may change with EC2 service changes.
234
244
  #
235
- # attribute : currently, only 'launchPermission' is supported.
236
- # operation_type : currently, only 'add' & 'remove' are supported.
237
- # vars:
238
- # :user_group : currently, only 'all' is supported.
239
- # :user_id
240
- # :product_code
241
- def modify_image_attribute(image_id, attribute, operation_type = nil, vars = {})
242
- params = {'ImageId' => image_id,
243
- 'Attribute' => attribute}
244
- params['OperationType'] = operation_type if operation_type
245
- params.update(amazonize_list('UserId', vars[:user_id])) if vars[:user_id]
246
- params.update(amazonize_list('UserGroup', vars[:user_group])) if vars[:user_group]
247
- params.update(amazonize_list('ProductCode', vars[:product_code])) if vars[:product_code]
245
+ # Attribute can take next values: 'launchPermission', 'productCode', 'description'.
246
+ # Value is a String for'description'. is a String or an Array for 'productCode' and
247
+ # is a Hash {:add_user_ids, :add_groups, :remove_user_ids, :remove_groups } for 'launchPermission'.
248
+ #
249
+ def modify_image_attribute(image_id, attribute, value)
250
+ params = { 'ImageId' => image_id }
251
+ case attribute.to_s
252
+ when 'launchPermission'
253
+ params.update(amazonize_list('LaunchPermission.Add.?.UserId', value[:add_user_ids]))
254
+ params.update(amazonize_list('LaunchPermission.Add.?.Group', value[:add_groups]))
255
+ params.update(amazonize_list('LaunchPermission.Remove.?.UserId', value[:remove_user_ids]))
256
+ params.update(amazonize_list('LaunchPermission.Remove.?.Group', value[:remove_groups]))
257
+ when 'productCode'
258
+ params.update(amazonize_list('ProductCode', value))
259
+ when 'description'
260
+ params['Description.Value'] = value
261
+ end
248
262
  link = generate_request("ModifyImageAttribute", params)
249
263
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
250
264
  rescue Exception
@@ -256,16 +270,16 @@ module RightAws
256
270
  # Returns +true+ or an exception.
257
271
  #
258
272
  # ec2.modify_image_launch_perm_add_users('ami-e444444d',['000000000777','000000000778']) #=> true
259
- def modify_image_launch_perm_add_users(image_id, user_id=[])
260
- modify_image_attribute(image_id, 'launchPermission', 'add', :user_id => user_id)
273
+ def modify_image_launch_perm_add_users(image_id, *user_ids)
274
+ modify_image_attribute(image_id, 'launchPermission', :add_user_ids => user_ids.flatten)
261
275
  end
262
276
 
263
277
  # Revokes image launch permissions for users. +user_id+ is a list of users AWS accounts ids. Returns +true+ or an exception.
264
278
  #
265
279
  # ec2.modify_image_launch_perm_remove_users('ami-e444444d',['000000000777','000000000778']) #=> true
266
280
  #
267
- def modify_image_launch_perm_remove_users(image_id, user_id=[])
268
- modify_image_attribute(image_id, 'launchPermission', 'remove', :user_id => user_id)
281
+ def modify_image_launch_perm_remove_users(image_id, *user_ids)
282
+ modify_image_attribute(image_id, 'launchPermission', :remove_user_ids => user_ids.flatten)
269
283
  end
270
284
 
271
285
  # Add image launch permissions for users groups (currently only 'all' is supported, which gives public launch permissions).
@@ -273,24 +287,32 @@ module RightAws
273
287
  #
274
288
  # ec2.modify_image_launch_perm_add_groups('ami-e444444d') #=> true
275
289
  #
276
- def modify_image_launch_perm_add_groups(image_id, user_group=['all'])
277
- modify_image_attribute(image_id, 'launchPermission', 'add', :user_group => user_group)
290
+ def modify_image_launch_perm_add_groups(image_id, *groups)
291
+ modify_image_attribute(image_id, 'launchPermission', :add_groups => groups.flatten)
278
292
  end
279
293
 
280
294
  # Remove image launch permissions for users groups (currently only 'all' is supported, which gives public launch permissions).
281
295
  #
282
296
  # ec2.modify_image_launch_perm_remove_groups('ami-e444444d') #=> true
283
297
  #
284
- def modify_image_launch_perm_remove_groups(image_id, user_group=['all'])
285
- modify_image_attribute(image_id, 'launchPermission', 'remove', :user_group => user_group)
298
+ def modify_image_launch_perm_remove_groups(image_id, *groups)
299
+ modify_image_attribute(image_id, 'launchPermission', :remove_groups => groups.flatten)
286
300
  end
287
301
 
288
302
  # Add product code to image
289
303
  #
290
304
  # ec2.modify_image_product_code('ami-e444444d','0ABCDEF') #=> true
291
305
  #
292
- def modify_image_product_code(image_id, product_code=[])
293
- modify_image_attribute(image_id, 'productCodes', nil, :product_code => product_code)
306
+ def modify_image_product_code(image_id, product_codes=[])
307
+ modify_image_attribute(image_id, 'productCodes',product_codes)
308
+ end
309
+
310
+ # Modify image description
311
+ #
312
+ # ec2.modify_image_product_code('ami-e444444d','My cool image') #=> true
313
+ #
314
+ def modify_image_description(image_id, description)
315
+ modify_image_attribute(image_id, 'description', description)
294
316
  end
295
317
 
296
318
  # Create a new image.
@@ -345,6 +367,7 @@ module RightAws
345
367
  when 'rootDeviceName' then @item[:root_device_name] = @text
346
368
  when 'imageClass' then @item[:image_class] = @text
347
369
  when 'virtualizationType' then @item[:virtualization_type] = @text
370
+ when 'hypervisor' then @item [:hypervisor] = @text
348
371
  else
349
372
  case full_tag_name
350
373
  when %r{/stateReason/code$} then @item[:state_reason_code] = @text.to_i
@@ -382,29 +405,35 @@ module RightAws
382
405
 
383
406
  class QEc2DescribeImageAttributeParser < RightAWSParser #:nodoc:
384
407
  def tagstart(name, attributes)
385
- case name
386
- when 'launchPermission'
387
- @result[:groups] = []
388
- @result[:users] = []
389
- when 'productCodes'
390
- @result[:aws_product_codes] = []
408
+ case full_tag_name
409
+ when %r{launchPermission$} then @result = {}
410
+ when %r{productCodes$} then @result = []
411
+ when %r{blockDeviceMapping$} then @result = []
412
+ when %r{blockDeviceMapping/item$} then @block_device_mapping = {}
391
413
  end
392
414
  end
393
415
  def tagend(name)
394
- # right now only 'launchPermission' is supported by Amazon.
395
- # But nobody know what will they xml later as attribute. That is why we
396
- # check for 'group' and 'userId' inside of 'launchPermission/item'
397
- case name
398
- when 'imageId' then @result[:aws_id] = @text
399
- when 'group' then @result[:groups] << @text if @xmlpath == 'DescribeImageAttributeResponse/launchPermission/item'
400
- when 'userId' then @result[:users] << @text if @xmlpath == 'DescribeImageAttributeResponse/launchPermission/item'
401
- when 'productCode' then @result[:aws_product_codes] << @text
402
- when 'kernel' then @result[:aws_kernel] = @text
403
- when 'ramdisk' then @result[:aws_ramdisk] = @text
416
+ case full_tag_name
417
+ when %r{/kernel/value$} then @result = @text
418
+ when %r{/ramdisk/value$} then @result = @text
419
+ when %r{/description/value$} then @result = @text
420
+ when %r{/productCode$} then @result << @text
421
+ when %r{launchPermission/item/group$} then (@result[:groups] ||=[]) << @text
422
+ when %r{launchPermission/item/userId$} then (@result[:user_ids]||=[]) << @text
423
+ when %r{/blockDeviceMapping/item} # no trailing $
424
+ case name
425
+ when 'deviceName' then @block_device_mapping[:device_name] = @text
426
+ when 'virtualName' then @block_device_mapping[:virtual_name] = @text
427
+ when 'noDevice' then @block_device_mapping[:no_device] = @text
428
+ when 'snapshotId' then @block_device_mapping[:ebs_snapshot_id] = @text
429
+ when 'volumeSize' then @block_device_mapping[:ebs_volume_size] = @text
430
+ when 'deleteOnTermination' then @block_device_mapping[:ebs_delete_on_termination] = @text == 'true' ? true : false
431
+ when 'item' then @result << @block_device_mapping
432
+ end
404
433
  end
405
434
  end
406
435
  def reset
407
- @result = {}
436
+ @result = nil
408
437
  end
409
438
  end
410
439