ktheory-right_aws 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/History.txt +284 -0
  2. data/Manifest.txt +50 -0
  3. data/README.txt +167 -0
  4. data/Rakefile +110 -0
  5. data/lib/acf/right_acf_interface.rb +485 -0
  6. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  7. data/lib/acf/right_acf_streaming_interface.rb +236 -0
  8. data/lib/acw/right_acw_interface.rb +249 -0
  9. data/lib/as/right_as_interface.rb +699 -0
  10. data/lib/awsbase/benchmark_fix.rb +39 -0
  11. data/lib/awsbase/right_awsbase.rb +978 -0
  12. data/lib/awsbase/support.rb +115 -0
  13. data/lib/ec2/right_ec2.rb +395 -0
  14. data/lib/ec2/right_ec2_ebs.rb +452 -0
  15. data/lib/ec2/right_ec2_images.rb +373 -0
  16. data/lib/ec2/right_ec2_instances.rb +755 -0
  17. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  18. data/lib/ec2/right_ec2_reserved_instances.rb +170 -0
  19. data/lib/ec2/right_ec2_security_groups.rb +277 -0
  20. data/lib/ec2/right_ec2_spot_instances.rb +399 -0
  21. data/lib/ec2/right_ec2_vpc.rb +571 -0
  22. data/lib/elb/right_elb_interface.rb +496 -0
  23. data/lib/rds/right_rds_interface.rb +998 -0
  24. data/lib/right_aws.rb +83 -0
  25. data/lib/s3/right_s3.rb +1126 -0
  26. data/lib/s3/right_s3_interface.rb +1199 -0
  27. data/lib/sdb/active_sdb.rb +1122 -0
  28. data/lib/sdb/right_sdb_interface.rb +721 -0
  29. data/lib/sqs/right_sqs.rb +388 -0
  30. data/lib/sqs/right_sqs_gen2.rb +343 -0
  31. data/lib/sqs/right_sqs_gen2_interface.rb +524 -0
  32. data/lib/sqs/right_sqs_interface.rb +594 -0
  33. data/test/acf/test_helper.rb +2 -0
  34. data/test/acf/test_right_acf.rb +138 -0
  35. data/test/ec2/test_helper.rb +2 -0
  36. data/test/ec2/test_right_ec2.rb +108 -0
  37. data/test/http_connection.rb +87 -0
  38. data/test/rds/test_helper.rb +2 -0
  39. data/test/rds/test_right_rds.rb +120 -0
  40. data/test/s3/test_helper.rb +2 -0
  41. data/test/s3/test_right_s3.rb +421 -0
  42. data/test/s3/test_right_s3_stubbed.rb +97 -0
  43. data/test/sdb/test_active_sdb.rb +357 -0
  44. data/test/sdb/test_helper.rb +3 -0
  45. data/test/sdb/test_right_sdb.rb +253 -0
  46. data/test/sqs/test_helper.rb +2 -0
  47. data/test/sqs/test_right_sqs.rb +291 -0
  48. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  49. data/test/test_credentials.rb +37 -0
  50. data/test/ts_right_aws.rb +14 -0
  51. metadata +184 -0
