right_aws 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +47 -0
- data/Manifest.txt +1 -0
- data/README.txt +65 -48
- data/Rakefile +11 -6
- data/lib/awsbase/right_awsbase.rb +94 -25
- data/lib/awsbase/support.rb +106 -0
- data/lib/ec2/right_ec2.rb +257 -140
- data/lib/right_aws.rb +4 -2
- data/lib/s3/right_s3.rb +39 -24
- data/lib/s3/right_s3_interface.rb +13 -16
- data/lib/sqs/right_sqs.rb +30 -19
- data/lib/sqs/right_sqs_interface.rb +49 -43
- data/test/ec2/test_right_ec2.rb +3 -2
- data/test/s3/test_right_s3.rb +1 -1
- data/test/sqs/test_right_sqs.rb +19 -24
- data/test/ts_right_aws.rb +1 -0
- metadata +6 -22
- data/test/awsbase/test_helper.rb +0 -2
- data/test/awsbase/test_right_awsbase.rb +0 -12
data/lib/ec2/right_ec2.rb
CHANGED
@@ -23,55 +23,106 @@
|
|
23
23
|
|
24
24
|
module RightAws
|
25
25
|
|
26
|
+
# = RightAWS::EC2 -- RightScale Amazon EC2 interface
|
27
|
+
# The RightAws::EC2 class provides a complete interface to Amazon's
|
28
|
+
# Elastic Compute Cloud service.
|
29
|
+
# For explanations of the semantics
|
30
|
+
# of each call, please refer to Amazon's documentation at
|
31
|
+
# http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=87
|
32
|
+
#
|
33
|
+
# Examples:
|
34
|
+
#
|
35
|
+
# Create an EC2 interface handle:
|
36
|
+
#
|
37
|
+
# @ec2 = RightAws::Ec2.new(aws_access_key_id,
|
38
|
+
# aws_secret_access_key)
|
39
|
+
# Create a new SSH key pair:
|
40
|
+
# @key = 'right_ec2_awesome_test_key'
|
41
|
+
# new_key = @ec2.create_key_pair(@key)
|
42
|
+
# keys = @ec2.describe_key_pairs
|
43
|
+
#
|
44
|
+
# Create a security group:
|
45
|
+
# @group = 'right_ec2_awesome_test_security_group'
|
46
|
+
# @ec2.create_security_group(@group,'My awesome test group')
|
47
|
+
# group = @ec2.describe_security_groups([@group])[0]
|
48
|
+
#
|
49
|
+
# Configure a security group:
|
50
|
+
# @ec2.authorize_security_group_named_ingress(@group, account_number, 'default')
|
51
|
+
# @ec2.authorize_security_group_IP_ingress(@group, 80,80,'udp','192.168.1.0/8')
|
52
|
+
#
|
53
|
+
# Describe the available images:
|
54
|
+
# images = @ec2.describe_images
|
55
|
+
#
|
56
|
+
# Launch an instance:
|
57
|
+
# ec2.run_instances('ami-9a9e7bf3', 1, 1, ['default'], @key, 'SomeImportantUserData', 'public')
|
58
|
+
#
|
59
|
+
#
|
60
|
+
# Describe running instances:
|
61
|
+
# @ec2.describe_instances
|
62
|
+
#
|
63
|
+
# Error handling: all operations raise an RightAws::AwsError in case
|
64
|
+
# of problems. Note that transient errors are automatically retried.
|
65
|
+
|
26
66
|
class Ec2
|
27
67
|
|
28
68
|
SIGNATURE_VERSION = "1"
|
29
|
-
|
69
|
+
# Amazon EC2 API version being used
|
70
|
+
API_VERSION = "2007-03-01"
|
30
71
|
DEFAULT_HOST = "ec2.amazonaws.com"
|
31
72
|
DEFAULT_PROTOCOL = 'https'
|
32
73
|
DEFAULT_PORT = 443
|
33
74
|
|
75
|
+
# Default addressing type (public=NAT, direct=no-NAT) used when launching instances.
|
34
76
|
DEFAULT_ADDRESSING_TYPE = 'public'
|
35
77
|
DNS_ADDRESSING_SET = ['public','direct']
|
36
78
|
|
37
|
-
|
79
|
+
# A list of Amazon problems we can handle by AWSErrorHandler.
|
38
80
|
@@amazon_problems = RightAws::AMAZON_PROBLEMS
|
39
81
|
|
40
|
-
|
82
|
+
# Current aws_access_key_id
|
41
83
|
attr_reader :aws_access_key_id
|
42
|
-
|
84
|
+
# Last HTTP request object
|
43
85
|
attr_reader :last_request
|
44
|
-
|
86
|
+
# Last HTTP response object
|
45
87
|
attr_reader :last_response
|
46
|
-
|
88
|
+
# Last AWS errors list (used by AWSErrorHandler)
|
47
89
|
attr_accessor :last_errors
|
48
|
-
|
90
|
+
# Last AWS request id (used by AWSErrorHandler)
|
49
91
|
attr_accessor :last_request_id
|
50
|
-
|
92
|
+
# Logger object, used by this class to generate log messages
|
51
93
|
attr_accessor :logger
|
52
|
-
|
94
|
+
# Option params passed into new
|
53
95
|
attr_accessor :params
|
54
96
|
|
55
97
|
@@bench_ec2 = Benchmark::Tms.new()
|
56
98
|
@@bench_xml = Benchmark::Tms.new()
|
57
99
|
|
58
|
-
|
100
|
+
# Benchmark::Tms instance that accumulates time spent in requests to EC2.
|
59
101
|
def self.bench_ec2; @@bench_ec2; end
|
60
102
|
|
61
|
-
|
103
|
+
# Benchmark::Tms instance that accumulates time spent in XML parsing.
|
62
104
|
def self.bench_xml; @@bench_xml; end
|
63
105
|
|
64
|
-
|
65
|
-
|
106
|
+
# Returns a list of Amazon service responses which are known to be transient errors.
|
107
|
+
# By default returns the same value as AMAZON_PROBLEMS const. See AWSErrorHandler.
|
66
108
|
def self.amazon_problems
|
67
109
|
@@amazon_problems
|
68
110
|
end
|
69
111
|
|
70
|
-
|
112
|
+
# Sets the list of Amazon problems that are automatically retried. See AWSErrorHandler.
|
71
113
|
def self.amazon_problems=(problems_list)
|
72
114
|
@@amazon_problems = problems_list
|
73
115
|
end
|
74
116
|
|
117
|
+
# Create a new handle to an EC2 account. All handles share the same per process or per thread
|
118
|
+
# HTTP connection to Amazon EC2. Each handle is for a specific account. The params have the
|
119
|
+
# following options:
|
120
|
+
# * <tt>:server</tt>: EC2 service host, default: DEFAULT_HOST
|
121
|
+
# * <tt>:port</tt>: EC2 service port, default: DEFAULT_PORT
|
122
|
+
# * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
|
123
|
+
# * <tt>:multi_thread</tt>: true=HTTP connection per thread, false=per process
|
124
|
+
# * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
|
125
|
+
#
|
75
126
|
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
76
127
|
@params = params
|
77
128
|
raise AwsError.new("AWS access keys are required to operate on EC2") \
|
@@ -94,7 +145,7 @@ module RightAws
|
|
94
145
|
AwsError::on_aws_exception(self, options)
|
95
146
|
end
|
96
147
|
|
97
|
-
# Return
|
148
|
+
# Return +true+ if this RightEc2NativeQuery instance works in multi_thread mode and +false+ otherwise.
|
98
149
|
def multi_thread
|
99
150
|
@params[:multi_thread]
|
100
151
|
end
|
@@ -132,13 +183,7 @@ module RightAws
|
|
132
183
|
@last_response = response
|
133
184
|
if response.is_a?(Net::HTTPSuccess)
|
134
185
|
@error_handler = nil
|
135
|
-
@@bench_xml.add!
|
136
|
-
if parser.kind_of?(RightAWSParser)
|
137
|
-
REXML::Document.parse_stream(response.body, parser)
|
138
|
-
else
|
139
|
-
parser.parse(response)
|
140
|
-
end
|
141
|
-
end
|
186
|
+
@@bench_xml.add! { parser.parse(response) }
|
142
187
|
return parser.result
|
143
188
|
else
|
144
189
|
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
@@ -167,49 +212,66 @@ module RightAws
|
|
167
212
|
#-----------------------------------------------------------------
|
168
213
|
|
169
214
|
def ec2_describe_images(type, list) #:nodoc:
|
170
|
-
link = generate_request("DescribeImages", hash_params(type,list))
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
return ec2_describe_images('ExecutableBy', list)
|
215
|
+
link = generate_request("DescribeImages", hash_params(type,list.to_a))
|
216
|
+
images = request_info(link, QEc2DescribeImagesParser.new(:logger => @logger))
|
217
|
+
images.collect! do |image|
|
218
|
+
{:aws_id => image.imageId,
|
219
|
+
:aws_location => image.imageLocation,
|
220
|
+
:aws_owner => image.imageOwnerId,
|
221
|
+
:aws_state => image.imageState.downcase,
|
222
|
+
:aws_is_public => image.isPublic,
|
223
|
+
:aws_product_codes => image.productCodes}
|
224
|
+
end
|
225
|
+
images
|
226
|
+
rescue Exception
|
227
|
+
on_exception
|
184
228
|
end
|
185
229
|
|
186
|
-
# Retrieve a list of images. Returns array of hashes or an exception:
|
230
|
+
# Retrieve a list of images. Returns array of hashes describing the images or an exception:
|
187
231
|
#
|
188
232
|
# ec2.describe_images #=>
|
189
|
-
# [{:aws_owner
|
190
|
-
# :
|
191
|
-
#
|
233
|
+
# [{:aws_owner => "522821470517",
|
234
|
+
# :aws_id => "ami-e4b6538d",
|
235
|
+
# :aws_state => "available",
|
236
|
+
# :aws_location => "marcins_cool_public_images/ubuntu-6.10.manifest.xml",
|
237
|
+
# :aws_is_public => true},
|
238
|
+
# {...},
|
239
|
+
# {...} ]
|
192
240
|
#
|
193
241
|
# If +list+ param is set, then retrieve information about the listed images only:
|
194
242
|
#
|
195
243
|
# ec2.describe_images(['ami-e4b6538d']) #=>
|
196
|
-
# [{:aws_owner
|
197
|
-
# :
|
244
|
+
# [{:aws_owner => "522821470517",
|
245
|
+
# :aws_id => "ami-e4b6538d",
|
246
|
+
# :aws_state => "available",
|
247
|
+
# :aws_location => "marcins_cool_public_images/ubuntu-6.10.manifest.xml",
|
248
|
+
# :aws_is_public => true}]
|
198
249
|
#
|
199
250
|
def describe_images(list=[])
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
251
|
+
ec2_describe_images('ImageId', list)
|
252
|
+
end
|
253
|
+
|
254
|
+
#
|
255
|
+
# Example:
|
256
|
+
#
|
257
|
+
# ec2.describe_images_by_owner('522821470517')
|
258
|
+
# ec2.describe_images_by_owner('self')
|
259
|
+
#
|
260
|
+
def describe_images_by_owner(list)
|
261
|
+
ec2_describe_images('Owner', list)
|
262
|
+
end
|
263
|
+
|
264
|
+
#
|
265
|
+
# Example:
|
266
|
+
#
|
267
|
+
# ec2.describe_images_by_executable_by('522821470517')
|
268
|
+
# ec2.describe_images_by_executable_by('self')
|
269
|
+
#
|
270
|
+
def describe_images_by_executable_by(list)
|
271
|
+
ec2_describe_images('ExecutableBy', list)
|
211
272
|
end
|
212
|
-
|
273
|
+
|
274
|
+
|
213
275
|
# Register new image at Amazon.
|
214
276
|
# Returns new image id or an exception.
|
215
277
|
#
|
@@ -218,7 +280,7 @@ module RightAws
|
|
218
280
|
def register_image(image_location)
|
219
281
|
link = generate_request("RegisterImage",
|
220
282
|
'ImageLocation' => image_location.to_s)
|
221
|
-
request_info(link, QEc2RegisterImageParser.new)
|
283
|
+
request_info(link, QEc2RegisterImageParser.new(:logger => @logger))
|
222
284
|
rescue Exception
|
223
285
|
on_exception
|
224
286
|
end
|
@@ -230,13 +292,13 @@ module RightAws
|
|
230
292
|
def deregister_image(image_id)
|
231
293
|
link = generate_request("DeregisterImage",
|
232
294
|
'ImageId' => image_id.to_s)
|
233
|
-
request_info(link, RightBoolResponseParser.new)
|
295
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
234
296
|
rescue Exception
|
235
297
|
on_exception
|
236
298
|
end
|
237
299
|
|
238
300
|
|
239
|
-
# Describe image attributes. Currently
|
301
|
+
# Describe image attributes. Currently 'launchPermission' and 'productCodes' are supported.
|
240
302
|
#
|
241
303
|
# ec2.describe_image_attribute('ami-e444444d') #=> {:groups=>["all"], :users=>["000000000777"]}
|
242
304
|
#
|
@@ -244,9 +306,15 @@ module RightAws
|
|
244
306
|
link = generate_request("DescribeImageAttribute",
|
245
307
|
'ImageId' => image_id,
|
246
308
|
'Attribute' => attribute)
|
247
|
-
image_attr = request_info(link, QEc2DescribeImageAttributeParser.new)
|
248
|
-
|
249
|
-
|
309
|
+
image_attr = request_info(link, QEc2DescribeImageAttributeParser.new(:logger => @logger))
|
310
|
+
result = {}
|
311
|
+
if image_attr.launchPermission
|
312
|
+
result = { :users => image_attr.launchPermission.userIds,
|
313
|
+
:groups => image_attr.launchPermission.groups }
|
314
|
+
elsif image_attr.productCodes
|
315
|
+
result = { :aws_product_codes => image_attr.productCodes}
|
316
|
+
end
|
317
|
+
result
|
250
318
|
rescue Exception
|
251
319
|
on_exception
|
252
320
|
end
|
@@ -259,37 +327,42 @@ module RightAws
|
|
259
327
|
link = generate_request("ResetImageAttribute",
|
260
328
|
'ImageId' => image_id,
|
261
329
|
'Attribute' => attribute)
|
262
|
-
request_info(link, RightBoolResponseParser.new)
|
330
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
263
331
|
rescue Exception
|
264
332
|
on_exception
|
265
333
|
end
|
266
334
|
|
267
|
-
#
|
268
|
-
#
|
335
|
+
# Modify an image's attributes. It is recommended that you use
|
336
|
+
# modify_image_launch_perm_add_users, modify_image_launch_perm_remove_users, etc.
|
337
|
+
# instead of modify_image_attribute because the signature of
|
338
|
+
# modify_image_attribute may change with EC2 service changes.
|
269
339
|
#
|
270
|
-
# attribute
|
271
|
-
#
|
272
|
-
#
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
'
|
279
|
-
params
|
280
|
-
params.update(hash_params('
|
340
|
+
# attribute : currently, only 'launchPermission' is supported.
|
341
|
+
# operation_type : currently, only 'add' & 'remove' are supported.
|
342
|
+
# vars:
|
343
|
+
# :user_group : currently, only 'all' is supported.
|
344
|
+
# :user_id
|
345
|
+
# :product_code
|
346
|
+
def modify_image_attribute(image_id, attribute, operation_type = nil, vars = {})
|
347
|
+
params = {'ImageId' => image_id,
|
348
|
+
'Attribute' => attribute}
|
349
|
+
params['OperationType'] = operation_type if operation_type
|
350
|
+
params.update(hash_params('UserId', vars[:user_id].to_a)) if vars[:user_id]
|
351
|
+
params.update(hash_params('UserGroup', vars[:user_group].to_a)) if vars[:user_group]
|
352
|
+
params.update(hash_params('ProductCode', vars[:product_code])) if vars[:product_code]
|
281
353
|
link = generate_request("ModifyImageAttribute", params)
|
282
|
-
request_info(link, RightBoolResponseParser.new)
|
354
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
283
355
|
rescue Exception
|
284
356
|
on_exception
|
285
357
|
end
|
286
358
|
|
287
|
-
# Grant image launch permissions
|
359
|
+
# Grant image launch permissions to users.
|
360
|
+
# Parameter +userId+ is a list of user AWS account ids.
|
361
|
+
# Returns +true+ or an exception.
|
288
362
|
#
|
289
363
|
# ec2.modify_image_launch_perm_add_users('ami-e444444d',['000000000777','000000000778']) #=> true
|
290
|
-
#
|
291
364
|
def modify_image_launch_perm_add_users(image_id, user_id=[])
|
292
|
-
modify_image_attribute(image_id, 'launchPermission', 'add', user_id
|
365
|
+
modify_image_attribute(image_id, 'launchPermission', 'add', :user_id => user_id.to_a)
|
293
366
|
end
|
294
367
|
|
295
368
|
# Revokes image launch permissions for users. +userId+ is a list of users AWS accounts ids. Returns +true+ or an exception.
|
@@ -297,7 +370,7 @@ module RightAws
|
|
297
370
|
# ec2.modify_image_launch_perm_remove_users('ami-e444444d',['000000000777','000000000778']) #=> true
|
298
371
|
#
|
299
372
|
def modify_image_launch_perm_remove_users(image_id, user_id=[])
|
300
|
-
modify_image_attribute(image_id, 'launchPermission', 'remove', user_id
|
373
|
+
modify_image_attribute(image_id, 'launchPermission', 'remove', :user_id => user_id.to_a)
|
301
374
|
end
|
302
375
|
|
303
376
|
# Add image launch permissions for users groups (currently only 'all' is supported, which gives public launch permissions).
|
@@ -306,7 +379,7 @@ module RightAws
|
|
306
379
|
# ec2.modify_image_launch_perm_add_groups('ami-e444444d') #=> true
|
307
380
|
#
|
308
381
|
def modify_image_launch_perm_add_groups(image_id, userGroup=['all'])
|
309
|
-
modify_image_attribute(image_id, 'launchPermission', 'add',
|
382
|
+
modify_image_attribute(image_id, 'launchPermission', 'add', :user_group => userGroup.to_a)
|
310
383
|
end
|
311
384
|
|
312
385
|
# Remove image launch permissions for users groups (currently only 'all' is supported, which gives public launch permissions).
|
@@ -314,7 +387,15 @@ module RightAws
|
|
314
387
|
# ec2.modify_image_launch_perm_remove_groups('ami-e444444d') #=> true
|
315
388
|
#
|
316
389
|
def modify_image_launch_perm_remove_groups(image_id, userGroup=['all'])
|
317
|
-
modify_image_attribute(image_id, 'launchPermission', 'remove',
|
390
|
+
modify_image_attribute(image_id, 'launchPermission', 'remove', :user_group => userGroup.to_a)
|
391
|
+
end
|
392
|
+
|
393
|
+
# Add product code to image
|
394
|
+
#
|
395
|
+
# ec2.modify_image_product_code('ami-e444444d','0ABCDEF') #=> true
|
396
|
+
#
|
397
|
+
def modify_image_product_code(image_id, productCode=[])
|
398
|
+
modify_image_attribute(image_id, 'productCodes', nil, :product_code => productCode.to_a)
|
318
399
|
end
|
319
400
|
|
320
401
|
def get_desc_instances(instances) # :nodoc:
|
@@ -334,7 +415,8 @@ module RightAws
|
|
334
415
|
:aws_state => instance.instanceState.name,
|
335
416
|
:ssh_key_name => instance.keyName,
|
336
417
|
:aws_image_id => instance.imageId,
|
337
|
-
:aws_reason => reason
|
418
|
+
:aws_reason => reason,
|
419
|
+
:aws_product_codes => instance.productCodes}
|
338
420
|
end
|
339
421
|
end
|
340
422
|
result
|
@@ -342,7 +424,8 @@ module RightAws
|
|
342
424
|
on_exception
|
343
425
|
end
|
344
426
|
|
345
|
-
# Retrieve information about EC2 instances. If +list+ is omitted then returns the
|
427
|
+
# Retrieve information about EC2 instances. If +list+ is omitted then returns the
|
428
|
+
# list of all instances.
|
346
429
|
#
|
347
430
|
# ec2.describe_instances #=>
|
348
431
|
# [{:aws_image_id => "ami-e444444d",
|
@@ -359,16 +442,27 @@ module RightAws
|
|
359
442
|
# ..., {...}]
|
360
443
|
#
|
361
444
|
def describe_instances(list=[])
|
362
|
-
link = generate_request("DescribeInstances", hash_params('InstanceId',list))
|
363
|
-
instances = request_info(link, QEc2DescribeInstancesParser.new)
|
445
|
+
link = generate_request("DescribeInstances", hash_params('InstanceId',list.to_a))
|
446
|
+
instances = request_info(link, QEc2DescribeInstancesParser.new(:logger => @logger))
|
364
447
|
get_desc_instances(instances)
|
365
448
|
rescue Exception
|
366
449
|
on_exception
|
367
450
|
end
|
368
451
|
|
452
|
+
# Return the product code attached to instance or +nil+ otherwise.
|
453
|
+
#
|
454
|
+
# ec2.confirm_product_instance('ami-e444444d','12345678') #=> nil
|
455
|
+
# ec2.confirm_product_instance('ami-e444444d','00001111') #=> "000000000888"
|
456
|
+
#
|
457
|
+
def confirm_product_instance(instance, product_code)
|
458
|
+
link = generate_request("ConfirmProductInstance", { 'ProductCode' => product_code,
|
459
|
+
'InstanceId' => instance })
|
460
|
+
request_info(link, QEc2ConfirmProductInstanceParser.new(:logger => @logger))
|
461
|
+
end
|
462
|
+
|
369
463
|
# Launch new EC2 instances. Returns a list of launched instances or an exception.
|
370
464
|
#
|
371
|
-
# ec2.run_instances('ami-e444444d',1,1,['my_awesome_group'],'my_awesome_key', 'Woohoo!!!', public) #=>
|
465
|
+
# ec2.run_instances('ami-e444444d',1,1,['my_awesome_group'],'my_awesome_key', 'Woohoo!!!', 'public') #=>
|
372
466
|
# [{:aws_image_id => "ami-e444444d",
|
373
467
|
# :aws_reason => "",
|
374
468
|
# :aws_state_code => "0",
|
@@ -382,9 +476,9 @@ module RightAws
|
|
382
476
|
# :private_dns_name => ""}]
|
383
477
|
#
|
384
478
|
def run_instances(image_id, min_count, max_count, group_ids, key_name, user_data='', addressing_type=DEFAULT_ADDRESSING_TYPE)
|
385
|
-
@logger.info("Launching instance of image #{image_id} for #{@aws_access_key_id}, key: #{key_name}, groups: #{(group_ids||[]).join(',')}")
|
479
|
+
@logger.info("Launching instance of image #{image_id} for #{@aws_access_key_id}, key: #{key_name}, groups: #{(group_ids||[]).to_a.join(',')}")
|
386
480
|
# careful: keyName and securityGroups may be nil
|
387
|
-
params = hash_params('SecurityGroup', group_ids)
|
481
|
+
params = hash_params('SecurityGroup', group_ids.to_a)
|
388
482
|
params.update( {'ImageId' => image_id,
|
389
483
|
'MinCount' => min_count.to_s,
|
390
484
|
'MaxCount' => max_count.to_s,
|
@@ -394,13 +488,13 @@ module RightAws
|
|
394
488
|
user_data.strip!
|
395
489
|
# Do not use CGI::escape(encode64(...)) as it is done in Amazons EC2 library.
|
396
490
|
# Amazon 169.254.169.254 does not like escaped symbols!
|
397
|
-
# And it
|
491
|
+
# And it doesn't like "\n" inside of encoded string! Grrr....
|
398
492
|
# Otherwise, some of UserData symbols will be lost...
|
399
|
-
params['UserData'] = Base64.encode64(user_data).delete("\n") unless user_data.
|
493
|
+
params['UserData'] = Base64.encode64(user_data).delete("\n") unless user_data.blank?
|
400
494
|
end
|
401
495
|
link = generate_request("RunInstances", params)
|
402
496
|
#debugger
|
403
|
-
instances = request_info(link, QEc2RunInstancesParser.new)
|
497
|
+
instances = request_info(link, QEc2RunInstancesParser.new(:logger => @logger))
|
404
498
|
get_desc_instances(instances)
|
405
499
|
rescue Exception
|
406
500
|
on_exception
|
@@ -421,8 +515,8 @@ module RightAws
|
|
421
515
|
# :aws_prev_state_code => 16}]
|
422
516
|
#
|
423
517
|
def terminate_instances(list=[])
|
424
|
-
link = generate_request("TerminateInstances", hash_params('InstanceId',list))
|
425
|
-
instances = request_info(link, QEc2TerminateInstancesParser.new)
|
518
|
+
link = generate_request("TerminateInstances", hash_params('InstanceId',list.to_a))
|
519
|
+
instances = request_info(link, QEc2TerminateInstancesParser.new(:logger => @logger))
|
426
520
|
instances.collect! do |instance|
|
427
521
|
{ :aws_instance_id => instance.instanceId,
|
428
522
|
:aws_shutdown_state => instance.shutdownState.name,
|
@@ -444,7 +538,7 @@ module RightAws
|
|
444
538
|
# :aws_output => "Linux version 2.6.16-xenU (builder@patchbat.amazonsa) (gcc version 4.0.1 20050727 ..."
|
445
539
|
def get_console_output(instance_id)
|
446
540
|
link = generate_request("GetConsoleOutput", { 'InstanceId.1' => instance_id })
|
447
|
-
result = request_info(link, QEc2GetConsoleOutputParser.new)
|
541
|
+
result = request_info(link, QEc2GetConsoleOutputParser.new(:logger => @logger))
|
448
542
|
{ :aws_instance_id => result.instanceId,
|
449
543
|
:aws_timestamp => result.timestamp,
|
450
544
|
:timestamp => (Time.parse(result.timestamp)).utc,
|
@@ -459,7 +553,7 @@ module RightAws
|
|
459
553
|
#
|
460
554
|
def reboot_instances(list)
|
461
555
|
link = generate_request("RebootInstances", hash_params('InstanceId', list.to_a))
|
462
|
-
request_info(link, RightBoolResponseParser.new)
|
556
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
463
557
|
rescue Exception
|
464
558
|
on_exception
|
465
559
|
end
|
@@ -480,8 +574,8 @@ module RightAws
|
|
480
574
|
# ..., {...}]
|
481
575
|
#
|
482
576
|
def describe_security_groups(list=[])
|
483
|
-
link = generate_request("DescribeSecurityGroups", hash_params('GroupName',list))
|
484
|
-
groups = request_info(link, QEc2DescribeSecurityGroupsParser.new)
|
577
|
+
link = generate_request("DescribeSecurityGroups", hash_params('GroupName',list.to_a))
|
578
|
+
groups = request_info(link, QEc2DescribeSecurityGroupsParser.new(:logger => @logger))
|
485
579
|
|
486
580
|
result = []
|
487
581
|
groups.each do |item|
|
@@ -527,7 +621,7 @@ module RightAws
|
|
527
621
|
link = generate_request("CreateSecurityGroup",
|
528
622
|
'GroupName' => name.to_s,
|
529
623
|
'GroupDescription' => description.to_s)
|
530
|
-
request_info(link, RightBoolResponseParser.new)
|
624
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
531
625
|
rescue Exception
|
532
626
|
on_exception
|
533
627
|
end
|
@@ -539,21 +633,22 @@ module RightAws
|
|
539
633
|
def delete_security_group(name)
|
540
634
|
link = generate_request("DeleteSecurityGroup",
|
541
635
|
'GroupName' => name.to_s)
|
542
|
-
request_info(link, RightBoolResponseParser.new)
|
636
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
543
637
|
rescue Exception
|
544
638
|
on_exception
|
545
639
|
end
|
546
640
|
|
547
|
-
# Authorize named ingress for security group.
|
641
|
+
# Authorize named ingress for security group. Allows instances that are member of someone
|
642
|
+
# else's security group to open connections to instances in my group.
|
548
643
|
#
|
549
|
-
# ec2.authorize_security_group_named_ingress('my_awesome_group',
|
644
|
+
# ec2.authorize_security_group_named_ingress('my_awesome_group', '7011-0219-8268', 'their_group_name') #=> true
|
550
645
|
#
|
551
646
|
def authorize_security_group_named_ingress(name, owner, group)
|
552
647
|
link = generate_request("AuthorizeSecurityGroupIngress",
|
553
648
|
'GroupName' => name.to_s,
|
554
649
|
'SourceSecurityGroupName' => group.to_s,
|
555
650
|
'SourceSecurityGroupOwnerId' => owner.to_s.gsub(/-/,''))
|
556
|
-
request_info(link, RightBoolResponseParser.new)
|
651
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
557
652
|
rescue Exception
|
558
653
|
on_exception
|
559
654
|
end
|
@@ -567,12 +662,12 @@ module RightAws
|
|
567
662
|
'GroupName' => name.to_s,
|
568
663
|
'SourceSecurityGroupName' => group.to_s,
|
569
664
|
'SourceSecurityGroupOwnerId' => owner.to_s.gsub(/-/,''))
|
570
|
-
request_info(link, RightBoolResponseParser.new)
|
665
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
571
666
|
rescue Exception
|
572
667
|
on_exception
|
573
668
|
end
|
574
669
|
|
575
|
-
# Add permission to a security group. Returns +true+ or an exception. +protocol+ is one of :'tcp'|'udp'|'icmp'
|
670
|
+
# Add permission to a security group. Returns +true+ or an exception. +protocol+ is one of :'tcp'|'udp'|'icmp'.
|
576
671
|
#
|
577
672
|
# ec2.authorize_security_group_IP_ingress('my_awesome_group', 80, 82, 'udp', '192.168.1.0/8') #=> true
|
578
673
|
# ec2.authorize_security_group_IP_ingress('my_awesome_group', -1, -1, 'icmp') #=> true
|
@@ -584,7 +679,7 @@ module RightAws
|
|
584
679
|
'FromPort' => from_port.to_s,
|
585
680
|
'ToPort' => to_port.to_s,
|
586
681
|
'CidrIp' => cidr_ip.to_s)
|
587
|
-
request_info(link, RightBoolResponseParser.new)
|
682
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
588
683
|
rescue Exception
|
589
684
|
on_exception
|
590
685
|
end
|
@@ -600,12 +695,13 @@ module RightAws
|
|
600
695
|
'FromPort' => from_port.to_s,
|
601
696
|
'ToPort' => to_port.to_s,
|
602
697
|
'CidrIp' => cidr_ip.to_s)
|
603
|
-
request_info(link, RightBoolResponseParser.new)
|
698
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
604
699
|
rescue Exception
|
605
700
|
on_exception
|
606
701
|
end
|
607
702
|
|
608
|
-
# Retrieve a list of SSH keys.
|
703
|
+
# Retrieve a list of SSH keys. Returns an array of keys or an exception. Each key is
|
704
|
+
# represented as a two-element hash.
|
609
705
|
#
|
610
706
|
# ec2.describe_key_pairs #=>
|
611
707
|
# [{:aws_fingerprint=> "01:02:03:f4:25:e6:97:e8:9b:02:1a:26:32:4e:58:6b:7a:8c:9f:03", :aws_key_name=>"key-1"},
|
@@ -613,8 +709,8 @@ module RightAws
|
|
613
709
|
# ..., {...} ]
|
614
710
|
#
|
615
711
|
def describe_key_pairs(list=[])
|
616
|
-
link = generate_request("DescribeKeyPairs", hash_params('KeyName',list))
|
617
|
-
result = request_info(link, QEc2DescribeKeyPairParser.new)
|
712
|
+
link = generate_request("DescribeKeyPairs", hash_params('KeyName',list.to_a))
|
713
|
+
result = request_info(link, QEc2DescribeKeyPairParser.new(:logger => @logger))
|
618
714
|
result.collect! do |key|
|
619
715
|
{:aws_key_name => key.keyName,
|
620
716
|
:aws_fingerprint => key.keyFingerprint }
|
@@ -624,7 +720,7 @@ module RightAws
|
|
624
720
|
on_exception
|
625
721
|
end
|
626
722
|
|
627
|
-
# Create new SSH key. Returns a hash of key's data or an exception.
|
723
|
+
# Create new SSH key. Returns a hash of the key's data or an exception.
|
628
724
|
#
|
629
725
|
# ec2.create_key_pair('my_awesome_key') #=>
|
630
726
|
# {:aws_key_name => "my_awesome_key",
|
@@ -634,7 +730,7 @@ module RightAws
|
|
634
730
|
def create_key_pair(name)
|
635
731
|
link = generate_request("CreateKeyPair",
|
636
732
|
'KeyName' => name.to_s)
|
637
|
-
key = request_info(link, QEc2CreateKeyPairParser.new)
|
733
|
+
key = request_info(link, QEc2CreateKeyPairParser.new(:logger => @logger))
|
638
734
|
{ :aws_key_name => key.keyName,
|
639
735
|
:aws_fingerprint => key.keyFingerprint,
|
640
736
|
:aws_material => key.keyMaterial}
|
@@ -642,24 +738,26 @@ module RightAws
|
|
642
738
|
on_exception
|
643
739
|
end
|
644
740
|
|
645
|
-
# Delete key pair. Returns +true+ or an exception.
|
741
|
+
# Delete a key pair. Returns +true+ or an exception.
|
646
742
|
#
|
647
743
|
# ec2.delete_key_pair('my_awesome_key') #=> true
|
648
744
|
#
|
649
745
|
def delete_key_pair(name)
|
650
746
|
link = generate_request("DeleteKeyPair",
|
651
747
|
'KeyName' => name.to_s)
|
652
|
-
request_info(link, RightBoolResponseParser.new)
|
748
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
653
749
|
rescue Exception
|
654
750
|
on_exception
|
655
751
|
end
|
752
|
+
|
753
|
+
#- Internal stuff from here on down...
|
656
754
|
|
657
755
|
|
658
756
|
#-----------------------------------------------------------------
|
659
757
|
# PARSERS: Boolean Response Parser
|
660
758
|
#-----------------------------------------------------------------
|
661
759
|
|
662
|
-
class RightBoolResponseParser < RightAWSParser
|
760
|
+
class RightBoolResponseParser < RightAWSParser
|
663
761
|
def tagend(name)
|
664
762
|
@result = @text=='true' ? true : false if name == 'return'
|
665
763
|
end
|
@@ -669,16 +767,16 @@ module RightAws
|
|
669
767
|
# PARSERS: Key Pair
|
670
768
|
#-----------------------------------------------------------------
|
671
769
|
|
672
|
-
class QEc2DescribeKeyPairType
|
770
|
+
class QEc2DescribeKeyPairType
|
673
771
|
attr_accessor :keyName
|
674
772
|
attr_accessor :keyFingerprint
|
675
773
|
end
|
676
774
|
|
677
|
-
class QEc2CreateKeyPairType < QEc2DescribeKeyPairType
|
775
|
+
class QEc2CreateKeyPairType < QEc2DescribeKeyPairType
|
678
776
|
attr_accessor :keyMaterial
|
679
777
|
end
|
680
778
|
|
681
|
-
class QEc2DescribeKeyPairParser < RightAWSParser
|
779
|
+
class QEc2DescribeKeyPairParser < RightAWSParser
|
682
780
|
def tagstart(name, attributes)
|
683
781
|
@item = QEc2DescribeKeyPairType.new if name == 'item'
|
684
782
|
end
|
@@ -694,7 +792,7 @@ module RightAws
|
|
694
792
|
end
|
695
793
|
end
|
696
794
|
|
697
|
-
class QEc2CreateKeyPairParser < RightAWSParser
|
795
|
+
class QEc2CreateKeyPairParser < RightAWSParser
|
698
796
|
def tagstart(name, attributes)
|
699
797
|
@result = QEc2CreateKeyPairType.new if !@result
|
700
798
|
end
|
@@ -711,12 +809,12 @@ module RightAws
|
|
711
809
|
# PARSERS: Security Groups
|
712
810
|
#-----------------------------------------------------------------
|
713
811
|
|
714
|
-
class QEc2UserIdGroupPairType
|
812
|
+
class QEc2UserIdGroupPairType
|
715
813
|
attr_accessor :userId
|
716
814
|
attr_accessor :groupName
|
717
815
|
end
|
718
816
|
|
719
|
-
class QEc2IpPermissionType
|
817
|
+
class QEc2IpPermissionType
|
720
818
|
attr_accessor :ipProtocol
|
721
819
|
attr_accessor :fromPort
|
722
820
|
attr_accessor :toPort
|
@@ -724,7 +822,7 @@ module RightAws
|
|
724
822
|
attr_accessor :ipRanges
|
725
823
|
end
|
726
824
|
|
727
|
-
class QEc2SecurityGroupItemType
|
825
|
+
class QEc2SecurityGroupItemType
|
728
826
|
attr_accessor :groupName
|
729
827
|
attr_accessor :groupDescription
|
730
828
|
attr_accessor :ownerId
|
@@ -732,7 +830,7 @@ module RightAws
|
|
732
830
|
end
|
733
831
|
|
734
832
|
|
735
|
-
class QEc2DescribeSecurityGroupsParser < RightAWSParser
|
833
|
+
class QEc2DescribeSecurityGroupsParser < RightAWSParser
|
736
834
|
def tagstart(name, attributes)
|
737
835
|
case name
|
738
836
|
when 'item'
|
@@ -782,17 +880,20 @@ module RightAws
|
|
782
880
|
# PARSERS: Images
|
783
881
|
#-----------------------------------------------------------------
|
784
882
|
|
785
|
-
class QEc2DescribeImagesResponseItemType
|
883
|
+
class QEc2DescribeImagesResponseItemType
|
786
884
|
attr_accessor :imageId
|
787
885
|
attr_accessor :imageState
|
788
886
|
attr_accessor :imageLocation
|
789
887
|
attr_accessor :imageOwnerId
|
790
888
|
attr_accessor :isPublic
|
889
|
+
attr_accessor :productCodes
|
791
890
|
end
|
792
891
|
|
793
|
-
class QEc2DescribeImagesParser < RightAWSParser
|
892
|
+
class QEc2DescribeImagesParser < RightAWSParser
|
794
893
|
def tagstart(name, attributes)
|
795
|
-
|
894
|
+
if name == 'item' && @xmlpath[%r{.*/imagesSet$}]
|
895
|
+
@image = QEc2DescribeImagesResponseItemType.new
|
896
|
+
end
|
796
897
|
end
|
797
898
|
def tagend(name)
|
798
899
|
case name
|
@@ -801,7 +902,8 @@ module RightAws
|
|
801
902
|
when 'imageState' ; @image.imageState = @text
|
802
903
|
when 'imageOwnerId' ; @image.imageOwnerId = @text
|
803
904
|
when 'isPublic' ; @image.isPublic = @text == 'true' ? true : false
|
804
|
-
when '
|
905
|
+
when 'productCode' ; (@image.productCodes ||= []) << @text
|
906
|
+
when 'item' ; @result << @image if @xmlpath[%r{.*/imagesSet$}]
|
805
907
|
end
|
806
908
|
end
|
807
909
|
def reset
|
@@ -809,7 +911,7 @@ module RightAws
|
|
809
911
|
end
|
810
912
|
end
|
811
913
|
|
812
|
-
class QEc2RegisterImageParser < RightAWSParser
|
914
|
+
class QEc2RegisterImageParser < RightAWSParser
|
813
915
|
def tagend(name)
|
814
916
|
@result = @text if name == 'imageId'
|
815
917
|
end
|
@@ -819,21 +921,22 @@ module RightAws
|
|
819
921
|
# PARSERS: Image Attribute
|
820
922
|
#-----------------------------------------------------------------
|
821
923
|
|
822
|
-
class QEc2LaunchPermissionItemType
|
924
|
+
class QEc2LaunchPermissionItemType
|
823
925
|
attr_accessor :groups
|
824
926
|
attr_accessor :userIds
|
825
927
|
end
|
826
928
|
|
827
|
-
class QEc2DescribeImageAttributeType
|
929
|
+
class QEc2DescribeImageAttributeType
|
828
930
|
attr_accessor :imageId
|
829
931
|
attr_accessor :launchPermission
|
932
|
+
attr_accessor :productCodes
|
830
933
|
end
|
831
934
|
|
832
|
-
class QEc2DescribeImageAttributeParser < RightAWSParser
|
935
|
+
class QEc2DescribeImageAttributeParser < RightAWSParser
|
833
936
|
def tagstart(name, attributes)
|
834
937
|
case name
|
835
938
|
when 'launchPermission'
|
836
|
-
|
939
|
+
@result.launchPermission = QEc2LaunchPermissionItemType.new
|
837
940
|
@result.launchPermission.groups = []
|
838
941
|
@result.launchPermission.userIds = []
|
839
942
|
end
|
@@ -848,6 +951,8 @@ module RightAws
|
|
848
951
|
@result.launchPermission.groups << @text if @xmlpath == 'DescribeImageAttributeResponse/launchPermission/item'
|
849
952
|
when 'userId'
|
850
953
|
@result.launchPermission.userIds << @text if @xmlpath == 'DescribeImageAttributeResponse/launchPermission/item'
|
954
|
+
when 'productCode'
|
955
|
+
(@result.productCodes ||= []) << @text
|
851
956
|
end
|
852
957
|
end
|
853
958
|
def reset
|
@@ -859,12 +964,12 @@ module RightAws
|
|
859
964
|
# PARSERS: Instances
|
860
965
|
#-----------------------------------------------------------------
|
861
966
|
|
862
|
-
class QEc2InstanceStateType
|
967
|
+
class QEc2InstanceStateType
|
863
968
|
attr_accessor :code
|
864
969
|
attr_accessor :name
|
865
970
|
end
|
866
971
|
|
867
|
-
class QEc2RunningInstancesItemType
|
972
|
+
class QEc2RunningInstancesItemType
|
868
973
|
attr_accessor :instanceId
|
869
974
|
attr_accessor :imageId
|
870
975
|
attr_accessor :instanceState
|
@@ -873,16 +978,17 @@ module RightAws
|
|
873
978
|
attr_accessor :reason
|
874
979
|
attr_accessor :keyName
|
875
980
|
attr_accessor :amiLaunchIndex
|
981
|
+
attr_accessor :productCodes
|
876
982
|
end
|
877
983
|
|
878
|
-
class QEc2DescribeInstancesType
|
984
|
+
class QEc2DescribeInstancesType
|
879
985
|
attr_accessor :reservationId
|
880
986
|
attr_accessor :ownerId
|
881
987
|
attr_accessor :groupSet
|
882
988
|
attr_accessor :instancesSet
|
883
989
|
end
|
884
990
|
|
885
|
-
class QEc2DescribeInstancesParser < RightAWSParser
|
991
|
+
class QEc2DescribeInstancesParser < RightAWSParser
|
886
992
|
def tagstart(name, attributes)
|
887
993
|
case name
|
888
994
|
when 'item'
|
@@ -922,6 +1028,7 @@ module RightAws
|
|
922
1028
|
elsif @xmlpath=='DescribeInstancesResponse/reservationSet'
|
923
1029
|
@result << @reservation
|
924
1030
|
end
|
1031
|
+
when 'productCode' ; (@instance.productCodes ||= []) << @text
|
925
1032
|
end
|
926
1033
|
end
|
927
1034
|
def reset
|
@@ -929,7 +1036,16 @@ module RightAws
|
|
929
1036
|
end
|
930
1037
|
end
|
931
1038
|
|
932
|
-
class
|
1039
|
+
class QEc2ConfirmProductInstanceParser < RightAWSParser
|
1040
|
+
def tagend(name)
|
1041
|
+
@result = @text if name == 'ownerId'
|
1042
|
+
end
|
1043
|
+
def reset
|
1044
|
+
@result = nil
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
class QEc2RunInstancesParser < RightAWSParser
|
933
1049
|
def tagstart(name, attributes)
|
934
1050
|
case name
|
935
1051
|
when 'RunInstancesResponse'
|
@@ -966,6 +1082,7 @@ module RightAws
|
|
966
1082
|
when 'item'
|
967
1083
|
@reservation.instancesSet << @instance if @xmlpath == 'RunInstancesResponse/instancesSet'
|
968
1084
|
when 'RunInstancesResponse'; @result << @reservation
|
1085
|
+
when 'productCode' ; (@instance.productCodes ||= []) << @text
|
969
1086
|
end
|
970
1087
|
end
|
971
1088
|
def reset
|
@@ -973,13 +1090,13 @@ module RightAws
|
|
973
1090
|
end
|
974
1091
|
end
|
975
1092
|
|
976
|
-
class QEc2TerminateInstancesResponseInfoType
|
1093
|
+
class QEc2TerminateInstancesResponseInfoType
|
977
1094
|
attr_accessor :instanceId
|
978
1095
|
attr_accessor :shutdownState
|
979
1096
|
attr_accessor :previousState
|
980
1097
|
end
|
981
1098
|
|
982
|
-
class QEc2TerminateInstancesParser < RightAWSParser
|
1099
|
+
class QEc2TerminateInstancesParser < RightAWSParser
|
983
1100
|
def tagstart(name, attributes)
|
984
1101
|
if name == 'item'
|
985
1102
|
@instance = QEc2TerminateInstancesResponseInfoType.new
|
@@ -1010,13 +1127,13 @@ module RightAws
|
|
1010
1127
|
# PARSERS: Console
|
1011
1128
|
#-----------------------------------------------------------------
|
1012
1129
|
|
1013
|
-
class QEc2GetConsoleOutputResponseType
|
1130
|
+
class QEc2GetConsoleOutputResponseType
|
1014
1131
|
attr_accessor :instanceId
|
1015
1132
|
attr_accessor :timestamp
|
1016
1133
|
attr_accessor :output
|
1017
1134
|
end
|
1018
1135
|
|
1019
|
-
class QEc2GetConsoleOutputParser < RightAWSParser
|
1136
|
+
class QEc2GetConsoleOutputParser < RightAWSParser
|
1020
1137
|
def tagend(name)
|
1021
1138
|
case name
|
1022
1139
|
when 'instanceId' ; @result.instanceId = @text
|