right_aws 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -30,7 +30,11 @@ module RightAws
30
30
  #-----------------------------------------------------------------
31
31
 
32
32
  # Retrieve reserved instances list.
33
- # Returns a list of Reserved Instances.
33
+ #
34
+ # Accepts a list of reserved instances and/or a set of filters as the last parameter.
35
+ #
36
+ # Filters: availability-zone, duration, fixed-price, instance-type, product-description,
37
+ # reserved-instances-id, start, state, tag-key, tag-value, tag:key, usage-price
34
38
  #
35
39
  # ec2.describe_reserved_instances #=>
36
40
  # [{:aws_id=>"1ba8e2e3-1c40-434c-a741-5ff16a4c542e",
@@ -44,21 +48,19 @@ module RightAws
44
48
  # :aws_start=>"2009-12-18T20:39:39.569Z"
45
49
  # :aws_instance_count=>1}]
46
50
  #
47
- def describe_reserved_instances(*reserved_instances)
48
- reserved_instances = reserved_instances.flatten
49
- link = generate_request("DescribeReservedInstances", amazonize_list('ReservedInstancesId', reserved_instances))
50
- request_cache_or_info(:describe_reserved_instances, link, QEc2DescribeReservedInstancesParser, @@bench, reserved_instances.blank?)
51
- rescue Exception
52
- on_exception
51
+ # ec2.describe_reserved_instances(:filters => {'availability-zone' => 'us-east-1a'})
52
+ #
53
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeReservedInstances.html
54
+ #
55
+ def describe_reserved_instances(*list_and_options)
56
+ describe_resources_with_list_and_options('DescribeReservedInstances', 'ReservedInstancesId', QEc2DescribeReservedInstancesParser, list_and_options)
53
57
  end
54
58
 
55
59
  # Retrieve reserved instances offerings.
56
- # Returns a set of available offerings.
60
+ #
61
+ # Accepts a list of reserved instances offerings and/or a set of filters as the last parameter.
57
62
  #
58
- # Optional params:
59
- # :aws_instance_type => String
60
- # :aws_availability_zone => String
61
- # :aws_product_description => String
63
+ # Filters: availability-zone, duration, fixed-price, instance-type, product-description, reserved-instances-offering-id, usage-price
62
64
  #
63
65
  # ec2.describe_reserved_instances_offerings #=>
64
66
  # [{:aws_instance_type=>"c1.medium",
@@ -77,19 +79,12 @@ module RightAws
77
79
  # :aws_usage_price=>0.24,
78
80
  # :aws_fixed_price=>2600.0}]
79
81
  #
80
- def describe_reserved_instances_offerings(*list_and_params)
81
- list, params = AwsUtils::split_items_and_params(list_and_params)
82
- # backward compartibility with the old way
83
- list ||= Array(params[:aws_ids])
84
- rparams = {}
85
- rparams.update(amazonize_list('ReservedInstancesOfferingId', list)) unless list.blank?
86
- rparams['InstanceType'] = params[:aws_instance_type] if params[:aws_instance_type]
87
- rparams['AvailabilityZone'] = params[:aws_availability_zone] if params[:aws_availability_zone]
88
- rparams['ProductDescription'] = params[:aws_product_description] if params[:aws_product_description]
89
- link = generate_request("DescribeReservedInstancesOfferings", rparams)
90
- request_cache_or_info(:describe_reserved_instances_offerings, link, QEc2DescribeReservedInstancesOfferingsParser, @@bench, list.blank?)
91
- rescue Exception
92
- on_exception
82
+ # ec2.describe_reserved_instances_offerings(:filters => {'availability-zone' => 'us-east-1c'})
83
+ #
84
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeReservedInstancesOfferings.html
85
+ #
86
+ def describe_reserved_instances_offerings(*list_and_options)
87
+ describe_resources_with_list_and_options('DescribeReservedInstancesOfferings', 'ReservedInstancesOfferingId', QEc2DescribeReservedInstancesOfferingsParser, list_and_options)
93
88
  end
94
89
 
95
90
  # Purchase a Reserved Instance.
@@ -111,21 +106,30 @@ module RightAws
111
106
 
112
107
  class QEc2DescribeReservedInstancesParser < RightAWSParser #:nodoc:
113
108
  def tagstart(name, attributes)
