talaris-right_aws 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/History.txt +305 -0
  2. data/Manifest.txt +60 -0
  3. data/README.txt +163 -0
  4. data/Rakefile +104 -0
  5. data/lib/acf/right_acf_interface.rb +549 -0
  6. data/lib/acf/right_acf_invalidations.rb +144 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +229 -0
  9. data/lib/acw/right_acw_interface.rb +248 -0
  10. data/lib/as/right_as_interface.rb +698 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +1174 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +458 -0
  16. data/lib/ec2/right_ec2_ebs.rb +465 -0
  17. data/lib/ec2/right_ec2_images.rb +413 -0
  18. data/lib/ec2/right_ec2_instances.rb +785 -0
  19. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  20. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  21. data/lib/ec2/right_ec2_reserved_instances.rb +174 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +396 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +425 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +583 -0
  26. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  27. data/lib/elb/right_elb_interface.rb +571 -0
  28. data/lib/iam/right_iam_access_keys.rb +71 -0
  29. data/lib/iam/right_iam_groups.rb +195 -0
  30. data/lib/iam/right_iam_interface.rb +341 -0
  31. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  32. data/lib/iam/right_iam_users.rb +251 -0
  33. data/lib/rds/right_rds_interface.rb +1309 -0
  34. data/lib/right_aws.rb +83 -0
  35. data/lib/route_53/right_route_53_interface.rb +630 -0
  36. data/lib/s3/right_s3.rb +1123 -0
  37. data/lib/s3/right_s3_interface.rb +1198 -0
  38. data/lib/sdb/active_sdb.rb +1107 -0
  39. data/lib/sdb/right_sdb_interface.rb +753 -0
  40. data/lib/sqs/right_sqs.rb +387 -0
  41. data/lib/sqs/right_sqs_gen2.rb +342 -0
  42. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  43. data/lib/sqs/right_sqs_interface.rb +593 -0
  44. data/right_aws.gemspec +91 -0
  45. data/test/acf/test_helper.rb +2 -0
  46. data/test/acf/test_right_acf.rb +138 -0
  47. data/test/awsbase/test_helper.rb +2 -0
  48. data/test/awsbase/test_right_awsbase.rb +12 -0
  49. data/test/ec2/test_helper.rb +2 -0
  50. data/test/ec2/test_right_ec2.rb +108 -0
  51. data/test/http_connection.rb +87 -0
  52. data/test/rds/test_helper.rb +2 -0
  53. data/test/rds/test_right_rds.rb +120 -0
  54. data/test/s3/test_helper.rb +2 -0
  55. data/test/s3/test_right_s3.rb +421 -0
  56. data/test/s3/test_right_s3_stubbed.rb +97 -0
  57. data/test/sdb/test_active_sdb.rb +357 -0
  58. data/test/sdb/test_batch_put_attributes.rb +54 -0
  59. data/test/sdb/test_helper.rb +3 -0
  60. data/test/sdb/test_right_sdb.rb +253 -0
  61. data/test/sqs/test_helper.rb +2 -0
  62. data/test/sqs/test_right_sqs.rb +285 -0
  63. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  64. data/test/test_credentials.rb +37 -0
  65. data/test/ts_right_aws.rb +14 -0
  66. metadata +214 -0
