right_aws 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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