@@ -0,0 +1,699 @@
1
+ #
2
+ # Copyright (c) 2007-2009 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ module RightAws
25
+
26
+ # = RightAWS::AsInterface -- RightScale Amazon Auto Scaling interface
27
+ # The RightAws::AsInterface class provides a complete interface to Amazon Auto Scaling service.
28
+ #
29
+ # For explanations of the semantics of each call, please refer to Amazon's documentation at
30
+ # http://docs.amazonwebservices.com/AutoScaling/latest/DeveloperGuide/
31
+ #
32
+ # Create an interface handle:
33
+ #
34
+ # as = RightAws::AsInterface.new(aws_access_key_id, aws_security_access_key)
35
+ #
36
+ # Create a launch configuration:
37
+ #
38
+ # as.create_launch_configuration('CentOS.5.1-c', 'ami-08f41161', 'm1.small',
39
+ # :key_name => 'kd-moo-test',
40
+ # :security_groups => ['default'],
41
+ # :user_data => "Woohoo: CentOS.5.1-c" )
42
+ #
43
+ # Create an AutoScaling group:
44
+ #
45
+ # as.create_auto_scaling_group('CentOS.5.1-c-array', 'CentOS.5.1-c', 'us-east-1c',
46
+ # :min_size => 2,
47
+ # :max_size => 5)
48
+ #
49
+ # Create a new trigger:
50
+ #
51
+ # as.create_or_update_scaling_trigger('kd.tr.1', 'CentOS.5.1-c-array',
52
+ # :measure_name => 'CPUUtilization',
53
+ # :statistic => :average,
54
+ # :dimensions => {
55
+ # 'AutoScalingGroupName' => 'CentOS.5.1-c-array',
56
+ # 'Namespace' => 'AWS',
57
+ # 'Service' => 'EC2' },
58
+ # :period => 60,
59
+ # :lower_threshold => 5,
60
+ # :lower_breach_scale_increment => -1,
61
+ # :upper_threshold => 60,
62
+ # :upper_breach_scale_increment => 1,
63
+ # :breach_duration => 300 )
64
+ #
65
+ # Describe scaling activity:
66
+ #
67
+ # as.incrementally_describe_scaling_activities('CentOS.5.1-c-array') #=> List of activities
68
+ #
69
+ # Describe the Auto Scaling group status:
70
+ #
71
+ # as.describe_auto_scaling_groups('CentOS.5.1-c-array') #=> Current group status
72
+ #
73
+ class AsInterface < RightAwsBase
74
+ include RightAwsBaseInterface
75
+
76
+ # Amazon AS API version being used
77
+ API_VERSION = '2009-05-15'
78
+ DEFAULT_HOST = 'autoscaling.amazonaws.com'
79
+ DEFAULT_PATH = '/'
80
+ DEFAULT_PROTOCOL = 'https'
81
+ DEFAULT_PORT = 443
82
+
83
+ @@bench = AwsBenchmarkingBlock.new
84
+ def self.bench_xml
85
+ @@bench.xml
86
+ end
87
+ def self.bench_service
88
+ @@bench.service
89
+ end
90
+
91
+ # Create a new handle to an CSLS account. All handles share the same per process or per thread
92
+ # HTTP connection to Amazon CSLS. Each handle is for a specific account. The params have the
93
+ # following options:
94
+ # * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol). Example: 'https://autoscaling.amazonaws.com/'
95
+ # * <tt>:server</tt>: AS service host, default: DEFAULT_HOST
96
+ # * <tt>:port</tt>: AS service port, default: DEFAULT_PORT
97
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
98
+ # * <tt>:multi_thread</tt>: true=HTTP connection per thread, false=per process
99
+ # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
100
+ # * <tt>:signature_version</tt>: The signature version : '0','1' or '2'(default)
101
+ # * <tt>:cache</tt>: true/false(default): describe_auto_scaling_groups
102
+ #
103
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
104
+ init({ :name => 'AS',
105
+ :default_host => ENV['AS_URL'] ? URI.parse(ENV['AS_URL']).host : DEFAULT_HOST,
106
+ :default_port => ENV['AS_URL'] ? URI.parse(ENV['AS_URL']).port : DEFAULT_PORT,
107
+ :default_service => ENV['AS_URL'] ? URI.parse(ENV['AS_URL']).path : DEFAULT_PATH,
108
+ :default_protocol => ENV['AS_URL'] ? URI.parse(ENV['AS_URL']).scheme : DEFAULT_PROTOCOL,
109
+ :default_api_version => ENV['AS_API_VERSION'] || API_VERSION },
110
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'] ,
111
+ aws_secret_access_key|| ENV['AWS_SECRET_ACCESS_KEY'],
112
+ params)
113
+ end
114
+
115
+ def generate_request(action, params={}) #:nodoc:
116
+ generate_request_impl(:get, action, params )
117
+ end
118
+
119
+ # Sends request to Amazon and parses the response
120
+ # Raises AwsError if any banana happened
121
+ def request_info(request, parser) #:nodoc:
122
+ request_info_impl(:aass_connection, @@bench, request, parser)
123
+ end
124
+
125
+ #-----------------------------------------------------------------
126
+ # Auto Scaling Groups
127
+ #-----------------------------------------------------------------
128
+
129
+ # Describe auto scaling groups.
130
+ # Returns a full description of the AutoScalingGroups from the given list.
131
+ # This includes all EC2 instances that are members of the group. If a list
132
+ # of names is not provided, then the full details of all AutoScalingGroups
133
+ # is returned. This style conforms to the EC2 DescribeInstances API behavior.
134
+ #
135
+ def describe_auto_scaling_groups(*auto_scaling_group_names)
136
+ auto_scaling_group_names = auto_scaling_group_names.flatten.compact
137
+ request_hash = amazonize_list('AutoScalingGroupNames.member', auto_scaling_group_names)
138
+ link = generate_request("DescribeAutoScalingGroups", request_hash)
139
+ request_cache_or_info(:describe_auto_scaling_groups, link, DescribeAutoScalingGroupsParser, @@bench, auto_scaling_group_names.blank?)
140
+ end
141
+
142
+ # Creates a new auto scaling group with the specified name.
143
+ # Returns +true+ or raises an exception.
144
+ #
145
+ # Options: +:min_size+, +:max_size+, +:cooldown+, +:load_balancer_names+
146
+ #
147
+ # as.create_auto_scaling_group('CentOS.5.1-c-array', 'CentOS.5.1-c', 'us-east-1c',
148
+ # :min_size => 2,
149
+ # :max_size => 5) #=> true
150
+ #
151
+ # Amazon's notice: Constraints: Restricted to one Availability Zone
152
+ def create_auto_scaling_group(auto_scaling_group_name, launch_configuration_name, availability_zones, options={})
153
+ options[:min_size] ||= 1
154
+ options[:max_size] ||= 20
155
+ options[:cooldown] ||= 0
156
+ request_hash = amazonize_list('AvailabilityZones.member', availability_zones)
157
+ request_hash.merge!( amazonize_list('LoadBalancerNames.member', options[:load_balancer_names]) )
158
+ request_hash.merge!( 'AutoScalingGroupName' => auto_scaling_group_name,
159
+ 'LaunchConfigurationName' => launch_configuration_name,
160
+ 'MinSize' => options[:min_size],
161
+ 'MaxSize' => options[:max_size],
162
+ 'Cooldown' => options[:cooldown] )
163
+ link = generate_request("CreateAutoScalingGroup", request_hash)
164
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
165
+ end
166
+
167
+ # Deletes all configuration for this auto scaling group and also deletes the group.
168
+ # Returns +true+ or raises an exception.
169
+ #
170
+ def delete_auto_scaling_group(auto_scaling_group_name)
171
+ link = generate_request('DeleteAutoScalingGroup', 'AutoScalingGroupName' => auto_scaling_group_name)
172
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
173
+ end
174
+
175
+ # Adjusts the desired size of the Capacity Group by using scaling actions, as necessary. When
176
+ # adjusting the size of the group downward, it is not possible to define which EC2 instances will be
177
+ # terminated. This also applies to any auto-scaling decisions that might result in the termination of
178
+ # instances.
179
+ #
180
+ # Returns +true+ or raises an exception.
181
+ #
182
+ # as.set_desired_capacity('CentOS.5.1-c',3) #=> 3
183
+ #
184
+ def set_desired_capacity(auto_scaling_group_name, desired_capacity)
185
+ link = generate_request('SetDesiredCapacity', 'AutoScalingGroupName' => auto_scaling_group_name,
186
+ 'DesiredCapacity' => desired_capacity )
187
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
188
+ end
189
+
190
+ # Updates the configuration for the given AutoScalingGroup. If MaxSize is lower than the current size,
191
+ # then there will be an implicit call to SetDesiredCapacity to set the group to the new MaxSize. The
192
+ # same is true for MinSize there will also be an implicit call to SetDesiredCapacity. All optional
193
+ # parameters are left unchanged if not passed in the request.
194
+ #
195
+ # The new settings are registered upon the completion of this call. Any launch configuration settings
196
+ # will take effect on any triggers after this call returns. However, triggers that are currently in
197
+ # progress can not be affected. See key term Trigger.
198
+ #
199
+ # Returns +true+ or raises an exception.
200
+ #
201
+ # Options: +:launch_configuration_name+, +:min_size+, +:max_size+, +:cooldown+, +:availability_zones+.
202
+ # (Amazon's notice: +:availability_zones+ is reserved for future use.)
203
+ #
204
+ # as.update_auto_scaling_group('CentOS.5.1-c', :min_size => 1, :max_size => 4) #=> true
205
+ #
206
+ def update_auto_scaling_group(auto_scaling_group_name, options={})
207
+ request_hash = amazonize_list('AvailabilityZones.member', options[:availability_zones])
208
+ request_hash['AutoScalingGroupName'] = auto_scaling_group_name
209
+ request_hash['LaunchConfigurationName'] = options[:launch_configuration_name] if options[:launch_configuration_name]
210
+ request_hash['MinSize'] = options[:min_size] if options[:min_size]
211
+ request_hash['MaxSize'] = options[:max_size] if options[:max_size]
212
+ request_hash['Cooldown'] = options[:cooldown] if options[:cooldown]
213
+ link = generate_request("UpdateAutoScalingGroup", request_hash)
214
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
215
+ end
216
+
217
+ #-----------------------------------------------------------------
218
+ # Scaling Activities
219
+ #-----------------------------------------------------------------
220
+
221
+ # Describe all Scaling Activities.
222
+ #
223
+ # describe_scaling_activities('CentOS.5.1-c-array') #=>
224
+ # [{:cause=>
225
+ # "At 2009-05-28 10:11:35Z trigger kd.tr.1 breached high threshold value for
226
+ # CPUUtilization, 10.0, adjusting the desired capacity from 1 to 2. At 2009-05-28 10:11:35Z
227
+ # a breaching trigger explicitly set group desired capacity changing the desired capacity
228
+ # from 1 to 2. At 2009-05-28 10:11:40Z an instance was started in response to a difference
229
+ # between desired and actual capacity, increasing the capacity from 1 to 2.",
230
+ # :activity_id=>"067c9abb-f8a7-4cf8-8f3c-dc6f280457c4",
231
+ # :progress=>0,
232
+ # :description=>"Launching a new EC2 instance",
233
+ # :status_code=>"InProgress",
234
+ # :start_time=>Thu May 28 10:11:40 UTC 2009},
235
+ # {:end_time=>Thu May 28 09:35:23 UTC 2009,
236
+ # :cause=>
237
+ # "At 2009-05-28 09:31:21Z a user request created an AutoScalingGroup changing the desired
238
+ # capacity from 0 to 1. At 2009-05-28 09:32:35Z an instance was started in response to a
239
+ # difference between desired and actual capacity, increasing the capacity from 0 to 1.",
240
+ # :activity_id=>"90d506ba-1b75-4d29-8739-0a75b1ba8030",
241
+ # :progress=>100,
242
+ # :description=>"Launching a new EC2 instance",
243
+ # :status_code=>"Successful",
244
+ # :start_time=>Thu May 28 09:32:35 UTC 2009}]}
245
+ #
246
+ def describe_scaling_activities(auto_scaling_group_name, *activity_ids)
247
+ result = []
248
+ incrementally_describe_scaling_activities(auto_scaling_group_name, *activity_ids) do |response|
249
+ result += response[:scaling_activities]
250
+ true
251
+ end
252
+ result
253
+ end
254
+
255
+ # Incrementally describe Scaling Activities.
256
+ # Returns the scaling activities specified for the given group. If the input list is empty, all the
257
+ # activities from the past six weeks will be returned. Activities will be sorted by completion time.
258
+ # Activities that have no completion time will be considered as using the most recent possible time.
259
+ #
260
+ # Optional params: +:max_records+, +:next_token+.
261
+ #
262
+ # # get max 100 first activities
263
+ # as.incrementally_describe_scaling_activities('CentOS.5.1-c-array') #=>
264
+ # {:scaling_activities=>
265
+ # [{:cause=>
266
+ # "At 2009-05-28 10:11:35Z trigger kd.tr.1 breached high threshold value for
267
+ # CPUUtilization, 10.0, adjusting the desired capacity from 1 to 2. At 2009-05-28 10:11:35Z
268
+ # a breaching trigger explicitly set group desired capacity changing the desired capacity
269
+ # from 1 to 2. At 2009-05-28 10:11:40Z an instance was started in response to a difference
270
+ # between desired and actual capacity, increasing the capacity from 1 to 2.",
271
+ # :activity_id=>"067c9abb-f8a7-4cf8-8f3c-dc6f280457c4",
272
+ # :progress=>0,
273
+ # :description=>"Launching a new EC2 instance",
274
+ # :status_code=>"InProgress",
275
+ # :start_time=>Thu May 28 10:11:40 UTC 2009},
276
+ # {:end_time=>Thu May 28 09:35:23 UTC 2009,
277
+ # :cause=>
278
+ # "At 2009-05-28 09:31:21Z a user request created an AutoScalingGroup changing the desired
279
+ # capacity from 0 to 1. At 2009-05-28 09:32:35Z an instance was started in response to a
280
+ # difference between desired and actual capacity, increasing the capacity from 0 to 1.",
281
+ # :activity_id=>"90d506ba-1b75-4d29-8739-0a75b1ba8030",
282
+ # :progress=>100,
283
+ # :description=>"Launching a new EC2 instance",
284
+ # :status_code=>"Successful",
285
+ # :start_time=>Thu May 28 09:32:35 UTC 2009}]}
286
+ #
287
+ # # list by 5 records
288
+ # incrementally_describe_scaling_activities('CentOS.5.1-c-array', :max_records => 5) do |response|
289
+ # puts response.inspect
290
+ # true
291
+ # end
292
+ #
293
+ def incrementally_describe_scaling_activities(auto_scaling_group_name, *activity_ids, &block)
294
+ activity_ids = activity_ids.flatten.compact
295
+ params = activity_ids.last.kind_of?(Hash) ? activity_ids.pop : {}
296
+ request_hash = amazonize_list('ActivityIds.member', activity_ids)
297
+ request_hash['AutoScalingGroupName'] = auto_scaling_group_name
298
+ request_hash['MaxRecords'] = params[:max_records] if params[:max_records]
299
+ request_hash['NextToken'] = params[:next_token] if params[:next_token]
300
+ last_response = nil
301
+ loop do
302
+ link = generate_request("DescribeScalingActivities", request_hash)
303
+ last_response = request_info( link, DescribeScalingActivitiesParser.new(:logger => @logger))
304
+ request_hash['NextToken'] = last_response[:next_token]
305
+ break unless block && block.call(last_response) && !last_response[:next_token].blank?
306
+ end
307
+ last_response
308
+ end
309
+
310
+ #-----------------------------------------------------------------
311
+ # Instance and Instance Workflow Operations
312
+ #-----------------------------------------------------------------
313
+
314
+ # This call will terminate the specified Instance. Optionally, the desired group size can be adjusted.
315
+ # If set to true, the default, the AutoScalingGroup size will decrease by one. If the AutoScalingGroup
316
+ # is associated with a LoadBalancer, the system will deregister the instance before terminating it.
317
+ # This call simply registers a termination request. The termination of the instance can not happen
318
+ # immediately.
319
+ #
320
+ # Returns the activity to terminate the instance.
321
+ #
322
+ def terminate_instance_in_auto_scaling_group(instance_id, should_decrement_desired_capacity=true)
323
+ request_hash = { 'InstanceId' => instance_id }
324
+ request_hash['ShouldDecrementDesiredCapacity'] = should_decrement_desired_capacity
325
+ link = generate_request('TerminateInstanceInAutoScalingGroup', request_hash )
326
+ request_info(link, DescribeScalingActivitiesParser.new(:logger => @logger))[:scaling_activities].first
327
+ end
328
+
329
+ #-----------------------------------------------------------------
330
+ # Launch Configuration Operations
331
+ #-----------------------------------------------------------------
332
+
333
+ # Creates a new Launch Configuration. Please note that the launch configuration name used must
334
+ # be unique, within the scope of your Amazon Web Services AWS account, and the maximum limit of
335
+ # launch configurations must not yet have been met, or else the call will fail.
336
+ #
337
+ # Once created, the new launch configuration is available for immediate use.
338
+ #
339
+ # Options: +:security_groups+, +:block_device_mappings+, +:key_name+,
340
+ # +:user_data+, +:kernel_id+, +:ramdisk_id+
341
+ #
342
+ # as.create_launch_configuration('kd: CentOS.5.1-c.1', 'ami-08f41161', 'c1.medium',
343
+ # :key_name => 'tim',
344
+ # :security_groups => ['default'],
345
+ # :user_data => "Woohoo: CentOS.5.1-c",
346
+ # :block_device_mappings => [ { :device_name => '/dev/sdk',
347
+ # :ebs_snapshot_id => 'snap-145cbc7d',
348
+ # :ebs_delete_on_termination => true,
349
+ # :ebs_volume_size => 3,
350
+ # :virtual_name => 'ephemeral2'
351
+ # } ]
352
+ # ) #=> true
353
+ #
354
+ def create_launch_configuration(launch_configuration_name, image_id, instance_type, options={})
355
+ request_hash = { 'LaunchConfigurationName' => launch_configuration_name,
356
+ 'ImageId' => image_id,
357
+ 'InstanceType' => instance_type }
358
+ request_hash.merge!(amazonize_list('SecurityGroups.member', options[:security_groups])) unless options[:security_groups].blank?
359
+ request_hash.merge!(amazonize_block_device_mappings(options[:block_device_mappings], 'BlockDeviceMappings.member'))
360
+ request_hash['KeyName'] = options[:key_name] if options[:key_name]
361
+ request_hash['UserData'] = Base64.encode64(options[:user_data]).delete("\n") unless options[:user_data].blank? if options[:user_data]
362
+ request_hash['KernelId'] = options[:kernel_id] if options[:kernel_id]
363
+ request_hash['RamdiskId'] = options[:ramdisk_id] if options[:ramdisk_id]
364
+ link = generate_request("CreateLaunchConfiguration", request_hash)
365
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
366
+ end
367
+
368
+
369
+ # Describe all Launch Configurations.
370
+ # Returns an array of configurations.
371
+ #
372
+ # as.describe_launch_configurations #=>
373
+ # [{:security_groups=>["default"],
374
+ # :ramdisk_id=>"",
375
+ # :user_data=>"V29vaG9vOiBDZW50T1MuNS4xLWM=",
376
+ # :instance_type=>"c1.medium",
377
+ # :block_device_mappings=>
378
+ # [{:virtual_name=>"ephemeral2", :device_name=>"/dev/sdk"}],
379
+ # :launch_configuration_name=>"kd: CentOS.5.1-c.1",
380
+ # :created_time=>"2010-03-29T10:00:32.742Z",
381
+ # :image_id=>"ami-08f41161",
382
+ # :key_name=>"tim",
383
+ # :kernel_id=>""}, ...]
384
+ #
385
+ def describe_launch_configurations(*launch_configuration_names)
386
+ result = []
387
+ incrementally_describe_launch_configurations(*launch_configuration_names) do |response|
388
+ result += response[:launch_configurations]
389
+ true
390
+ end
391
+ result
392
+ end
393
+
394
+ # Incrementally describe Launch Configurations.
395
+ # Returns a full description of the launch configurations given the specified names. If no names
396
+ # are specified, then the full details of all launch configurations are returned.
397
+ #
398
+ # Optional params: +:max_records+, +:next_token+.
399
+ #
400
+ # # get max 100 first configurations
401
+ # as.incrementally_describe_launch_configurations #=>
402
+ # {:launch_configurations=>
403
+ # [{:created_time=>Thu May 28 09:31:20 UTC 2009,
404
+ # :kernel_id=>"",
405
+ # :launch_configuration_name=>"CentOS.5.1-c",
406
+ # :ramdisk_id=>"",
407
+ # :security_groups=>["default"],
408
+ # :key_name=>"kd-moo-test",
409
+ # :user_data=>"Woohoo: CentOS.5.1-c-array",
410
+ # :image_id=>"ami-08f41161",
411
+ # :block_device_mappings=>[],
412
+ # :instance_type=>"m1.small"}, ... ]}
413
+ #
414
+ # # list by 5 records
415
+ # incrementally_describe_launch_configurations(:max_records => 5) do |response|
416
+ # puts response.inspect
417
+ # true
418
+ # end
419
+ #
420
+ def incrementally_describe_launch_configurations(*launch_configuration_names, &block)
421
+ launch_configuration_names = launch_configuration_names.flatten.compact
422
+ params = launch_configuration_names.last.kind_of?(Hash) ? launch_configuration_names.pop : {}
423
+ request_hash = amazonize_list('LaunchConfigurationNames.member', launch_configuration_names)
424
+ request_hash['MaxRecords'] = params[:max_records] if params[:max_records]
425
+ request_hash['NextToken'] = params[:next_token] if params[:next_token]
426
+ last_response = nil
427
+ loop do
428
+ link = generate_request("DescribeLaunchConfigurations", request_hash)
429
+ last_response = request_info( link, DescribeLaunchConfigurationsParser.new(:logger => @logger) )
430
+ request_hash['NextToken'] = last_response[:next_token]
431
+ break unless block && block.call(last_response) && !last_response[:next_token].blank?
432
+ end
433
+ last_response
434
+ end
435
+
436
+ # Delete launch configuration.
437
+ # Returns +true+ or an exception.
438
+ #
439
+ # as.delete_launch_configuration('CentOS.5.1') #=> true
440
+ #
441
+ def delete_launch_configuration(launch_configuration_name)
442
+ link = generate_request('DeleteLaunchConfiguration', 'LaunchConfigurationName' => launch_configuration_name)
443
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
444
+ end
445
+
446
+ #-----------------------------------------------------------------
447
+ # Trigger Operations
448
+ #-----------------------------------------------------------------
449
+
450
+ # Create or update specified trigger.
451
+ # This call sets the parameters that governs when and how to scale an AutoScalingGroup.
452
+ # If the Trigger, within the scope of the caller's AWS account, specified already exists,
453
+ # it will be updated. If a trigger with a different name already exists, this call will fail.
454
+ #
455
+ # Returns +true+ or an exception.
456
+ #
457
+ # Options: +:measure_name+, +:statistic+, +:period+, +:lower_threshold+, +:lower_breach_scale_increment+,
458
+ # +:upper_threshold+, +:upper_breach_scale_increment+, +:dimensions+, +:breach_duration+, +:unit+, +:custom_unit+
459
+ #
460
+ # as.create_or_update_scaling_trigger('kd.tr.1', 'CentOS.5.1-c-array',
461
+ # :measure_name => 'CPUUtilization',
462
+ # :statistic => :average,
463
+ # :dimensions => {
464
+ # 'AutoScalingGroupName' => 'CentOS.5.1-c-array',
465
+ # 'Namespace' => 'AWS',
466
+ # 'Service' => 'EC2' },
467
+ # :period => 60,
468
+ # :lower_threshold => 5,
469
+ # :lower_breach_scale_increment => -1,
470
+ # :upper_threshold => 60,
471
+ # :upper_breach_scale_increment => 1,
472
+ # :breach_duration => 300 ) #=> true
473
+ #
474
+ def create_or_update_scaling_trigger(trigger_name, auto_scaling_group_name, options={})
475
+ request_hash = { 'TriggerName' => trigger_name,
476
+ 'AutoScalingGroupName' => auto_scaling_group_name,
477
+ 'MeasureName' => options[:measure_name],
478
+ 'Statistic' => options[:statistic].to_s.capitalize,
479
+ 'Period' => options[:period],
480
+ 'LowerThreshold' => options[:lower_threshold],
481
+ 'LowerBreachScaleIncrement' => options[:lower_breach_scale_increment],
482
+ 'UpperThreshold' => options[:upper_threshold],
483
+ 'UpperBreachScaleIncrement' => options[:upper_breach_scale_increment],
484
+ 'BreachDuration' => options[:breach_duration] }
485
+ request_hash['Unit'] = options[:unit] if options[:unit]
486
+ request_hash['CustomUnit'] = options[:custom_unit] if options[:custom_unit]
487
+ dimensions = []
488
+ (options[:dimensions] || {}).each do |key, values|
489
+ Array(values).each { |value| dimensions << [key, value] }
490
+ end
491
+ request_hash.merge!(amazonize_list(['Dimensions.member.?.Name', 'Dimensions.member.?.Value'], dimensions))
492
+ link = generate_request("CreateOrUpdateScalingTrigger", request_hash)
493
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
494
+ end
495
+
496
+ # Describe triggers.
497
+ # Returns a full description of the trigger in the specified Auto Scaling Group.
498
+ #
499
+ # as.describe_triggers('CentOS.5.1-c-array') #=>
500
+ # [{:status=>"HighBreaching",
501
+ # :breach_duration=>300,
502
+ # :measure_name=>"CPUUtilization",
503
+ # :trigger_name=>"kd.tr.1",
504
+ # :period=>60,
505
+ # :lower_threshold=>0.0,
506
+ # :lower_breach_scale_increment=>-1,
507
+ # :dimensions=>
508
+ # {"Namespace"=>"AWS",
509
+ # "AutoScalingGroupName"=>"CentOS.5.1-c-array",
510
+ # "Service"=>"EC2"},
511
+ # :statistic=>"Average",
512
+ # :upper_threshold=>10.0,
513
+ # :created_time=>Thu May 28 09:48:46 UTC 2009,
514
+ # :auto_scaling_group_name=>"CentOS.5.1-c-array",
515
+ # :upper_breach_scale_increment=>1}]
516
+ #
517
+ def describe_triggers(auto_scaling_group_name)
518
+ link = generate_request("DescribeTriggers", 'AutoScalingGroupName' => auto_scaling_group_name)
519
+ request_info(link, DescribeTriggersParser.new(:logger => @logger))
520
+ end
521
+
522
+ # Delete specified trigger.
523
+ # Returns +true+ or an exception.
524
+ #
525
+ # as.delete_trigger('kd.tr.1', 'CentOS.5.1-c-array') #=> true
526
+ #
527
+ def delete_trigger(trigger_name, auto_scaling_group_name)
528
+ link = generate_request('DeleteTrigger', 'TriggerName' => trigger_name,
529
+ 'AutoScalingGroupName' => auto_scaling_group_name)
530
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
531
+ end
532
+
533
+ #-----------------------------------------------------------------
534
+ # PARSERS: Scaling Activity
535
+ #-----------------------------------------------------------------
536
+
537
+ class DescribeScalingActivitiesParser < RightAWSParser #:nodoc:
538
+ def tagstart(name, attributes)
539
+ case name
540
+ when 'member', 'Activity' then @item = {}
541
+ end
542
+ end
543
+ def tagend(name)
544
+ case name
545
+ when 'ActivityId' then @item[:activity_id] = @text
546
+ when 'StartTime' then @item[:start_time] = @text
547
+ when 'EndTime' then @item[:end_time] = @text
548
+ when 'Progress' then @item[:progress] = @text.to_i
549
+ when 'StatusCode' then @item[:status_code] = @text
550
+ when 'Cause' then @item[:cause] = @text
551
+ when 'Description' then @item[:description] = @text
552
+ when 'member', 'Activity' then @result[:scaling_activities] << @item
553
+ when 'NextToken' then @result[:next_token] = @text
554
+ end
555
+ end
556
+ def reset
557
+ @result = { :scaling_activities => []}
558
+ end
559
+ end
560
+
561
+ #-----------------------------------------------------------------
562
+ # PARSERS: Auto Scaling Groups
563
+ #-----------------------------------------------------------------
564
+
565
+ class DescribeAutoScalingGroupsParser < RightAWSParser #:nodoc:
566
+ def tagstart(name, attributes)
567
+ case name
568
+ when 'member'
569
+ case @xmlpath
570
+ when @p then @item = { :instances => [ ],
571
+ :availability_zones => [],
572
+ :load_balancer_names => [] }
573
+ when "#@p/member/Instances" then @instance = { }
574
+ end
575
+ end
576
+ end
577
+ def tagend(name)
578
+ case name
579
+ when 'CreatedTime' then @item[:created_time] = @text
580
+ when 'MinSize' then @item[:min_size] = @text.to_i
581
+ when 'MaxSize' then @item[:max_size] = @text.to_i
582
+ when 'DesiredCapacity' then @item[:desired_capacity] = @text.to_i
583
+ when 'Cooldown' then @item[:cooldown] = @text.to_i
584
+ when 'LaunchConfigurationName' then @item[:launch_configuration_name] = @text
585
+ when 'AutoScalingGroupName' then @item[:auto_scaling_group_name] = @text
586
+ when 'InstanceId' then @instance[:instance_id] = @text
587
+ when 'LifecycleState' then @instance[:lifecycle_state] = @text
588
+ when 'AvailabilityZone' then @instance[:availability_zone] = @text
589
+ when 'member'
590
+ case @xmlpath
591
+ when @p then
592
+ @item[:availability_zones].sort!
593
+ @result << @item
594
+ when "#@p/member/AvailabilityZones" then @item[:availability_zones] << @text
595
+ when "#@p/member/LoadBalancerNames" then @item[:load_balancer_names] << @text
596
+ when "#@p/member/Instances" then @item[:instances] << @instance
597
+ end
598
+ end
599
+ end
600
+ def reset
601
+ @p = 'DescribeAutoScalingGroupsResponse/DescribeAutoScalingGroupsResult/AutoScalingGroups'
602
+ @result = []
603
+ end
604
+ end
605
+
606
+ #-----------------------------------------------------------------
607
+ # PARSERS: Launch Configurations
608
+ #-----------------------------------------------------------------
609
+
610
+ class DescribeLaunchConfigurationsParser < RightAWSParser #:nodoc:
611
+ def tagstart(name, attributes)
612
+ case full_tag_name
613
+ when %r{/LaunchConfigurations/member$}
614
+ @item = { :block_device_mappings => [],
615
+ :security_groups => [] }
616
+ when %r{/BlockDeviceMappings/member$}
617
+ @block_device_mapping = {}
618
+ end
619
+ end
620
+ def tagend(name)
621
+ case name
622
+ when 'CreatedTime' then @item[:created_time] = @text
623
+ when 'InstanceType' then @item[:instance_type] = @text
624
+ when 'KeyName' then @item[:key_name] = @text
625
+ when 'ImageId' then @item[:image_id] = @text
626
+ when 'KernelId' then @item[:kernel_id] = @text
627
+ when 'RamdiskId' then @item[:ramdisk_id] = @text
628
+ when 'LaunchConfigurationName' then @item[:launch_configuration_name] = @text
629
+ when 'UserData' then @item[:user_data] = @text
630
+ when 'NextToken' then @result[:next_token] = @text
631
+ else
632
+ case full_tag_name
633
+ when %r{/BlockDeviceMappings/member} # no trailing $
634
+ case name
635
+ when 'DeviceName' then @block_device_mapping[:device_name] = @text
636
+ when 'VirtualName' then @block_device_mapping[:virtual_name] = @text
637
+ when 'member' then @item[:block_device_mappings] << @block_device_mapping
638
+ end
639
+ when %r{member/SecurityGroups/member$}
640
+ @item[:security_groups] << @text
641
+ when %r{/LaunchConfigurations/member$}
642
+ @item[:security_groups].sort!
643
+ @result[:launch_configurations] << @item
644
+ end
645
+ end
646
+ end
647
+ def reset
648
+ @result = { :launch_configurations => []}
649
+ end
650
+ end
651
+
652
+ #-----------------------------------------------------------------
653
+ # PARSERS: Triggers
654
+ #-----------------------------------------------------------------
655
+
656
+ class DescribeTriggersParser < RightAWSParser #:nodoc:
657
+ def tagstart(name, attributes)
658
+ case name
659
+ when 'member'
660
+ case @xmlpath
661
+ when 'DescribeTriggersResponse/DescribeTriggersResult/Triggers'
662
+ @item = { :dimensions => {} }
663
+ when 'DescribeTriggersResponse/DescribeTriggersResult/Triggers/member/Dimensions'
664
+ @dimension = {}
665
+ end
666
+ end
667
+ end
668
+ def tagend(name)
669
+ case name
670
+ when 'AutoScalingGroupName' then @item[:auto_scaling_group_name] = @text
671
+ when 'MeasureName' then @item[:measure_name] = @text
672
+ when 'CreatedTime' then @item[:created_time] = @text
673
+ when 'BreachDuration' then @item[:breach_duration] = @text.to_i
674
+ when 'UpperBreachScaleIncrement' then @item[:upper_breach_scale_increment] = @text.to_i
675
+ when 'UpperThreshold' then @item[:upper_threshold] = @text.to_f
676
+ when 'LowerThreshold' then @item[:lower_threshold] = @text.to_f
677
+ when 'LowerBreachScaleIncrement' then @item[:lower_breach_scale_increment] = @text.to_i
678
+ when 'Period' then @item[:period] = @text.to_i
679
+ when 'Status' then @item[:status] = @text
680
+ when 'TriggerName' then @item[:trigger_name] = @text
681
+ when 'Statistic' then @item[:statistic] = @text
682
+ when 'Unit' then @item[:unit] = @text
683
+ when 'Name' then @dimension[:name] = @text
684
+ when 'Value' then @dimension[:value] = @text
685
+ when 'member'
686
+ case @xmlpath
687
+ when "#@p/member/Dimensions" then @item[:dimensions][@dimension[:name]] = @dimension[:value]
688
+ when @p then @result << @item
689
+ end
690
+ end
691
+ end
692
+ def reset
693
+ @p = 'DescribeTriggersResponse/DescribeTriggersResult/Triggers'
694
+ @result = []
695
+ end
696
+ end
697
+ end
698
+
699
+ end