114
- @item = {} if name == 'item'
109
+ case full_tag_name
110
+ when %r{/reservedInstancesSet/item$} then @item = { :tags => {} }
111
+ when %r{/tagSet/item$} then @aws_tag = {}
112
+ end
115
113
  end
116
114
  def tagend(name)
117
115
  case name
118
- when 'reservedInstancesId' then @item[:aws_id] = @text
119
- when 'instanceType' then @item[:aws_instance_type] = @text
120
- when 'availabilityZone' then @item[:aws_availability_zone] = @text
121
- when 'duration' then @item[:aws_duration] = @text.to_i
122
- when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
123
- when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
124
- when 'instanceCount' then @item[:aws_instance_count] = @text.to_i
125
- when 'productDescription' then @item[:aws_product_description] = @text
126
- when 'state' then @item[:aws_state] = @text
127
- when 'start' then @item[:aws_start] = @text
128
- when 'item' then @result << @item
116
+ when 'reservedInstancesId' then @item[:aws_id] = @text
117
+ when 'instanceType' then @item[:aws_instance_type] = @text
118
+ when 'availabilityZone' then @item[:aws_availability_zone] = @text
119
+ when 'duration' then @item[:aws_duration] = @text.to_i
120
+ when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
121
+ when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
122
+ when 'instanceCount' then @item[:aws_instance_count] = @text.to_i
123
+ when 'productDescription' then @item[:aws_product_description] = @text
124
+ when 'state' then @item[:aws_state] = @text
125
+ when 'start' then @item[:aws_start] = @text
126
+ else
127
+ case full_tag_name
128
+ when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
129
+ when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
130
+ when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
131
+ when %r{/reservedInstancesSet/item$} then @result << @item
132
+ end
129
133
  end
130
134
  end
131
135
  def reset
@@ -136,19 +140,19 @@ module RightAws
136
140
  class QEc2DescribeReservedInstancesOfferingsParser < RightAWSParser #:nodoc:
137
141
  def tagstart(name, attributes)
138
142
  @item = {} if name == 'item'
139
- end
143
+ end
140
144
  def tagend(name)
141
145
  case name
142
- when 'reservedInstancesOfferingId' then @item[:aws_id] = @text
143
- when 'instanceType' then @item[:aws_instance_type] = @text
144
- when 'availabilityZone' then @item[:aws_availability_zone] = @text
145
- when 'duration' then @item[:aws_duration] = @text.to_i
146
- when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
147
- when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
148
- when 'productDescription' then @item[:aws_product_description] = @text
146
+ when 'reservedInstancesOfferingId' then @item[:aws_id] = @text
147
+ when 'instanceType' then @item[:aws_instance_type] = @text
148
+ when 'availabilityZone' then @item[:aws_availability_zone] = @text
149
+ when 'duration' then @item[:aws_duration] = @text.to_i
150
+ when 'usagePrice' then @item[:aws_usage_price] = @text.to_f
151
+ when 'fixedPrice' then @item[:aws_fixed_price] = @text.to_f
152
+ when 'productDescription' then @item[:aws_product_description] = @text
149
153
  when 'item' then @result << @item
154
+ end
150
155
  end
151
- end
152
156
  def reset
153
157
  @result = []
154
158
  end
@@ -29,7 +29,12 @@ module RightAws
29
29
  # Security groups
30
30
  #-----------------------------------------------------------------
31
31
 
32
- # Retrieve Security Groups information. If +list+ is omitted the returns the whole list of groups.
32
+ # Retrieve Security Groups information.
33
+ #
34
+ # Accepts a list of security groups and/or a set of filters as the last parameter.
35
+ #
36
+ # Filters: description, group-name, ip-permission.cidr, ip-permission.from-port, ip-permission.group-name,
37
+ # ip-permission.protocol, ip-permission.to-port, ip-permission.user-id, owner-id
33
38
  #
34
39
  # # Amazon cloud:
35
40
  # ec2 = Rightscale::Ec2.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
@@ -79,10 +84,12 @@ module RightAws
79
84
  # :aws_description=>"default group",
80
85
  # :aws_owner=>"826693181925"}]
81
86
  #
82
- def describe_security_groups(list=[])
83
- link = generate_request("DescribeSecurityGroups", amazonize_list('GroupName', list))
84
-
85
- request_cache_or_info( :describe_security_groups, link, QEc2DescribeSecurityGroupsParser, @@bench, list.blank?) do |parser|
87
+ # ec2.describe_security_groups(:filters => {'ip-permission.from-port' => '22'})
88
+ #
89
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html
90
+ #
91
+ def describe_security_groups(*list_and_options)
92
+ describe_resources_with_list_and_options('DescribeSecurityGroups', 'GroupName', QEc2DescribeSecurityGroupsParser, list_and_options) do |parser|
86
93
  result = []