@@ -0,0 +1,84 @@
1
+ #
2
+ # Copyright (c) 2010 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
+ class Ec2
27
+
28
+ def describe_licenses(*license_ids)
29
+ link = generate_request("DescribeLicenses", amazonize_list('LicenseId', license_ids))
30
+ request_info(link, QEc2DescribeLicensesParser.new(:logger => @logger))
31
+ end
32
+
33
+ def activate_license(license_id, capacity)
34
+ link = generate_request("ActivateLicense", 'LicenseId' => license_id,
35
+ 'Capacity' => capacity)
36
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
37
+ end
38
+
39
+ # def get_license_capacity(license_id)
40
+ # link = generate_request("GetLicenseCapacity", 'LicenseId' => license_id)
41
+ # request_info(link, RightBoolResponseParser.new(:logger => @logger))
42
+ # end
43
+
44
+ def deactivate_license(license_id, capacity)
45
+ link = generate_request("DeactivateLicense", 'LicenseId' => license_id,
46
+ 'Capacity' => capacity)
47
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
48
+ end
49
+
50
+ #-----------------------------------------------------------------
51
+ # PARSERS: Images
52
+ #-----------------------------------------------------------------
53
+
54
+ class QEc2DescribeLicensesParser < RightAWSParser #:nodoc:
55
+ def tagstart(name, attributes)
56
+ case full_tag_name
57
+ when %r{/licenseSet/item$} then @item = { :capacities => [] }
58
+ when %r{/capacitySet/item$} then @capacity_item = {}
59
+ end
60
+ end
61
+ def tagend(name)
62
+ case name
63
+ when 'licenseId' then @item[:license_id] = @text
64
+ when 'type' then @item[:type] = @text
65
+ when 'pool' then @item[:pool] = @text
66
+ when 'capacity' then @capacity_item[:capacity] = @text.to_i
67
+ when 'instanceCapacity' then @capacity_item[:instance_capacity] = @text.to_i
68
+ when 'state' then @capacity_item[:state] = @text
69
+ when 'earliestAllowedDeactivationTime' then @capacity_item[:earliest_allowed_deactivation_time] = @text
70
+ else
71
+ case full_tag_name
72
+ when %r{/capacitySet/item$} then @item[:capacities] << @capacity_item
73
+ when %r{/licenseSet/item$} then @result << @item
74
+ end
75
+ end
76
+ end
77
+ def reset
78
+ @result = []
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,571 @@
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::ElbInterface -- RightScale Amazon Elastic Load Balancer interface
27
+ # The RightAws::ElbInterface class provides a complete interface to Amazon's
28
+ # Elastic Load Balancer service.
29
+ #
30
+ # For explanations of the semantics of each call, please refer to Amazon's documentation at
31
+ # http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/DeveloperGuide/
32
+ #
33
+ # Create an interface handle:
34
+ #
35
+ # elb = RightAws::ElbInterface.new(aws_access_key_id, aws_security_access_key)
36
+ #
37
+ # Create an new load balancer:
38
+ #
39
+ # elb.create_load_balancer( 'test-kd1',
40
+ # ['us-east-1a', 'us-east-1b'],
41
+ # [ { :protocol => :http, :load_balancer_port => 80, :instance_port => 80 },
42
+ # { :protocol => :tcp, :load_balancer_port => 443, :instance_port => 443 } ])
43
+ #
44
+ # Configure its health checking:
45
+ #
46
+ # elb.configure_health_check( 'test-kd1',
47
+ # { :healthy_threshold => 9,
48
+ # :unhealthy_threshold => 3,
49
+ # :target => "TCP:433",
50
+ # :timeout => 6,
51
+ # :interval => 31}
52
+ #
53
+ # Register instances with the balancer:
54
+ #
55
+ # elb.register_instances_with_load_balancer('test-kd1', 'i-8b8bcbe2', 'i-bf8bcbd6') #=> ["i-8b8bcbe2", "i-bf8bcbd6"]
56
+ #
57
+ # Add new availability zones:
58
+ #
59
+ # elb.enable_availability_zones_for_load_balancer("test-kd1", "us-east-1c")
60
+ #
61
+ class ElbInterface < RightAwsBase
62
+ include RightAwsBaseInterface
63
+
64
+ # Amazon ELB API version being used
65
+ API_VERSION = "2010-07-01"
66
+ DEFAULT_HOST = "elasticloadbalancing.amazonaws.com"
67
+ DEFAULT_PATH = '/'
68
+ DEFAULT_PROTOCOL = 'https'
69
+ DEFAULT_PORT = 443
70
+
71
+ LISTENER_PROTOCOLS = [ 'HTTP', 'HTTPS', 'TCP', 'SSL' ]
72
+
73
+ @@bench = AwsBenchmarkingBlock.new
74
+ def self.bench_xml
75
+ @@bench.xml
76
+ end
77
+ def self.bench_service
78
+ @@bench.service
79
+ end
80
+
81
+ # Create a new handle to an ELB account. All handles share the same per process or per thread
82
+ # HTTP connection to Amazon ELB. Each handle is for a specific account. The params have the
83
+ # following options:
84
+ # * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol). Example: 'https://elasticloadbalancing.amazonaws.com'
85
+ # * <tt>:server</tt>: ELB service host, default: DEFAULT_HOST
86
+ # * <tt>:port</tt>: ELB service port, default: DEFAULT_PORT
87
+ # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
88
+ # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
89
+ # * <tt>:signature_version</tt>: The signature version : '0','1' or '2'(default)
90
+ # * <tt>:cache</tt>: true/false(default): caching works for: describe_load_balancers
91
+ #
92
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
93
+ init({ :name => 'ELB',
94
+ :default_host => ENV['ELB_URL'] ? URI.parse(ENV['ELB_URL']).host : DEFAULT_HOST,
95
+ :default_port => ENV['ELB_URL'] ? URI.parse(ENV['ELB_URL']).port : DEFAULT_PORT,
96
+ :default_service => ENV['ELB_URL'] ? URI.parse(ENV['ELB_URL']).path : DEFAULT_PATH,
97
+ :default_protocol => ENV['ELB_URL'] ? URI.parse(ENV['ELB_URL']).scheme : DEFAULT_PROTOCOL,
98
+ :default_api_version => ENV['ELB_API_VERSION'] || API_VERSION },
99
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'] ,
100
+ aws_secret_access_key|| ENV['AWS_SECRET_ACCESS_KEY'],
101
+ params)
102
+ end
103
+
104
+ def generate_request(action, params={}) #:nodoc:
105
+ generate_request_impl(:get, action, params )
106
+ end
107
+
108
+ # Sends request to Amazon and parses the response
109
+ # Raises AwsError if any banana happened
110
+ def request_info(request, parser) #:nodoc:
111
+ request_info_impl(:lbs_connection, @@bench, request, parser)
112
+ end
113
+
114
+ #-----------------------------------------------------------------
115
+ # Load Balancers
116
+ #-----------------------------------------------------------------
117
+ # Describe load balancers.
118
+ # Returns an array of load balancers.
119
+ #
120
+ # elb.describe_load_balancers #=>
121
+ # [ { :health_check =>
122
+ # { :healthy_threshold => 10,
123
+ # :unhealthy_threshold => 2,
124
+ # :target => "TCP:80",
125
+ # :timeout => 5,
126
+ # :interval => 30},
127
+ # :load_balancer_name => "test-kd1",
128
+ # :availability_zones => ["us-east-1a", "us-east-1b"],
129
+ # :listeners =>
130
+ # [ { :protocol => "HTTP", :load_balancer_port => "80", :instance_port => "80" },
131
+ # { :protocol => "TCP", :load_balancer_port => "443", :instance_port => "443" } ],
132
+ # :created_time => "2009-05-27T11:59:11.000Z",
133
+ # :dns_name => "test-kd1-1519253964.us-east-1.elb.amazonaws.com",
134
+ # :instances => [] } ]
135
+ #
136
+ # elb.describe_load_balancers("test-kd1") #=>
137
+ # [{:load_balancer_name=>"test-kd1",
138
+ # :instances=>["i-9fc056f4", "i-b3debfd8"],
139
+ # :health_check=>
140
+ # {:interval=>30,
141
+ # :healthy_threshold=>10,
142
+ # :target=>"TCP:80",
143
+ # :unhealthy_threshold=>2,
144
+ # :timeout=>5},
145
+ # :dns_name=>"test-kd1-869291821.us-east-1.elb.amazonaws.com",
146
+ # :listeners=>
147
+ # [{:load_balancer_port=>"80",
148
+ # :policy_names=>["my-policy-1"],
149
+ # :instance_port=>"80",
150
+ # :protocol=>"HTTP"},
151
+ # {:load_balancer_port=>"8080",
152
+ # :policy_names=>["my-policy-lb-1"],
153
+ # :instance_port=>"8080",
154
+ # :protocol=>"HTTP"},
155
+ # {:load_balancer_port=>"443",
156
+ # :policy_names=>[],
157
+ # :instance_port=>"443",
158
+ # :protocol=>"TCP"}],
159
+ # :created_time=>"2010-04-15T12:04:49.000Z",
160
+ # :availability_zones=>["us-east-1a", "us-east-1b"],
161
+ # :app_cookie_stickiness_policies=>
162
+ # [{:policy_name=>"my-policy-1", :cookie_name=>"my-cookie-1"}],
163
+ # :lb_cookie_stickiness_policies=>
164
+ # [{:cookie_expiration_period=>60, :policy_name=>"my-policy-lb-1"}]}]
165
+ #
166
+ def describe_load_balancers(*load_balancers)
167
+ load_balancers = load_balancers.flatten.compact
168
+ request_hash = amazonize_list("LoadBalancerNames.member", load_balancers)
169
+ link = generate_request("DescribeLoadBalancers", request_hash)
170
+ request_cache_or_info(:describe_load_balancers, link, DescribeLoadBalancersParser, @@bench, load_balancers.right_blank?)
171
+ end
172
+
173
+ # Create new load balancer.
174
+ # Returns a new load balancer DNS name.
175
+ #
176
+ # Listener options: :protocol, :load_balancer_port, :instance_port and :ssl_certificate_id
177
+ # Protocols: :tcp, :http, :https or :ssl
178
+ #
179
+ # elb.create_load_balancer( 'test-kd1',
180
+ # ['us-east-1a', 'us-east-1b'],
181
+ # [ { :protocol => :http, :load_balancer_port => 80, :instance_port => 80 },
182
+ # { :protocol => :https, :load_balancer_port => 443, :instance_port => 443,
183
+ # :ssl_certificate_id => 'arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob' } ])
184
+ # #=> "test-kd1-1519253964.us-east-1.elb.amazonaws.com"
185
+ #
186
+ def create_load_balancer(load_balancer_name, availability_zones=[], listeners=[])
187
+ request_hash = { 'LoadBalancerName' => load_balancer_name }
188
+ # merge zones
189
+ request_hash.merge!( amazonize_list("AvailabilityZones.member", availability_zones) )
190
+ # merge listeners
191
+ if listeners.right_blank?
192
+ listeners = { :protocol => :http,
193
+ :load_balancer_port => 80,
194
+ :instance_port => 80 }
195
+ end
196
+ request_hash = merge_listeners_into_request_hash(request_hash, listeners)
197
+ link = generate_request("CreateLoadBalancer", request_hash)
198
+ request_info(link, CreateLoadBalancerParser.new(:logger => @logger))
199
+ end
200
+
201
+ # Delete load balancer.
202
+ # Returns +true+ on success.
203
+ #
204
+ # elb.delete_load_balancer('test-kd1') #=> true
205
+ #
206
+ # Amazon: Because this API has been designed to be idempotent, even if the LoadBalancer does not exist or
207
+ # has been deleted, DeleteLoadBalancer still returns a success.
208
+ #
209
+ def delete_load_balancer(load_balancer_name)
210
+ link = generate_request("DeleteLoadBalancer", 'LoadBalancerName' => load_balancer_name)
211
+ request_info(link, DeleteLoadBalancerParser.new(:logger => @logger))
212
+ end
213
+
214
+ # Creates one or more new listeners on a LoadBalancer for the specified port. If a listener with the given
215
+ # port does not already exist, it will be created; otherwise, the properties of the new listener must match
216
+ # the the properties of the existing listener.
217
+ #
218
+ # Listener options: :protocol, :load_balancer_port, :instance_port and :ssl_certificate_id
219
+ # Protocols: :tcp, :http, :https or :ssl
220
+ #
221
+ # elb.create_load_balancer_listeners( 'test-kd1',
222
+ # [ { :protocol => :http, :load_balancer_port => 80, :instance_port => 80 },
223
+ # { :protocol => :https, :load_balancer_port => 443, :instance_port => 443,
224
+ # :ssl_certificate_id => 'arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob' } ]) #=> true
225
+ #
226
+ def create_load_balancer_listeners(load_balancer_name, listeners)
227
+ request_hash = { 'LoadBalancerName' => load_balancer_name }
228
+ request_hash = merge_listeners_into_request_hash(request_hash, listeners)
229
+ link = generate_request("CreateLoadBalancerListeners", request_hash)
230
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
231
+ end
232
+
233
+ # Removes listeners from the load balancer for the specified port number.
234
+ #
235
+ # elb.delete_load_balancer_listeners( 'kd_test', 80, 443) #=> true
236
+ #
237
+ def delete_load_balancer_listeners(load_balancer_name, *load_balancer_ports)
238
+ load_balancer_ports.flatten!
239
+ request_hash = { 'LoadBalancerName' => load_balancer_name }
240
+ request_hash.merge!( amazonize_list("LoadBalancerPorts.member", load_balancer_ports ) )
241
+ link = generate_request("DeleteLoadBalancerListeners", request_hash )
242
+ request_info(link, DeleteLoadBalancerParser.new(:logger => @logger))
243
+ end
244
+
245
+ # Add one or more zones to a load balancer.
246
+ # Returns a list of updated availability zones for the load balancer.
247
+ #
248
+ # elb.enable_availability_zones_for_load_balancer("test-kd1", "us-east-1c") #=> ["us-east-1a", "us-east-1c"]
249
+ #
250
+ def enable_availability_zones_for_load_balancer(load_balancer_name, *availability_zones)
251
+ availability_zones.flatten!
252
+ request_hash = amazonize_list("AvailabilityZones.member", availability_zones)
253
+ request_hash.merge!( 'LoadBalancerName' => load_balancer_name )
254
+ link = generate_request("EnableAvailabilityZonesForLoadBalancer", request_hash)
255
+ request_info(link, AvailabilityZonesForLoadBalancerParser.new(:logger => @logger))
256
+ end
257
+
258
+ # Remove one or more zones from a load balancer.
259
+ # Returns a list of updated availability zones for the load balancer.
260
+ #
261
+ # elb.disable_availability_zones_for_load_balancer("test-kd1", "us-east-1c") #=> ["us-east-1a"]
262
+ #
263
+ def disable_availability_zones_for_load_balancer(load_balancer_name, *availability_zones)
264
+ availability_zones.flatten!
265
+ request_hash = amazonize_list("AvailabilityZones.member", availability_zones)
266
+ request_hash.merge!( 'LoadBalancerName' => load_balancer_name )
267
+ link = generate_request("DisableAvailabilityZonesForLoadBalancer", request_hash)
268
+ request_info(link, AvailabilityZonesForLoadBalancerParser.new(:logger => @logger))
269
+ end
270
+
271
+ # Define an application healthcheck for the instances.
272
+ # Returns an updated health check configuration for the load balancer.
273
+ #
274
+ # hc = elb.configure_health_check( 'test-kd1',
275
+ # { :healthy_threshold => 9,
276
+ # :unhealthy_threshold => 3,
277
+ # :target => "TCP:433",
278
+ # :timeout => 6,
279
+ # :interval => 31}
280
+ # pp hc #=> { :target=>"TCP:433", :timeout=>6, :interval=>31, :healthy_threshold=>9, :unhealthy_threshold=>3 }
281
+ #
282
+ def configure_health_check(load_balancer_name, health_check)
283
+ request_hash = { 'LoadBalancerName' => load_balancer_name }
284
+ health_check.each{ |key, value| request_hash["HealthCheck.#{key.to_s.right_camelize}"] = value }
285
+ link = generate_request("ConfigureHealthCheck", request_hash)
286
+ request_info(link, HealthCheckParser.new(:logger => @logger))
287
+ end
288
+
289
+ #-----------------------------------------------------------------
290
+ # Instances
291
+ #-----------------------------------------------------------------
292
+
293
+ # Describe the current state of the instances of the specified load balancer.
294
+ # Returns a list of the instances.
295
+ #
296
+ # elb.describe_instance_health('test-kd1', 'i-8b8bcbe2', 'i-bf8bcbd6') #=>
297
+ # [ { :description => "Instance registration is still in progress",
298
+ # :reason_code => "ELB",
299
+ # :instance_id => "i-8b8bcbe2",
300
+ # :state => "OutOfService" },
301
+ # { :description => "Instance has failed at least the UnhealthyThreshold number of health checks consecutively.",
302
+ # :reason_code => "Instance",
303
+ # :instance_id => "i-bf8bcbd6",
304
+ # :state => "OutOfService" } ]
305
+ #
306
+ def describe_instance_health(load_balancer_name, *instances)
307
+ instances.flatten!
308
+ request_hash = amazonize_list("Instances.member.?.InstanceId", instances)
309
+ request_hash.merge!( 'LoadBalancerName' => load_balancer_name )
310
+ link = generate_request("DescribeInstanceHealth", request_hash)
311
+ request_info(link, DescribeInstanceHealthParser.new(:logger => @logger))
312
+ end
313
+
314
+ # Add new instance(s) to the load balancer.
315
+ # Returns an updated list of instances for the load balancer.
316
+ #
317
+ # elb.register_instances_with_load_balancer('test-kd1', 'i-8b8bcbe2', 'i-bf8bcbd6') #=> ["i-8b8bcbe2", "i-bf8bcbd6"]
318
+ #
319
+ def register_instances_with_load_balancer(load_balancer_name, *instances)
320
+ instances.flatten!
321
+ request_hash = amazonize_list("Instances.member.?.InstanceId", instances)
322
+ request_hash.merge!( 'LoadBalancerName' => load_balancer_name )
323
+ link = generate_request("RegisterInstancesWithLoadBalancer", request_hash)
324
+ request_info(link, InstancesWithLoadBalancerParser.new(:logger => @logger))
325
+ end
326
+
327
+ # Remove instance(s) from the load balancer.
328
+ # Returns an updated list of instances for the load balancer.
329
+ #
330
+ # elb.deregister_instances_with_load_balancer('test-kd1', 'i-8b8bcbe2') #=> ["i-bf8bcbd6"]
331
+ #
332
+ def deregister_instances_with_load_balancer(load_balancer_name, *instances)
333
+ instances.flatten!
334
+ request_hash = amazonize_list("Instances.member.?.InstanceId", instances)
335
+ request_hash.merge!( 'LoadBalancerName' => load_balancer_name )
336
+ link = generate_request("DeregisterInstancesFromLoadBalancer", request_hash)
337
+ request_info(link, InstancesWithLoadBalancerParser.new(:logger => @logger))
338
+ end
339
+
340
+ #-----------------------------------------------------------------
341
+ # Cookies
342
+ #-----------------------------------------------------------------
343
+
344
+ # Generates a stickiness policy with sticky session lifetimes that follow
345
+ # that of an application-generated cookie.
346
+ # This policy can only be associated with HTTP listeners.
347
+ #
348
+ # elb.create_app_cookie_stickiness_policy('my-load-balancer', 'MyLoadBalancerPolicy', 'MyCookie') #=> true
349
+ #
350
+ def create_app_cookie_stickiness_policy(load_balancer_name, policy_name, cookie_name)
351
+ request_hash = { 'LoadBalancerName' => load_balancer_name,
352
+ 'PolicyName' => policy_name,
353
+ 'CookieName' => cookie_name }
354
+ link = generate_request("CreateAppCookieStickinessPolicy", request_hash)
355
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
356
+ end
357
+
358
+ # Generates a stickiness policy with sticky session lifetimes controlled by the
359
+ # lifetime of the browser (user-agent) or a specified expiration period.
360
+ # This policy can only be associated only with HTTP listeners.
361
+ #
362
+ # elb.create_lb_cookie_stickiness_policy('my-load-balancer', 'MyLoadBalancerPolicy', 60) #=> true
363
+ #
364
+ def create_lb_cookie_stickiness_policy(load_balancer_name, policy_name, cookie_expiration_period)
365
+ request_hash = { 'LoadBalancerName' => load_balancer_name,
366
+ 'PolicyName' => policy_name,
367
+ 'CookieExpirationPeriod' => cookie_expiration_period }
368
+ link = generate_request("CreateLBCookieStickinessPolicy", request_hash)
369
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
370
+ end
371
+
372
+ # Associates, updates, or disables a policy with a listener on the load balancer.
373
+ # Only zero(0) or one(1) policy can be associated with a listener.
374
+ #
375
+ # elb.set_load_balancer_policies_of_listener('my-load-balancer', 80, 'MyLoadBalancerPolicy') #=> true
376
+ #
377
+ def set_load_balancer_policies_of_listener(load_balancer_name, load_balancer_port, *policy_names)
378
+ policy_names.flatten!
379
+ request_hash = { 'LoadBalancerName' => load_balancer_name,
380
+ 'LoadBalancerPort' => load_balancer_port }
381
+ if policy_names.right_blank?
382
+ request_hash['PolicyNames'] = ''
383
+ else
384
+ request_hash.merge!(amazonize_list('PolicyNames.member', policy_names))
385
+ end
386
+ link = generate_request("SetLoadBalancerPoliciesOfListener", request_hash)
387
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
388
+ end
389
+
390
+ # Deletes a policy from the load balancer. The specified policy must not be enabled for any listeners.
391
+ #
392
+ # elb.delete_load_balancer_policy('my-load-balancer', 'MyLoadBalancerPolicy') #=> true
393
+ #
394
+ def delete_load_balancer_policy(load_balancer_name, policy_name)
395
+ request_hash = { 'LoadBalancerName' => load_balancer_name,
396
+ 'PolicyName' => policy_name }
397
+ link = generate_request("DeleteLoadBalancerPolicy", request_hash)
398
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
399
+ end
400
+
401
+ def set_load_balancer_listener_ssl_certificate(load_balancer_name, load_balancer_port, ssl_sertificate_id)
402
+ request_hash = { 'LoadBalancerName' => load_balancer_name,
403
+ 'LoadBalancerPort' => load_balancer_port,
404
+ 'SSLCertificateId' => ssl_sertificate_id }
405
+ link = generate_request("SetLoadBalancerListenerSSLCertificate", request_hash)
406
+ request_info(link, RightHttp2xxParser.new(:logger => @logger))
407
+ end
408
+
409
+ #-----------------------------------------------------------------
410
+ # Helpers
411
+ #-----------------------------------------------------------------
412
+
413
+ def merge_listeners_into_request_hash(request_hash, listeners) # :nodoc:
414
+ listeners = [listeners] unless listeners.is_a?(Array)
415
+ request_hash.merge(amazonize_list( ['Listeners.member.?.Protocol',
416
+ 'Listeners.member.?.LoadBalancerPort',
417
+ 'Listeners.member.?.InstancePort',
418
+ 'Listeners.member.?.SSLCertificateId'],
419
+ listeners.map{ |i|
420
+ [ (i[:protocol] || 'HTTP').to_s.upcase,
421
+ i[:load_balancer_port] || 80,
422
+ i[:instance_port] || 80,
423
+ i[:ssl_certificate_id]]
424
+ },
425
+ :default => :skip_nils
426
+ )
427
+ )
428
+ end
429
+
430
+ #-----------------------------------------------------------------
431
+ # PARSERS: Load Balancers
432
+ #-----------------------------------------------------------------
433
+
434
+ class DescribeLoadBalancersParser < RightAWSParser #:nodoc:
435
+ def tagstart(name, attributes)
436
+ case full_tag_name
437
+ when %r{LoadBalancerDescriptions/member$}
438
+ @item = { :availability_zones => [],
439
+ :health_check => {},
440
+ :listeners => [],
441
+ :instances => [],
442
+ :app_cookie_stickiness_policies => [],
443
+ :lb_cookie_stickiness_policies => []}
444
+ when %r{ListenerDescriptions/member$} then @listener = {:policy_names => []}
445
+ when %r{AppCookieStickinessPolicies/member$} then @app_cookie_stickiness_policy = {}
446
+ when %r{LBCookieStickinessPolicies/member$} then @lb_cookie_stickiness_policy = {}
447
+ end
448
+ end
449
+ def tagend(name)
450
+ case name
451
+ when 'LoadBalancerName' then @item[:load_balancer_name] = @text
452
+ when 'DNSName' then @item[:dns_name] = @text
453
+ when 'CreatedTime' then @item[:created_time] = @text
454
+ when 'Interval' then @item[:health_check][:interval] = @text.to_i
455
+ when 'Target' then @item[:health_check][:target] = @text
456
+ when 'HealthyThreshold' then @item[:health_check][:healthy_threshold] = @text.to_i
457
+ when 'Timeout' then @item[:health_check][:timeout] = @text.to_i
458
+ when 'UnhealthyThreshold' then @item[:health_check][:unhealthy_threshold] = @text.to_i
459
+ when 'Protocol' then @listener[:protocol] = @text
460
+ when 'LoadBalancerPort' then @listener[:load_balancer_port] = @text
461
+ when 'InstancePort' then @listener[:instance_port] = @text
462
+ when 'SSLCertificateId' then @listener[:ssl_certificate_id] = @text
463
+ end
464
+ case full_tag_name
465
+ when %r{AvailabilityZones/member$} then @item[:availability_zones] << @text
466
+ when %r{Instances/member/InstanceId$} then @item[:instances] << @text
467
+ when %r{ListenerDescriptions/member$} then @item[:listeners] << @listener
468
+ when %r{ListenerDescriptions/member/PolicyNames/member$} then @listener[:policy_names] << @text
469
+ when %r{AppCookieStickinessPolicies/member}
470
+ case name
471
+ when 'PolicyName' then @app_cookie_stickiness_policy[:policy_name] = @text
472
+ when 'CookieName' then @app_cookie_stickiness_policy[:cookie_name] = @text
473
+ when 'member' then @item[:app_cookie_stickiness_policies] << @app_cookie_stickiness_policy
474
+ end
475
+ when %r{LBCookieStickinessPolicies/member}
476
+ case name
477
+ when 'PolicyName' then @lb_cookie_stickiness_policy[:policy_name] = @text
478
+ when 'CookieExpirationPeriod' then @lb_cookie_stickiness_policy[:cookie_expiration_period] = @text.to_i
479
+ when 'member' then @item[:lb_cookie_stickiness_policies] << @lb_cookie_stickiness_policy
480
+ end
481
+ when %r{LoadBalancerDescriptions/member$}
482
+ @item[:availability_zones].sort!
483
+ @item[:instances].sort!
484
+ @result << @item
485
+ end
486
+ end
487
+ def reset
488
+ @result = []
489
+ end
490
+ end
491
+
492
+ class CreateLoadBalancerParser < RightAWSParser #:nodoc:
493
+ def tagend(name)
494
+ @result = @text if name == 'DNSName'
495
+ end
496
+ end
497
+
498
+ class DeleteLoadBalancerParser < RightAWSParser #:nodoc:
499
+ def tagend(name)
500
+ @result = true if name == 'DeleteLoadBalancerResult'
501
+ end
502
+ end
503
+
504
+ class AvailabilityZonesForLoadBalancerParser < RightAWSParser #:nodoc:
505
+ def tagend(name)
506
+ case name
507
+ when 'member'
508
+ @result << @text
509
+ when 'AvailabilityZones'
510
+ @result.sort!
511
+ end
512
+ end
513
+ def reset
514
+ @result = []
515
+ end
516
+ end
517
+
518
+ class HealthCheckParser < RightAWSParser #:nodoc:
519
+ def tagend(name)
520
+ case name
521
+ when 'Interval' then @result[:interval] = @text.to_i
522
+ when 'Target' then @result[:target] = @text
523
+ when 'HealthyThreshold' then @result[:healthy_threshold] = @text.to_i
524
+ when 'Timeout' then @result[:timeout] = @text.to_i
525
+ when 'UnhealthyThreshold' then @result[:unhealthy_threshold] = @text.to_i
526
+ end
527
+ end
528
+ def reset
529
+ @result = {}
530
+ end
531
+ end
532
+
533
+ #-----------------------------------------------------------------
534
+ # PARSERS: Instances
535
+ #-----------------------------------------------------------------
536
+
537
+ class DescribeInstanceHealthParser < RightAWSParser #:nodoc:
538
+ def tagstart(name, attributes)
539
+ @item = {} if name == 'member'
540
+ end
541
+ def tagend(name)
542
+ case name
543
+ when 'Description' then @item[:description] = @text
544
+ when 'State' then @item[:state] = @text
545
+ when 'InstanceId' then @item[:instance_id] = @text
546
+ when 'ReasonCode' then @item[:reason_code] = @text
547
+ when 'member' then @result << @item
548
+ end
549
+ end
550
+ def reset
551
+ @result = []
552
+ end
553
+ end
554
+
555
+ class InstancesWithLoadBalancerParser < RightAWSParser #:nodoc:
556
+ def tagend(name)
557
+ case name
558
+ when 'InstanceId'
559
+ @result << @text
560
+ when 'Instances'
561
+ @result.sort!
562
+ end
563
+ end
564
+ def reset
565
+ @result = []
566
+ end
567
+ end
568
+
569
+ end
570
+
571
+ end