87
94
  parser.result.each do |item|
88
95
  result_item = { :aws_owner => item[:owner_id],
@@ -97,10 +104,7 @@ module RightAws
97
104
  # IP permissions
98
105
  Array(permission[:ip_ranges]).each do |ip_range|
99
106
  perm = result_perm.dup
100
- # Mhhh... For Eucalyptus we somehow get used to use ":cidr_ip" instead of ":cidr_ips"...
101
- if @params[:eucalyptus] then perm[:cidr_ip] = ip_range
102
- else perm[:cidr_ips] = ip_range
103
- end
107
+ perm[:cidr_ips] = ip_range
104
108
  aws_perms << perm
105
109
  end
106
110
  # Group permissions
@@ -108,12 +112,6 @@ module RightAws
108
112
  perm = result_perm.dup
109
113
  perm[:group] = group[:group_name]
110
114
  perm[:owner] = group[:user_id]
111
- # AWS does not support Port Based Group Permissions but Eucalyptus does
112
- unless @params[:port_based_group_ingress]
113
- perm.delete(:from_port)
114
- perm.delete(:to_port)
115
- perm.delete(:protocol)
116
- end
117
115
  aws_perms << perm
118
116
  end
119
117
  end
@@ -122,8 +120,6 @@ module RightAws
122
120
  end
123
121
  result
124
122
  end
125
- rescue Exception
126
- on_exception
127
123
  end
128
124
 
129
125
  # Create new Security Group. Returns +true+ or an exception.
@@ -132,7 +128,7 @@ module RightAws
132
128
  #
133
129
  def create_security_group(name, description=nil)
134
130
  # EC2 doesn't like an empty description...
135
- description = "-" if description.blank?
131
+ description = "-" if description.right_blank?
136
132
  link = generate_request("CreateSecurityGroup",
137
133
  'GroupName' => name.to_s,
138
134
  'GroupDescription' => description.to_s)
@@ -153,13 +149,14 @@ module RightAws
153
149
  on_exception
154
150
  end
155
151
 
156
- # Edit group permissions.
152
+ # Edit AWS/Eucaliptus security group permissions.
157
153
  #
158
- # action - :authorize (or :grant) | :revoke (or :remove)
159
- # group_name - security group name
160
- # params - a combination of options below:
161
- # :source_group_owner => grantee id
162
- # :source_group => grantee group name
154
+ # Options:
155
+ # action - :authorize (or :grant) | :revoke (or :remove)
156
+ # group_name - security group name
157
+ # permissions - a combination of options below:
158
+ # :source_group_owner => UserId
159
+ # :source_group => GroupName
163
160
  # :from_port => from port
164
161
  # :to_port => to port
165
162
  # :port => set both :from_port and to_port with the same value
@@ -174,7 +171,8 @@ module RightAws
174
171
  # :port => '80',
175
172
  # :cidr_ip => '127.0.0.1/32') #=> true
176
173
  #
177
- # P.S. setting both group based and port based ingresses is not supported by Amazon but by Eucalyptus.
174
+ # P.S. This method is deprecated for AWS and but still good for Eucaliptus clouds.
175
+ # Use +modify_security_group_ingress+ method for AWS clouds.
178
176
  #
179
177
  def edit_security_group(action, group_name, params)
180
178
  hash = {}
@@ -184,16 +182,134 @@ module RightAws
184
182
  else raise "Unknown action #{action.inspect}!"
185
183
  end
186
184
  hash['GroupName'] = group_name
187
- hash['SourceSecurityGroupName'] = params[:source_group] unless params[:source_group].blank?
188
- hash['SourceSecurityGroupOwnerId'] = params[:source_group_owner].to_s.gsub(/-/,'') unless params[:source_group_owner].blank?
189
- hash['IpProtocol'] = params[:protocol] unless params[:protocol].blank?
190
- unless params[:port].blank?
185
+ hash['SourceSecurityGroupName'] = params[:source_group] unless params[:source_group].right_blank?
186
+ hash['SourceSecurityGroupOwnerId'] = params[:source_group_owner].to_s.gsub(/-/,'') unless params[:source_group_owner].right_blank?
187
+ hash['IpProtocol'] = params[:protocol] unless params[:protocol].right_blank?
188
+ unless params[:port].right_blank?
191
189
  hash['FromPort'] = params[:port]
192
190
  hash['ToPort'] = params[:port]
193
191
  end
194
- hash['FromPort'] = params[:from_port] unless params[:from_port].blank?
195
- hash['ToPort'] = params[:to_port] unless params[:to_port].blank?
196
- hash['CidrIp'] = params[:cidr_ip] unless params[:cidr_ip].blank?
192
+ hash['FromPort'] = params[:from_port] unless params[:from_port].right_blank?
193
+ hash['ToPort'] = params[:to_port] unless params[:to_port].right_blank?
194
+ hash['CidrIp'] = params[:cidr_ip] unless params[:cidr_ip].right_blank?
195
+ #
196
+ link = generate_request(action, hash)
197
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
198
+ rescue Exception
199
+ on_exception
200
+ end
201
+
202
+ # Modify AWS security group permissions.
203
+ #
204
+ # Options:
205
+ # action - :authorize (or :grant) | :revoke (or :remove)
206
+ # group_name - security group name
207
+ # permissions - a combination of options below:
208
+ # # Ports:
209
+ # :from_port => from port
210
+ # :to_port => to port
211
+ # :port => set both :from_port and to_port with the same value
212
+ # # Protocol
213
+ # :protocol => :tcp | :udp | :icmp
214
+ # # Group(s)
215
+ # :source_group_owner => UserId
216
+ # :source_group => GroupName
217
+ # # or
218
+ # :source_groups => { UserId1 => GroupName1, UserName2 => GroupName2 }
219
+ # :source_groups => [ [ UserId1, GroupName1 ], [ UserName2 => GroupName2 ] ]
220
+ # # CidrIp(s)
221
+ # :cidr_ip => '0.0.0.0/0'
222
+ # :cidr_ips => ['1.1.1.1/1', '2.2.2.2/2']
223
+ #
224
+ # # CidrIP based permissions:
225
+ #
226
+ # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
227
+ # :cidr_ip => "127.0.0.0/31",
228
+ # :port => 811,
229
+ # :protocol => 'tcp' ) #=> true
230
+ #
231
+ # ec2.modify_security_group_ingress(:revoke, 'my_cool_group',
232
+ # :cidr_ips => ["127.0.0.1/32", "127.0.0.2/32"],
233
+ # :port => 812,
234
+ # :protocol => 'tcp' ) #=> true
235
+ #
236
+ # # Group based permissions:
237
+ #
238
+ # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
239
+ # :source_group_owner => "586789340000",
240
+ # :source_group => "sketchy-us",
241
+ # :port => 800,
242
+ # :protocol => 'tcp' ) #=> true
243
+ #
244
+ # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
245
+ # :source_groups => { "586789340000" => "sketchy-us",
246
+ # "635201710000" => "sketchy" },
247
+ # :port => 801,
248
+ # :protocol => 'tcp' ) #=> true
249
+ #
250
+ # ec2.modify_security_group_ingress(:revoke, 'my_cool_group',
251
+ # :source_groups => [[ "586789340000", "sketchy-us" ],
252
+ # [ "586789340000", "default" ]],
253
+ # :port => 809,
254
+ # :protocol => 'tcp' ) #=> true
255
+ #
256
+ # # +Permissions+ can be an array of permission hashes:
257
+ #
258
+ # ec2.modify_security_group_ingress(:authorize, 'my_cool_group',
259
+ # [{ :source_groups => { "586789340000" => "sketchy-us",
260
+ # "635201710000" => "sketchy" },
261
+ # :port => 803,
262
+ # :protocol => 'tcp'},
263
+ # { :cidr_ips => ["127.0.0.1/32", "127.0.0.2/32"],
264
+ # :port => 812,
265
+ # :protocol => 'tcp' }]) #=> true
266
+ #
267
+ def modify_security_group_ingress(action, group_name, permissions)
268
+ hash = {}
269
+ case action
270
+ when :authorize, :grant then action = "AuthorizeSecurityGroupIngress"
271
+ when :revoke, :remove then action = "RevokeSecurityGroupIngress"
272
+ else raise "Unknown action #{action.inspect}!"
273
+ end
274
+ # Group Name
275
+ hash["GroupName"] = group_name
276
+ #
277
+ permissions = [permissions] unless permissions.is_a?(Array)
278
+ permissions.each_with_index do |permission, idx|
279
+ pid = idx+1
280
+ # Protocol
281
+ hash["IpPermissions.#{pid}.IpProtocol"] = permission[:protocol]
282
+ # Port
283
+ unless permission[:port].right_blank?
284
+ hash["IpPermissions.#{pid}.FromPort"] = permission[:port]
285
+ hash["IpPermissions.#{pid}.ToPort"] = permission[:port]
286
+ else
287
+ hash["IpPermissions.#{pid}.FromPort"] = permission[:from_port]
288
+ hash["IpPermissions.#{pid}.ToPort"] = permission[:to_port]
289
+ end
290
+ # Source Group(s)
291
+ # Old way (if it is used):
292
+ # :source_group_owner => UserId, :source_group => GroupName
293
+ if !permission[:source_group].right_blank? && !permission[:source_group_owner].right_blank?
294
+ permission[:source_groups] = { permission[:source_group_owner] => permission[:source_group]}
295
+ end
296
+ # # Fix UserId(s): '0000-0000-0000' => '000000000000'
297
+ # permission[:source_groups] = Array(permission[:source_groups])
298
+ # permission[:source_groups].each do |item|
299
+ # item[0] = item[0].to_s.gsub(/-/,'')
300
+ # end
301
+ # New way:
302
+ # :source_groups => {UserId1 => GroupName1, ... UserIdN => GroupNameN}
303
+ # or (this allows using same UserId multiple times )
304
+ # :source_groups => [[UserId1, GroupName1], ... [UserIdN, GroupNameN]]
305
+ hash.merge!(amazonize_list( ["IpPermissions.#{pid}.Groups.?.UserId",
306
+ "IpPermissions.#{pid}.Groups.?.GroupName"],
307
+ permission[:source_groups] ))
308
+ # CidrIp(s)
309
+ cidr_ips = permission[:cidr_ips] unless permission[:cidr_ips].right_blank?
310
+ cidr_ips ||= permission[:cidr_ip] unless permission[:cidr_ip].right_blank?
311
+ hash.merge!(amazonize_list("IpPermissions.1.IpRanges.?.CidrIp", cidr_ips))
312
+ end
197
313
  #
198
314
  link = generate_request(action, hash)
199
315
  request_info(link, RightBoolResponseParser.new(:logger => @logger))
@@ -30,7 +30,10 @@ module RightAws
30
30
  #-----------------------------------------------------------------
31
31
 
32
32
  # Describe Spot Price history.
33
+ #
33
34
  # Options: :start_time, :end_time, instance_types, product_description
35
+ #
36
+ # Filters: instance-type, product-description, spot-price, timestamp
34
37
  #
35
38
  # ec2.describe_spot_price_history #=>
36
39
  # [{:spot_price=>0.054,
@@ -63,13 +66,21 @@ module RightAws
63
66
  # :spot_price=>0.058,
64
67
  # :instance_type=>"c1.medium"}, ... ]
65
68
  #
69
+ # ec2.describe_spot_price_history(:filters => {'spot-price' => '0.2' })
70
+ #
71
+ # ec2.describe_spot_price_history(:instance_types => ["c1.medium"], :filters => {'spot-price' => '0.2' })
72
+ #
73
+ #
74
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeSpotPriceHistory.html
75
+ #
66
76
  def describe_spot_price_history(options={})
67
77
  options = options.dup
68
78
  request_hash = {}
69
- request_hash['StartTime'] = AwsUtils::utc_iso8601(options[:start_time]) unless options[:start_time].blank?
70
- request_hash['EndTime'] = AwsUtils::utc_iso8601(options[:end_time]) unless options[:end_time].blank?
71
- request_hash['ProductDescription'] = options[:product_description] unless options[:product_description].blank?
72
- request_hash.merge!(amazonize_list('InstanceType', Array(options[:instance_types]))) unless options[:instance_types].blank?
79
+ request_hash.merge!(amazonize_list(['Filter.?.Name', 'Filter.?.Value.?'], options[:filters])) unless options[:filters].right_blank?
80
+ request_hash['StartTime'] = AwsUtils::utc_iso8601(options[:start_time]) unless options[:start_time].right_blank?
81
+ request_hash['EndTime'] = AwsUtils::utc_iso8601(options[:end_time]) unless options[:end_time].right_blank?
82
+ request_hash['ProductDescription'] = options[:product_description] unless options[:product_description].right_blank?
83
+ request_hash.merge!(amazonize_list('InstanceType', Array(options[:instance_types]))) unless options[:instance_types].right_blank?
73
84
  link = generate_request("DescribeSpotPriceHistory", request_hash)
74
85
  request_info(link, QEc2DescribeSpotPriceHistoryParser.new)
75
86
  rescue Exception
@@ -78,6 +89,14 @@ module RightAws
78
89
 
79
90
  # Describe Spot Instance requests.
80
91
  #
92
+ # Accepts a list of requests and/or a set of filters as the last parameter.
93
+ #
94
+ # Filters: availability-zone-group, create-time, fault-code, fault-message, instance-id, launch-group,
95
+ # launch.block-device-mapping.delete-on-termination, launch.block-device-mapping.device-name,
96
+ # launch.block-device-mapping.snapshot-id, launch.group-id, launch.image-id, launch.instance-type,
97
+ # launch.kernel-id, launch.key-name, launch.monitoring-enabled, launch.ramdisk-id, product-description,
98
+ # spot-instance-request-id, spot-price, state, tag-key, tag-value, tag:key, type, valid-from, valid-until
99
+ #
81
100
  # ec2.describe_spot_instance_requests #=>
82
101
  # [{:type=>"one-time",
83
102
  # :create_time=>"2010-03-10T10:30:32.000Z",
@@ -113,9 +132,12 @@ module RightAws
113
132
  # :monitoring_enabled=>false,
114
133
  # :key_name=>"tim"}]
115
134
  #
116
- def describe_spot_instance_requests(*spot_instance_request_ids)
117
- link = generate_request("DescribeSpotInstanceRequests", amazonize_list('SpotInstanceRequestId', spot_instance_request_ids.flatten))
118
- request_info(link, QEc2DescribeSpotInstanceParser.new(:logger => @logger))
135
+ # ec2.describe_spot_instance_requests(:filters => {'type'=>"one-time", 'state'=>"open"})
136
+ #
137
+ # P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeSpotInstanceRequests.html
138
+ #
139
+ def describe_spot_instance_requests(*list_and_options)
140
+ describe_resources_with_list_and_options('DescribeSpotInstanceRequests', 'SpotInstanceRequestId', QEc2DescribeSpotInstanceParser, list_and_options)
119
141
  end
120
142
 
121
143
  # Create a Spot Instance request.
@@ -205,25 +227,25 @@ module RightAws
205
227
  request_hash = { 'SpotPrice' => options[:spot_price],
206
228
  'LaunchSpecification.ImageId' => options[:image_id],
207
229
  'LaunchSpecification.InstanceType' => options[:instance_type]}
208
- request_hash['ValidFrom'] = AwsUtils::utc_iso8601(options[:valid_from]) unless options[:valid_from].blank?
209
- request_hash['ValidUntil'] = AwsUtils::utc_iso8601(options[:valid_until]) unless options[:valid_until].blank?
210
- request_hash['InstanceCount'] = options[:instance_count] unless options[:instance_count].blank?
211
- request_hash['Type'] = options[:type] unless options[:type].blank?
212
- request_hash['LaunchGroup'] = options[:launch_group] unless options[:launch_group].blank?
213
- request_hash['AvailabilityZoneGroup'] = options[:availability_zone_group] unless options[:availability_zone_group].blank?
214
- request_hash['LaunchSpecification.KeyName'] = options[:key_name] unless options[:key_name].blank?
215
- request_hash['LaunchSpecification.AddressingType'] = options[:addressing_type] unless options[:addressing_type].blank?
216
- request_hash['LaunchSpecification.KernelId'] = options[:kernel_id] unless options[:kernel_id].blank?
217
- request_hash['LaunchSpecification.RamdiskId'] = options[:ramdisk_id] unless options[:ramdisk_id].blank?
218
- request_hash['LaunchSpecification.SubnetId'] = options[:subnet_id] unless options[:subnet_id].blank?
219
- request_hash['LaunchSpecification.Placement.AvailabilityZone'] = options[:availability_zone] unless options[:availability_zone].blank?
220
- request_hash['LaunchSpecification.Monitoring.Enabled'] = options[:monitoring_enabled] unless options[:monitoring_enabled].blank?
221
- request_hash.merge!(amazonize_list('LaunchSpecification.SecurityGroup', options[:groups])) unless options[:groups].blank?
230
+ request_hash['ValidFrom'] = AwsUtils::utc_iso8601(options[:valid_from]) unless options[:valid_from].right_blank?
231
+ request_hash['ValidUntil'] = AwsUtils::utc_iso8601(options[:valid_until]) unless options[:valid_until].right_blank?
232
+ request_hash['InstanceCount'] = options[:instance_count] unless options[:instance_count].right_blank?
233
+ request_hash['Type'] = options[:type] unless options[:type].right_blank?
234
+ request_hash['LaunchGroup'] = options[:launch_group] unless options[:launch_group].right_blank?
235
+ request_hash['AvailabilityZoneGroup'] = options[:availability_zone_group] unless options[:availability_zone_group].right_blank?
236
+ request_hash['LaunchSpecification.KeyName'] = options[:key_name] unless options[:key_name].right_blank?
237
+ request_hash['LaunchSpecification.AddressingType'] = options[:addressing_type] unless options[:addressing_type].right_blank?
238
+ request_hash['LaunchSpecification.KernelId'] = options[:kernel_id] unless options[:kernel_id].right_blank?
239
+ request_hash['LaunchSpecification.RamdiskId'] = options[:ramdisk_id] unless options[:ramdisk_id].right_blank?
240
+ request_hash['LaunchSpecification.SubnetId'] = options[:subnet_id] unless options[:subnet_id].right_blank?
241
+ request_hash['LaunchSpecification.Placement.AvailabilityZone'] = options[:availability_zone] unless options[:availability_zone].right_blank?
242
+ request_hash['LaunchSpecification.Monitoring.Enabled'] = options[:monitoring_enabled] unless options[:monitoring_enabled].right_blank?
243
+ request_hash.merge!(amazonize_list('LaunchSpecification.SecurityGroup', options[:groups])) unless options[:groups].right_blank?
222
244
  request_hash.merge!(amazonize_block_device_mappings(options[:block_device_mappings], 'LaunchSpecification.BlockDeviceMapping'))
223
- unless options[:user_data].blank?
245
+ unless options[:user_data].right_blank?
224
246
  # See RightAws::Ec2#run_instances
225
247
  options[:user_data].strip!
226
- request_hash['LaunchSpecification.UserData'] = Base64.encode64(options[:user_data]).delete("\n") unless options[:user_data].blank?
248
+ request_hash['LaunchSpecification.UserData'] = Base64.encode64(options[:user_data]).delete("\n") unless options[:user_data].right_blank?
227
249
  end
228
250
  link = generate_request("RequestSpotInstances", request_hash)
229
251
  request_info(link, QEc2DescribeSpotInstanceParser.new(:logger => @logger))
@@ -253,7 +275,7 @@ module RightAws
253
275
  #
254
276
  def create_spot_datafeed_subscription(bucket, prefix=nil)
255
277
  request_hash = { 'Bucket' => bucket }
256
- request_hash['Prefix'] = prefix unless prefix.blank?
278
+ request_hash['Prefix'] = prefix unless prefix.right_blank?
257
279
  link = generate_request("CreateSpotDatafeedSubscription", request_hash)
258
280
  request_info(link, QEc2DescribeSpotDatafeedSubscriptionParser.new(:logger => @logger))
259
281
  end
@@ -306,10 +328,12 @@ module RightAws
306
328
  def tagstart(name, attributes)
307
329
  case full_tag_name
308
330
  when %r{spotInstanceRequestSet/item$}
309
- @item = {}
331
+ @item = { :tags => {} }
310
332
  when %r{/blockDeviceMapping/item$}
311
333
  @item[:block_device_mappings] ||= []
312
334
  @block_device_mapping = {}
335
+ when %r{/tagSet/item$}
336
+ @aws_tag = {}
313
337
  end
314
338
  end
315
339
  def tagend(name)
@@ -351,8 +375,10 @@ module RightAws
351
375
  when 'deleteOnTermination' then @block_device_mapping[:ebs_delete_on_termination] = @text == 'true' ? true : false
352
376
  when 'item' then @item[:block_device_mappings] << @block_device_mapping
353
377
  end
354
- when %r{spotInstanceRequestSet/item$}
355
- @result << @item
378
+ when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
379
+ when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
380
+ when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
381
+ when %r{spotInstanceRequestSet/item$} then @result << @item
356
382
  end
357
383
  end
358
384
  end