aboisvert_aws 3.0.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 +329 -0
- data/Manifest.txt +61 -0
- data/README.txt +163 -0
- data/Rakefile +130 -0
- data/lib/acf/right_acf_interface.rb +549 -0
- data/lib/acf/right_acf_invalidations.rb +144 -0
- data/lib/acf/right_acf_origin_access_identities.rb +230 -0
- data/lib/acf/right_acf_streaming_interface.rb +229 -0
- data/lib/acw/right_acw_interface.rb +248 -0
- data/lib/as/right_as_interface.rb +698 -0
- data/lib/awsbase/benchmark_fix.rb +39 -0
- data/lib/awsbase/right_awsbase.rb +1343 -0
- data/lib/awsbase/support.rb +35 -0
- data/lib/awsbase/version.rb +9 -0
- data/lib/ec2/right_ec2.rb +541 -0
- data/lib/ec2/right_ec2_ebs.rb +481 -0
- data/lib/ec2/right_ec2_images.rb +444 -0
- data/lib/ec2/right_ec2_instances.rb +788 -0
- data/lib/ec2/right_ec2_monitoring.rb +70 -0
- data/lib/ec2/right_ec2_placement_groups.rb +108 -0
- data/lib/ec2/right_ec2_reserved_instances.rb +184 -0
- data/lib/ec2/right_ec2_security_groups.rb +491 -0
- data/lib/ec2/right_ec2_spot_instances.rb +422 -0
- data/lib/ec2/right_ec2_tags.rb +139 -0
- data/lib/ec2/right_ec2_vpc.rb +590 -0
- data/lib/ec2/right_ec2_vpc2.rb +381 -0
- data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
- data/lib/elb/right_elb_interface.rb +573 -0
- data/lib/emr/right_emr_interface.rb +727 -0
- data/lib/iam/right_iam_access_keys.rb +71 -0
- data/lib/iam/right_iam_groups.rb +195 -0
- data/lib/iam/right_iam_interface.rb +341 -0
- data/lib/iam/right_iam_mfa_devices.rb +67 -0
- data/lib/iam/right_iam_users.rb +251 -0
- data/lib/rds/right_rds_interface.rb +1384 -0
- data/lib/right_aws.rb +86 -0
- data/lib/route_53/right_route_53_interface.rb +640 -0
- data/lib/s3/right_s3.rb +1138 -0
- data/lib/s3/right_s3_interface.rb +1278 -0
- data/lib/sdb/active_sdb.rb +1107 -0
- data/lib/sdb/right_sdb_interface.rb +762 -0
- data/lib/sns/right_sns_interface.rb +286 -0
- data/lib/sqs/right_sqs.rb +387 -0
- data/lib/sqs/right_sqs_gen2.rb +342 -0
- data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
- data/lib/sqs/right_sqs_interface.rb +593 -0
- data/right_aws.gemspec +90 -0
- data/test/README.mdown +39 -0
- data/test/acf/test_helper.rb +2 -0
- data/test/acf/test_right_acf.rb +138 -0
- data/test/awsbase/test_helper.rb +2 -0
- data/test/awsbase/test_right_awsbase.rb +11 -0
- data/test/ec2/test_helper.rb +2 -0
- data/test/ec2/test_right_ec2.rb +107 -0
- data/test/elb/test_helper.rb +2 -0
- data/test/elb/test_right_elb.rb +43 -0
- data/test/http_connection.rb +87 -0
- data/test/rds/test_helper.rb +2 -0
- data/test/rds/test_right_rds.rb +120 -0
- data/test/route_53/fixtures/a_record.xml +18 -0
- data/test/route_53/fixtures/alias_record.xml +18 -0
- data/test/route_53/test_helper.rb +2 -0
- data/test/route_53/test_right_route_53.rb +141 -0
- data/test/s3/test_helper.rb +2 -0
- data/test/s3/test_right_s3.rb +528 -0
- data/test/s3/test_right_s3_stubbed.rb +97 -0
- data/test/sdb/test_active_sdb.rb +357 -0
- data/test/sdb/test_batch_put_attributes.rb +54 -0
- data/test/sdb/test_helper.rb +3 -0
- data/test/sdb/test_right_sdb.rb +253 -0
- data/test/sns/test_helper.rb +2 -0
- data/test/sns/test_right_sns.rb +153 -0
- data/test/sqs/test_helper.rb +2 -0
- data/test/sqs/test_right_sqs.rb +285 -0
- data/test/sqs/test_right_sqs_gen2.rb +264 -0
- data/test/test_credentials.rb +37 -0
- data/test/ts_right_aws.rb +15 -0
- metadata +257 -0
@@ -0,0 +1,444 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 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
|
+
class Ec2
|
27
|
+
|
28
|
+
#-----------------------------------------------------------------
|
29
|
+
# Images
|
30
|
+
#-----------------------------------------------------------------
|
31
|
+
|
32
|
+
# Describe images helper
|
33
|
+
# params:
|
34
|
+
# { 'ImageId' => ['id1', ..., 'idN'],
|
35
|
+
# 'Owner' => ['self', ..., 'userN'],
|
36
|
+
# 'ExecutableBy' => ['self', 'all', ..., 'userN']
|
37
|
+
# }
|
38
|
+
def ec2_describe_images(params={}, options={}, cache_for=nil) #:nodoc:
|
39
|
+
request_hash = {}
|
40
|
+
params.each { |list_by, list| request_hash.merge! amazonize_list(list_by, Array(list)) }
|
41
|
+
request_hash.merge!(amazonize_list(['Filter.?.Name', 'Filter.?.Value.?'], options[:filters])) unless options[:filters].right_blank?
|
42
|
+
link = generate_request("DescribeImages", request_hash)
|
43
|
+
request_cache_or_info cache_for, link, QEc2DescribeImagesParser, @@bench, cache_for
|
44
|
+
rescue Exception
|
45
|
+
on_exception
|
46
|
+
end
|
47
|
+
|
48
|
+
# Retrieve a list of images.
|
49
|
+
#
|
50
|
+
# Accepts a list of images and/or a set of filters as the last parameter.
|
51
|
+
#
|
52
|
+
# Filters: architecture, block-device-mapping.delete-on-termination block-device-mapping.device-name,
|
53
|
+
# block-device-mapping.snapshot-id, block-device-mapping.volume-size, description, image-id, image-type,
|
54
|
+
# is-public, kernel-id, manifest-location, name, owner-alias, owner-id, platform, product-code,
|
55
|
+
# ramdisk-id, root-device-name, root-device-type, state, state-reason-code, state-reason-message,
|
56
|
+
# tag-key, tag-value, tag:key, virtualization-type
|
57
|
+
#
|
58
|
+
# ec2.describe_images #=>
|
59
|
+
# [{:description=>"EBS backed Fedora core 8 i386",
|
60
|
+
# :aws_architecture=>"i386",
|
61
|
+
# :aws_id=>"ami-c2a3f5d4",
|
62
|
+
# :aws_image_type=>"machine",
|
63
|
+
# :root_device_name=>"/dev/sda1",
|
64
|
+
# :image_class=>"elastic",
|
65
|
+
# :aws_owner=>"937766719418",
|
66
|
+
# :aws_location=>"937766719418/EBS backed FC8 i386",
|
67
|
+
# :aws_state=>"available",
|
68
|
+
# :block_device_mappings=>
|
69
|
+
# [{:ebs_snapshot_id=>"snap-829a20eb",
|
70
|
+
# :ebs_delete_on_termination=>true,
|
71
|
+
# :device_name=>"/dev/sda1"}],
|
72
|
+
# :name=>"EBS backed FC8 i386",
|
73
|
+
# :aws_is_public=>true}, ... ]
|
74
|
+
#
|
75
|
+
# ec2.describe_images(:filters => { 'image-type' => 'kernel', 'state' => 'available', 'tag:MyTag' => 'MyValue'})
|
76
|
+
#
|
77
|
+
# ec2.describe_images("ari-fda54b94", "ami-2ee80247", "aki-00896a69",
|
78
|
+
# :filters => { 'image-type' => 'kernel', 'state' => 'available' }) #=>
|
79
|
+
# [{:root_device_type=>"instance-store",
|
80
|
+
# :aws_id=>"aki-00896a69",
|
81
|
+
# :aws_image_type=>"kernel",
|
82
|
+
# :aws_location=>
|
83
|
+
# "karmic-kernel-zul/ubuntu-kernel-2.6.31-300-ec2-i386-20091002-test-04.manifest.xml",
|
84
|
+
# :virtualization_type=>"paravirtual",
|
85
|
+
# :aws_state=>"available",
|
86
|
+
# :aws_owner=>"099720109477",
|
87
|
+
# :tags=>{},
|
88
|
+
# :aws_is_public=>true,
|
89
|
+
# :aws_architecture=>"i386"}]
|
90
|
+
#
|
91
|
+
# P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeImages.html
|
92
|
+
#
|
93
|
+
def describe_images(*list_and_options)
|
94
|
+
list, options = AwsUtils::split_items_and_params(list_and_options)
|
95
|
+
cache_for = (list.right_blank? && options[:filters].right_blank?) ? :describe_images : nil
|
96
|
+
ec2_describe_images( {'ImageId'=>list}, options, cache_for)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Retrieve a list of images by image owner.
|
100
|
+
#
|
101
|
+
# Accepts a list of images and/or a set of filters as the last parameter.
|
102
|
+
#
|
103
|
+
# Filters: architecture, block-device-mapping.delete-on-termination block-device-mapping.device-name,
|
104
|
+
# block-device-mapping.snapshot-id, block-device-mapping.volume-size, description, image-id, image-type,
|
105
|
+
# is-public, kernel-id, manifest-location, name, owner-alias, owner-id, platform, product-code,
|
106
|
+
# ramdisk-id, root-device-name, root-device-type, state, state-reason-code, state-reason-message,
|
107
|
+
# tag-key, tag-value, tag:key, virtualization-type
|
108
|
+
#
|
109
|
+
# ec2.describe_images_by_owner('522821470517')
|
110
|
+
# ec2.describe_images_by_owner('self', :filters => { 'block-device-mapping.delete-on-termination' => 'false' })
|
111
|
+
#
|
112
|
+
# P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeImages.html
|
113
|
+
#
|
114
|
+
def describe_images_by_owner(*list_and_options)
|
115
|
+
list, options = AwsUtils::split_items_and_params(list_and_options)
|
116
|
+
list = ['self'] if list.right_blank?
|
117
|
+
cache_for = (list==['self'] && options[:filters].right_blank?) ? :describe_images_by_owner : nil
|
118
|
+
ec2_describe_images( {'Owner'=>list}, options, cache_for)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Retrieve a list of images by image executable by.
|
122
|
+
#
|
123
|
+
# Accepts a list of images and/or a set of filters as the last parameter.
|
124
|
+
#
|
125
|
+
# Filters: architecture, block-device-mapping.delete-on-termination block-device-mapping.device-name,
|
126
|
+
# block-device-mapping.snapshot-id, block-device-mapping.volume-size, description, image-id, image-type,
|
127
|
+
# is-public, kernel-id, manifest-location, name, owner-alias, owner-id, platform, product-code,
|
128
|
+
# ramdisk-id, root-device-name, root-device-type, state, state-reason-code, state-reason-message,
|
129
|
+
# tag-key, tag-value, tag:key, virtualization-type
|
130
|
+
#
|
131
|
+
# ec2.describe_images_by_executable_by('522821470517')
|
132
|
+
# ec2.describe_images_by_executable_by('self')
|
133
|
+
# ec2.describe_images_by_executable_by('all', :filters => { 'architecture' => 'i386' })
|
134
|
+
#
|
135
|
+
# P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeImages.html
|
136
|
+
#
|
137
|
+
def describe_images_by_executable_by(*list_and_options)
|
138
|
+
list, options = AwsUtils::split_items_and_params(list_and_options)
|
139
|
+
list = ['self'] if list.right_blank?
|
140
|
+
cache_for = (list==['self'] && options[:filters].right_blank?) ? :describe_images_by_executable_by : nil
|
141
|
+
ec2_describe_images( {'ExecutableBy'=>list}, options, cache_for)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Register new image at Amazon.
|
145
|
+
# Options: :image_location, :name, :description, :architecture, :kernel_id, :ramdisk_id,
|
146
|
+
# :root_device_name, :block_device_mappings, :virtualizationt_type(hvm|paravirtual)
|
147
|
+
#
|
148
|
+
# Returns new image id.
|
149
|
+
#
|
150
|
+
# # Register S3 image
|
151
|
+
# ec2.register_image('bucket_for_k_dzreyev/image_bundles/kd__CentOS_1_10_2009_10_21_13_30_43_MSD/image.manifest.xml') #=> 'ami-e444444d'
|
152
|
+
#
|
153
|
+
# # or
|
154
|
+
# image_reg_params = { :image_location => 'bucket_for_k_dzreyev/image_bundles/kd__CentOS_1_10_2009_10_21_13_30_43_MSD/image.manifest.xml',
|
155
|
+
# :name => 'my-test-one-1',
|
156
|
+
# :description => 'My first test image' }
|
157
|
+
# ec2.register_image(image_reg_params) #=> "ami-bca1f7aa"
|
158
|
+
#
|
159
|
+
# # Register EBS image
|
160
|
+
# image_reg_params = { :name => 'my-test-image',
|
161
|
+
# :description => 'My first test image',
|
162
|
+
# :root_device_name => "/dev/sda1",
|
163
|
+
# :block_device_mappings => [ { :ebs_snapshot_id=>"snap-7360871a",
|
164
|
+
# :ebs_delete_on_termination=>true,
|
165
|
+
# :device_name=>"/dev/sda1"},
|
166
|
+
# { :virtual_name => 'ephemeral0',}
|
167
|
+
# :device_name=>"/dev/sdb"} ]
|
168
|
+
# ec2.register_image(image_reg_params) #=> "ami-b2a1f7a4"
|
169
|
+
#
|
170
|
+
def register_image(options)
|
171
|
+
case
|
172
|
+
when options.is_a?(String)
|
173
|
+
options = { :image_location => options }
|
174
|
+
when !options.is_a?(Hash)
|
175
|
+
raise "Unsupported options type"
|
176
|
+
end
|
177
|
+
params = {}
|
178
|
+
params['ImageLocation'] = options[:image_location] if options[:image_location]
|
179
|
+
params['Name'] = options[:name] if options[:name]
|
180
|
+
params['Description'] = options[:description] if options[:description]
|
181
|
+
params['Architecture'] = options[:architecture] if options[:architecture]
|
182
|
+
params['KernelId'] = options[:kernel_id] if options[:kernel_id]
|
183
|
+
params['RamdiskId'] = options[:ramdisk_id] if options[:ramdisk_id]
|
184
|
+
params['RootDeviceName'] = options[:root_device_name] if options[:root_device_name]
|
185
|
+
params['VirtualizationType'] = options[:virtualization_type] if options[:virtualization_type]
|
186
|
+
# params['SnapshotId'] = options[:snapshot_id] if options[:snapshot_id]
|
187
|
+
params.merge!(amazonize_block_device_mappings(options[:block_device_mappings]))
|
188
|
+
link = generate_request("RegisterImage", params)
|
189
|
+
request_info(link, QEc2RegisterImageParser.new(:logger => @logger))
|
190
|
+
rescue Exception
|
191
|
+
on_exception
|
192
|
+
end
|
193
|
+
|
194
|
+
# Deregister image at Amazon. Returns +true+ or an exception.
|
195
|
+
#
|
196
|
+
# ec2.deregister_image('ami-e444444d') #=> true
|
197
|
+
#
|
198
|
+
def deregister_image(image_id)
|
199
|
+
link = generate_request("DeregisterImage",
|
200
|
+
'ImageId' => image_id.to_s)
|
201
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
202
|
+
rescue Exception
|
203
|
+
on_exception
|
204
|
+
end
|
205
|
+
|
206
|
+
# Describe image attributes.
|
207
|
+
#
|
208
|
+
# Returns: String (or nil) for 'description', 'kernel', 'ramdisk'; Hash for 'launchPermission'; Array for 'productCodes', 'blockDeviceMapping'
|
209
|
+
#
|
210
|
+
# ec2.describe_image_attribute('ami-00000000', 'description') #=> 'My cool Image'
|
211
|
+
# ec2.describe_image_attribute('ami-00000000', 'launchPermission') #=> {:user_ids=>["443739700000", "115864000000", "309179000000", "857501300000"]}
|
212
|
+
# ec2.describe_image_attribute('ami-00000000', 'productCodes') #=> ["8ED10000"]
|
213
|
+
# ec2.describe_image_attribute('ami-00000000', 'kernel') #=> "aki-9b00e5f2"
|
214
|
+
# ec2.describe_image_attribute('ami-00000000', 'ramdisk') #=> nil
|
215
|
+
# ec2.describe_image_attribute('ami-00000000', 'blockDeviceMapping') #=> [{:device_name=>"sda2", :virtual_name=>"ephemeral0"},
|
216
|
+
# {:device_name=>"sda1", :virtual_name=>"ami"},
|
217
|
+
# {:device_name=>"/dev/sda1", :virtual_name=>"root"},
|
218
|
+
# {:device_name=>"sda3", :virtual_name=>"swap"}]
|
219
|
+
#
|
220
|
+
def describe_image_attribute(image_id, attribute='launchPermission')
|
221
|
+
link = generate_request("DescribeImageAttribute",
|
222
|
+
'ImageId' => image_id,
|
223
|
+
'Attribute' => attribute)
|
224
|
+
request_info(link, QEc2DescribeImageAttributeParser.new(:logger => @logger))
|
225
|
+
rescue Exception
|
226
|
+
on_exception
|
227
|
+
end
|
228
|
+
|
229
|
+
# Reset image attribute. Currently, only 'launchPermission' is supported. Returns +true+ or an exception.
|
230
|
+
#
|
231
|
+
# ec2.reset_image_attribute('ami-e444444d') #=> true
|
232
|
+
#
|
233
|
+
def reset_image_attribute(image_id, attribute='launchPermission')
|
234
|
+
link = generate_request("ResetImageAttribute",
|
235
|
+
'ImageId' => image_id,
|
236
|
+
'Attribute' => attribute)
|
237
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
238
|
+
rescue Exception
|
239
|
+
on_exception
|
240
|
+
end
|
241
|
+
|
242
|
+
# Modify an image's attributes. It is recommended that you use
|
243
|
+
# modify_image_launch_perm_add_users, modify_image_launch_perm_remove_users, etc.
|
244
|
+
# instead of modify_image_attribute because the signature of
|
245
|
+
# modify_image_attribute may change with EC2 service changes.
|
246
|
+
#
|
247
|
+
# Attribute can take next values: 'launchPermission', 'productCode', 'description'.
|
248
|
+
# Value is a String for'description'. is a String or an Array for 'productCode' and
|
249
|
+
# is a Hash {:add_user_ids, :add_groups, :remove_user_ids, :remove_groups } for 'launchPermission'.
|
250
|
+
#
|
251
|
+
def modify_image_attribute(image_id, attribute, value)
|
252
|
+
params = { 'ImageId' => image_id }
|
253
|
+
case attribute.to_s
|
254
|
+
when 'launchPermission'
|
255
|
+
params.update(amazonize_list('LaunchPermission.Add.?.UserId', value[:add_user_ids]))
|
256
|
+
params.update(amazonize_list('LaunchPermission.Add.?.Group', value[:add_groups]))
|
257
|
+
params.update(amazonize_list('LaunchPermission.Remove.?.UserId', value[:remove_user_ids]))
|
258
|
+
params.update(amazonize_list('LaunchPermission.Remove.?.Group', value[:remove_groups]))
|
259
|
+
when 'productCode'
|
260
|
+
params.update(amazonize_list('ProductCode', value))
|
261
|
+
when 'description'
|
262
|
+
params['Description.Value'] = value
|
263
|
+
end
|
264
|
+
link = generate_request("ModifyImageAttribute", params)
|
265
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
266
|
+
rescue Exception
|
267
|
+
on_exception
|
268
|
+
end
|
269
|
+
|
270
|
+
# Grant image launch permissions to users.
|
271
|
+
# Parameter +user_id+ is a list of user AWS account ids.
|
272
|
+
# Returns +true+ or an exception.
|
273
|
+
#
|
274
|
+
# ec2.modify_image_launch_perm_add_users('ami-e444444d',['000000000777','000000000778']) #=> true
|
275
|
+
def modify_image_launch_perm_add_users(image_id, *user_ids)
|
276
|
+
modify_image_attribute(image_id, 'launchPermission', :add_user_ids => user_ids.flatten)
|
277
|
+
end
|
278
|
+
|
279
|
+
# Revokes image launch permissions for users. +user_id+ is a list of users AWS accounts ids. Returns +true+ or an exception.
|
280
|
+
#
|
281
|
+
# ec2.modify_image_launch_perm_remove_users('ami-e444444d',['000000000777','000000000778']) #=> true
|
282
|
+
#
|
283
|
+
def modify_image_launch_perm_remove_users(image_id, *user_ids)
|
284
|
+
modify_image_attribute(image_id, 'launchPermission', :remove_user_ids => user_ids.flatten)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Add image launch permissions for users groups (currently only 'all' is supported, which gives public launch permissions).
|
288
|
+
# Returns +true+ or an exception.
|
289
|
+
#
|
290
|
+
# ec2.modify_image_launch_perm_add_groups('ami-e444444d') #=> true
|
291
|
+
#
|
292
|
+
def modify_image_launch_perm_add_groups(image_id, *groups)
|
293
|
+
modify_image_attribute(image_id, 'launchPermission', :add_groups => groups.flatten)
|
294
|
+
end
|
295
|
+
|
296
|
+
# Remove image launch permissions for users groups (currently only 'all' is supported, which gives public launch permissions).
|
297
|
+
#
|
298
|
+
# ec2.modify_image_launch_perm_remove_groups('ami-e444444d') #=> true
|
299
|
+
#
|
300
|
+
def modify_image_launch_perm_remove_groups(image_id, *groups)
|
301
|
+
modify_image_attribute(image_id, 'launchPermission', :remove_groups => groups.flatten)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Add product code to image
|
305
|
+
#
|
306
|
+
# ec2.modify_image_product_code('ami-e444444d','0ABCDEF') #=> true
|
307
|
+
#
|
308
|
+
def modify_image_product_code(image_id, product_codes=[])
|
309
|
+
modify_image_attribute(image_id, 'productCodes',product_codes)
|
310
|
+
end
|
311
|
+
|
312
|
+
# Modify image description
|
313
|
+
#
|
314
|
+
# ec2.modify_image_product_code('ami-e444444d','My cool image') #=> true
|
315
|
+
#
|
316
|
+
def modify_image_description(image_id, description)
|
317
|
+
modify_image_attribute(image_id, 'description', description)
|
318
|
+
end
|
319
|
+
|
320
|
+
# Create a new image.
|
321
|
+
# Options: :name, :description, :no_reboot(bool)
|
322
|
+
#
|
323
|
+
# ec2.create_image(instance, :description => 'KD: test#1',
|
324
|
+
# :no_reboot => true,
|
325
|
+
# :name => 'kd-1' ) #=> "ami-84a1f792"
|
326
|
+
#
|
327
|
+
def create_image(instance_aws_id, options={})
|
328
|
+
params = { 'InstanceId' => instance_aws_id }
|
329
|
+
params['Name'] = options[:name] unless options[:name].right_blank?
|
330
|
+
params['Description'] = options[:description] unless options[:description].right_blank?
|
331
|
+
params['NoReboot'] = options[:no_reboot].to_s unless options[:no_reboot].nil?
|
332
|
+
link = generate_request("CreateImage", params)
|
333
|
+
request_info(link, QEc2RegisterImageParser.new(:logger => @logger))
|
334
|
+
end
|
335
|
+
|
336
|
+
#-----------------------------------------------------------------
|
337
|
+
# PARSERS: Images
|
338
|
+
#-----------------------------------------------------------------
|
339
|
+
|
340
|
+
class QEc2DescribeImagesParser < RightAWSParser #:nodoc:
|
341
|
+
def tagstart(name, attributes)
|
342
|
+
case full_tag_name
|
343
|
+
when %r{/imagesSet/item$}
|
344
|
+
@item = { :tags => {} }
|
345
|
+
when %r{/blockDeviceMapping/item$}
|
346
|
+
@item[:block_device_mappings] ||= []
|
347
|
+
@block_device_mapping = {}
|
348
|
+
when %r{/tagSet/item$}
|
349
|
+
@aws_tag = {}
|
350
|
+
end
|
351
|
+
end
|
352
|
+
def tagend(name)
|
353
|
+
case name
|
354
|
+
when 'imageId' then @item[:aws_id] = @text
|
355
|
+
when 'imageLocation' then @item[:aws_location] = @text
|
356
|
+
when 'imageState' then @item[:aws_state] = @text
|
357
|
+
when 'imageOwnerId' then @item[:aws_owner] = @text
|
358
|
+
when 'isPublic' then @item[:aws_is_public] = @text == 'true' ? true : false
|
359
|
+
when 'productCode' then (@item[:aws_product_codes] ||= []) << @text
|
360
|
+
when 'architecture' then @item[:aws_architecture] = @text
|
361
|
+
when 'imageType' then @item[:aws_image_type] = @text
|
362
|
+
when 'kernelId' then @item[:aws_kernel_id] = @text
|
363
|
+
when 'ramdiskId' then @item[:aws_ramdisk_id] = @text
|
364
|
+
when 'platform' then @item[:aws_platform] = @text
|
365
|
+
when 'imageOwnerAlias' then @item[:image_owner_alias] = @text
|
366
|
+
when 'name' then @item[:name] = @text
|
367
|
+
when 'description' then @item[:description] = @text
|
368
|
+
when 'rootDeviceType' then @item[:root_device_type] = @text
|
369
|
+
when 'rootDeviceName' then @item[:root_device_name] = @text
|
370
|
+
when 'imageClass' then @item[:image_class] = @text
|
371
|
+
when 'virtualizationType' then @item[:virtualization_type] = @text
|
372
|
+
when 'hypervisor' then @item [:hypervisor] = @text
|
373
|
+
else
|
374
|
+
case full_tag_name
|
375
|
+
when %r{/stateReason/code$} then @item[:state_reason_code] = @text.to_i
|
376
|
+
when %r{/stateReason/message$} then @item[:state_reason_message] = @text
|
377
|
+
when %r{/blockDeviceMapping/item} # no trailing $
|
378
|
+
case name
|
379
|
+
when 'deviceName' then @block_device_mapping[:device_name] = @text
|
380
|
+
when 'virtualName' then @block_device_mapping[:virtual_name] = @text
|
381
|
+
when 'volumeSize' then @block_device_mapping[:ebs_volume_size] = @text.to_i
|
382
|
+
when 'snapshotId' then @block_device_mapping[:ebs_snapshot_id] = @text
|
383
|
+
when 'deleteOnTermination' then @block_device_mapping[:ebs_delete_on_termination] = @text == 'true' ? true : false
|
384
|
+
when 'item' then @item[:block_device_mappings] << @block_device_mapping
|
385
|
+
end
|
386
|
+
when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
|
387
|
+
when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
|
388
|
+
when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
|
389
|
+
when %r{/imagesSet/item$} then @result << @item
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
def reset
|
394
|
+
@result = []
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
class QEc2RegisterImageParser < RightAWSParser #:nodoc:
|
399
|
+
def tagend(name)
|
400
|
+
@result = @text if name == 'imageId'
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
#-----------------------------------------------------------------
|
405
|
+
# PARSERS: Image Attribute
|
406
|
+
#-----------------------------------------------------------------
|
407
|
+
|
408
|
+
class QEc2DescribeImageAttributeParser < RightAWSParser #:nodoc:
|
409
|
+
def tagstart(name, attributes)
|
410
|
+
case full_tag_name
|
411
|
+
when %r{launchPermission$} then @result = {}
|
412
|
+
when %r{productCodes$} then @result = []
|
413
|
+
when %r{blockDeviceMapping$} then @result = []
|
414
|
+
when %r{blockDeviceMapping/item$} then @block_device_mapping = {}
|
415
|
+
end
|
416
|
+
end
|
417
|
+
def tagend(name)
|
418
|
+
case full_tag_name
|
419
|
+
when %r{/kernel/value$} then @result = @text
|
420
|
+
when %r{/ramdisk/value$} then @result = @text
|
421
|
+
when %r{/description/value$} then @result = @text
|
422
|
+
when %r{/productCode$} then @result << @text
|
423
|
+
when %r{launchPermission/item/group$} then (@result[:groups] ||=[]) << @text
|
424
|
+
when %r{launchPermission/item/userId$} then (@result[:user_ids]||=[]) << @text
|
425
|
+
when %r{/blockDeviceMapping/item} # no trailing $
|
426
|
+
case name
|
427
|
+
when 'deviceName' then @block_device_mapping[:device_name] = @text
|
428
|
+
when 'virtualName' then @block_device_mapping[:virtual_name] = @text
|
429
|
+
when 'noDevice' then @block_device_mapping[:no_device] = @text
|
430
|
+
when 'snapshotId' then @block_device_mapping[:ebs_snapshot_id] = @text
|
431
|
+
when 'volumeSize' then @block_device_mapping[:ebs_volume_size] = @text
|
432
|
+
when 'deleteOnTermination' then @block_device_mapping[:ebs_delete_on_termination] = @text == 'true' ? true : false
|
433
|
+
when 'item' then @result << @block_device_mapping
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
def reset
|
438
|
+
@result = nil
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|
@@ -0,0 +1,788 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 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
|
+
class Ec2
|
27
|
+
|
28
|
+
#-----------------------------------------------------------------
|
29
|
+
# Instances
|
30
|
+
#-----------------------------------------------------------------
|
31
|
+
|
32
|
+
def get_desc_instances(instances) # :nodoc:
|
33
|
+
result = []
|
34
|
+
instances.each do |reservation|
|
35
|
+
reservation[:instances_set].each do |instance|
|
36
|
+
# Parse and remove timestamp from the reason string. The timestamp is of
|
37
|
+
# the request, not when EC2 took action, thus confusing & useless...
|
38
|
+
instance[:aws_reason] = instance[:aws_reason].sub(/\(\d[^)]*GMT\) */, '')
|
39
|
+
instance[:aws_owner] = reservation[:aws_owner]
|
40
|
+
instance[:aws_reservation_id] = reservation[:aws_reservation_id]
|
41
|
+
# Security Groups
|
42
|
+
instance[:groups] = instance[:groups].right_blank? ? reservation[:aws_groups] : instance[:groups]
|
43
|
+
result << instance
|
44
|
+
end
|
45
|
+
end
|
46
|
+
result
|
47
|
+
rescue Exception
|
48
|
+
on_exception
|
49
|
+
end
|
50
|
+
|
51
|
+
# Retrieve information about EC2 instances.
|
52
|
+
#
|
53
|
+
# Accepts a list of instances and/or a set of filters as the last parameter.
|
54
|
+
#
|
55
|
+
# Filters: architecture, availability-zone, block-device-mapping.attach-time, block-device-mapping.delete-on-termination,
|
56
|
+
# block-device-mapping.device-name, block-device-mapping.status, block-device-mapping.volume-id, client-token, dns-name,
|
57
|
+
# group-id, image-id, instance-id, instance-lifecycle, instance-state-code, instance-state-name, instance-type, ip-address,
|
58
|
+
# kernel-id, key-name, launch-index, launch-time, monitoring-state, owner-id, placement-group-name, platform,
|
59
|
+
# private-dns-name, private-ip-address, product-code, ramdisk-id, reason, requester-id, reservation-id, root-device-name,
|
60
|
+
# root-device-type, spot-instance-request-id, state-reason-code, state-reason-message, subnet-id, tag-key, tag-value,
|
61
|
+
# tag:key, virtualization-type, vpc-id,
|
62
|
+
#
|
63
|
+
#
|
64
|
+
# ec2.describe_instances #=>
|
65
|
+
# [{:source_dest_check=>true,
|
66
|
+
# :subnet_id=>"subnet-da6cf9b3",
|
67
|
+
# :aws_kernel_id=>"aki-3932d150",
|
68
|
+
# :ami_launch_index=>"0",
|
69
|
+
# :tags=>{},
|
70
|
+
# :aws_reservation_id=>"r-7cd25c11",
|
71
|
+
# :aws_owner=>"826693181925",
|
72
|
+
# :state_reason_code=>"Client.UserInitiatedShutdown",
|
73
|
+
# :aws_instance_id=>"i-2d898e41",
|
74
|
+
# :hypervisor=>"xen",
|
75
|
+
# :root_device_name=>"/dev/sda1",
|
76
|
+
# :aws_ramdisk_id=>"ari-c515f6ac",
|
77
|
+
# :aws_instance_type=>"m1.large",
|
78
|
+
# :groups=>[{:group_name=>"2009-07-15-default", :group_id=>"sg-90c5d6fc"}],
|
79
|
+
# :block_device_mappings=>
|
80
|
+
# [{:device_name=>"/dev/sda1",
|
81
|
+
# :ebs_status=>"attached",
|
82
|
+
# :ebs_attach_time=>"2011-03-04T18:51:58.000Z",
|
83
|
+
# :ebs_delete_on_termination=>true,
|
84
|
+
# :ebs_volume_id=>"vol-38f2bd50"}],
|
85
|
+
# :state_reason_message=>
|
86
|
+
# "Client.UserInitiatedShutdown: User initiated shutdown",
|
87
|
+
# :aws_image_id=>"ami-a3638cca",
|
88
|
+
# :virtualization_type=>"paravirtual",
|
89
|
+
# :aws_launch_time=>"2011-03-04T18:13:59.000Z",
|
90
|
+
# :private_dns_name=>"",
|
91
|
+
# :aws_product_codes=>[],
|
92
|
+
# :aws_availability_zone=>"us-east-1a",
|
93
|
+
# :aws_state_code=>80,
|
94
|
+
# :architecture=>"x86_64",
|
95
|
+
# :dns_name=>"",
|
96
|
+
# :client_token=>"1299262447-684266-NNgyH-ouPTI-MzG6h-5AIRk",
|
97
|
+
# :root_device_type=>"ebs",
|
98
|
+
# :vpc_id=>"vpc-e16cf988",
|
99
|
+
# :monitoring_state=>"disabled",
|
100
|
+
# :ssh_key_name=>"default",
|
101
|
+
# :private_ip_address=>"192.168.0.52",
|
102
|
+
# :aws_reason=>"User initiated ",
|
103
|
+
# :aws_state=>"stopped"}, ...]
|
104
|
+
#
|
105
|
+
# ec2.describe_instances("i-8ce84ae6", "i-8ce84ae8", "i-8ce84ae0")
|
106
|
+
# ec2.describe_instances(:filters => { 'availability-zone' => 'us-east-1a', 'instance-type' => 'c1.medium' })
|
107
|
+
#
|
108
|
+
# P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DescribeInstances.html
|
109
|
+
#
|
110
|
+
def describe_instances(*list_and_options)
|
111
|
+
describe_resources_with_list_and_options('DescribeInstances', 'InstanceId', QEc2DescribeInstancesParser, list_and_options) do |parser|
|
112
|
+
get_desc_instances(parser.result)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return the product code attached to instance or +nil+ otherwise.
|
117
|
+
#
|
118
|
+
# ec2.confirm_product_instance('ami-e444444d','12345678') #=> nil
|
119
|
+
# ec2.confirm_product_instance('ami-e444444d','00001111') #=> "000000000888"
|
120
|
+
#
|
121
|
+
def confirm_product_instance(instance, product_code)
|
122
|
+
link = generate_request("ConfirmProductInstance", { 'ProductCode' => product_code,
|
123
|
+
'InstanceId' => instance })
|
124
|
+
request_info(link, QEc2ConfirmProductInstanceParser.new(:logger => @logger))
|
125
|
+
end
|
126
|
+
|
127
|
+
# Launch new EC2 instances. Returns a list of launched instances or an exception.
|
128
|
+
#
|
129
|
+
# ec2.run_instances('ami-e444444d',1,1,['2009-07-15-default'],'my_awesome_key', 'Woohoo!!!', 'public') #=>
|
130
|
+
# [{:aws_image_id => "ami-e444444d",
|
131
|
+
# :aws_reason => "",
|
132
|
+
# :aws_state_code => "0",
|
133
|
+
# :aws_owner => "000000000888",
|
134
|
+
# :aws_instance_id => "i-123f1234",
|
135
|
+
# :aws_reservation_id => "r-aabbccdd",
|
136
|
+
# :aws_state => "pending",
|
137
|
+
# :dns_name => "",
|
138
|
+
# :ssh_key_name => "my_awesome_key",
|
139
|
+
# :groups => [{:group_name=>"2009-07-15-default", :group_id=>"sg-90c5d6fc"}],
|
140
|
+
# :private_dns_name => "",
|
141
|
+
# :aws_instance_type => "m1.small",
|
142
|
+
# :aws_launch_time => "2008-1-1T00:00:00.000Z"
|
143
|
+
# :aws_ramdisk_id => "ari-8605e0ef"
|
144
|
+
# :aws_kernel_id => "aki-9905e0f0",
|
145
|
+
# :ami_launch_index => "0",
|
146
|
+
# :aws_availability_zone => "us-east-1b"
|
147
|
+
# }]
|
148
|
+
#
|
149
|
+
def run_instances(image_id, min_count, max_count, group_names, key_name, user_data='',
|
150
|
+
addressing_type = nil, instance_type = nil,
|
151
|
+
kernel_id = nil, ramdisk_id = nil, availability_zone = nil,
|
152
|
+
monitoring_enabled = nil, subnet_id = nil, disable_api_termination = nil,
|
153
|
+
instance_initiated_shutdown_behavior = nil, block_device_mappings = nil,
|
154
|
+
placement_group_name = nil, client_token = nil)
|
155
|
+
launch_instances(image_id, { :min_count => min_count,
|
156
|
+
:max_count => max_count,
|
157
|
+
:user_data => user_data,
|
158
|
+
:group_names => group_names,
|
159
|
+
:key_name => key_name,
|
160
|
+
:instance_type => instance_type,
|
161
|
+
:addressing_type => addressing_type,
|
162
|
+
:kernel_id => kernel_id,
|
163
|
+
:ramdisk_id => ramdisk_id,
|
164
|
+
:availability_zone => availability_zone,
|
165
|
+
:monitoring_enabled => monitoring_enabled,
|
166
|
+
:subnet_id => subnet_id,
|
167
|
+
:disable_api_termination => disable_api_termination,
|
168
|
+
:instance_initiated_shutdown_behavior => instance_initiated_shutdown_behavior,
|
169
|
+
:block_device_mappings => block_device_mappings,
|
170
|
+
:placement_group_name => placement_group_name,
|
171
|
+
:client_token => client_token
|
172
|
+
})
|
173
|
+
end
|
174
|
+
|
175
|
+
# Launch new EC2 instances.
|
176
|
+
#
|
177
|
+
# Options: :image_id, :addressing_type, :min_count, max_count, :key_name, :kernel_id, :ramdisk_id,
|
178
|
+
# :availability_zone, :monitoring_enabled, :subnet_id, :disable_api_termination, :instance_initiated_shutdown_behavior,
|
179
|
+
# :block_device_mappings, :placement_group_name, :license_pool, :group_ids, :group_names, :private_ip_address
|
180
|
+
#
|
181
|
+
# Returns a list of launched instances or an exception.
|
182
|
+
#
|
183
|
+
# ec2.launch_instances( "ami-78779511",
|
184
|
+
# :min_count => 1,
|
185
|
+
# :group_names => ["default", "eugeg223123123"],
|
186
|
+
# :user_data => 'Ohoho!',
|
187
|
+
# :availability_zone => "us-east-1a",
|
188
|
+
# :disable_api_termination => false,
|
189
|
+
# :instance_initiated_shutdown_behavior => 'terminate',
|
190
|
+
# :block_device_mappings => [ {:ebs_snapshot_id=>"snap-e40fd188",
|
191
|
+
# :ebs_delete_on_termination=>true,
|
192
|
+
# :device_name => "/dev/sdk",
|
193
|
+
# :virtual_name => "mystorage"} ] ) #=>
|
194
|
+
# [{:hypervisor=>"xen",
|
195
|
+
# :private_dns_name=>"",
|
196
|
+
# :client_token=>"1309532374-551037-gcsBj-gEypk-piG06-ODfQm",
|
197
|
+
# :monitoring_state=>"disabled",
|
198
|
+
# :aws_availability_zone=>"us-east-1a",
|
199
|
+
# :root_device_name=>"/dev/sda1",
|
200
|
+
# :state_reason_code=>"pending",
|
201
|
+
# :dns_name=>"",
|
202
|
+
# :tags=>{},
|
203
|
+
# :aws_reason=>"",
|
204
|
+
# :virtualization_type=>"paravirtual",
|
205
|
+
# :state_reason_message=>"pending",
|
206
|
+
# :aws_reservation_id=>"r-6fada703",
|
207
|
+
# :aws_ramdisk_id=>"ari-a51cf9cc",
|
208
|
+
# :ami_launch_index=>"0",
|
209
|
+
# :groups=>
|
210
|
+
# [{:group_id=>"sg-a0b85dc9", :group_name=>"default"},
|
211
|
+
# {:group_id=>"sg-70733019", :group_name=>"eugeg223123123"}],
|
212
|
+
# :aws_owner=>"826693181925",
|
213
|
+
# :aws_instance_type=>"m1.small",
|
214
|
+
# :aws_state=>"pending",
|
215
|
+
# :root_device_type=>"ebs",
|
216
|
+
# :aws_image_id=>"ami-78779511",
|
217
|
+
# :aws_kernel_id=>"aki-a71cf9ce",
|
218
|
+
# :aws_launch_time=>"2011-07-01T14:59:35.000Z",
|
219
|
+
# :aws_state_code=>0,
|
220
|
+
# :aws_instance_id=>"i-4f202621",
|
221
|
+
# :aws_product_codes=>[]}]
|
222
|
+
#
|
223
|
+
def launch_instances(image_id, options={})
|
224
|
+
options[:user_data] = options[:user_data].to_s
|
225
|
+
params = map_api_keys_and_values( options,
|
226
|
+
:key_name, :addressing_type, :kernel_id,
|
227
|
+
:ramdisk_id, :subnet_id, :instance_initiated_shutdown_behavior,
|
228
|
+
:private_ip_address, :additional_info, :license_pool,
|
229
|
+
:image_id => { :value => image_id },
|
230
|
+
:min_count => { :value => options[:min_count] || 1 },
|
231
|
+
:max_count => { :value => options[:max_count] || options[:min_count] || 1 },
|
232
|
+
:placement_tenancy => 'Placement.Tenancy',
|
233
|
+
:placement_group_name => 'Placement.GroupName',
|
234
|
+
:availability_zone => 'Placement.AvailabilityZone',
|
235
|
+
:group_names => { :amazonize_list => 'SecurityGroup' },
|
236
|
+
:group_ids => { :amazonize_list => 'SecurityGroupId' },
|
237
|
+
:block_device_mappings => { :amazonize_bdm => 'BlockDeviceMapping' },
|
238
|
+
:instance_type => { :value => options[:instance_type] || DEFAULT_INSTANCE_TYPE },
|
239
|
+
:disable_api_termination => { :value => Proc.new{ !options[:disable_api_termination].nil? && options[:disable_api_termination].to_s }},
|
240
|
+
:client_token => { :value => !@params[:eucalyptus] && (options[:client_token] || AwsUtils::generate_unique_token)},
|
241
|
+
:user_data => { :value => Proc.new { !options[:user_data].empty? && Base64.encode64(options[:user_data]).delete("\n") }},
|
242
|
+
:monitoring_enabled => { :name => 'Monitoring.Enabled',
|
243
|
+
:value => Proc.new{ options[:monitoring_enabled] && options[:monitoring_enabled].to_s }})
|
244
|
+
# Log debug information
|
245
|
+
@logger.info("Launching instance of image #{image_id}. Options: #{params.inspect}")
|
246
|
+
link = generate_request("RunInstances", params)
|
247
|
+
instances = request_info(link, QEc2DescribeInstancesParser.new(:logger => @logger))
|
248
|
+
get_desc_instances(instances)
|
249
|
+
rescue Exception
|
250
|
+
on_exception
|
251
|
+
end
|
252
|
+
|
253
|
+
# Start instances.
|
254
|
+
#
|
255
|
+
# ec2.start_instances("i-36e84a5e") #=>
|
256
|
+
# [{:aws_prev_state_name=>"stopped",
|
257
|
+
# :aws_instance_id=>"i-36e84a5e",
|
258
|
+
# :aws_current_state_code=>16,
|
259
|
+
# :aws_current_state_name=>"running",
|
260
|
+
# :aws_prev_state_code=>80}]
|
261
|
+
#
|
262
|
+
def start_instances(*instance_aws_ids)
|
263
|
+
instance_aws_ids = instance_aws_ids.flatten
|
264
|
+
link = generate_request("StartInstances", amazonize_list('InstanceId', instance_aws_ids))
|
265
|
+
request_info(link, QEc2TerminateInstancesParser.new(:logger => @logger))
|
266
|
+
end
|
267
|
+
|
268
|
+
# Stop instances.
|
269
|
+
#
|
270
|
+
# Options: :force => true|false
|
271
|
+
#
|
272
|
+
# ec2.stop_instances("i-36e84a5e") #=>
|
273
|
+
# [{:aws_prev_state_code=>16,
|
274
|
+
# :aws_prev_state_name=>"running",
|
275
|
+
# :aws_instance_id=>"i-36e84a5e",
|
276
|
+
# :aws_current_state_code=>64,
|
277
|
+
# :aws_current_state_name=>"stopping"}]
|
278
|
+
#
|
279
|
+
def stop_instances(*instance_aws_ids_and_options)
|
280
|
+
list, options = AwsUtils::split_items_and_params(instance_aws_ids_and_options)
|
281
|
+
request_hash = {}
|
282
|
+
request_hash['Force'] = true if options[:force]
|
283
|
+
request_hash.merge!(amazonize_list('InstanceId', list))
|
284
|
+
link = generate_request("StopInstances", request_hash)
|
285
|
+
request_info(link, QEc2TerminateInstancesParser.new(:logger => @logger))
|
286
|
+
end
|
287
|
+
|
288
|
+
# Terminates EC2 instances. Returns a list of termination params or an exception.
|
289
|
+
#
|
290
|
+
# ec2.terminate_instances(['i-cceb49a4']) #=>
|
291
|
+
# [{:aws_instance_id=>"i-cceb49a4",
|
292
|
+
# :aws_current_state_code=>32,
|
293
|
+
# :aws_current_state_name=>"shutting-down",
|
294
|
+
# :aws_prev_state_code=>16,
|
295
|
+
# :aws_prev_state_name=>"running"}]
|
296
|
+
#
|
297
|
+
def terminate_instances(*instance_aws_ids)
|
298
|
+
instance_aws_ids = instance_aws_ids.flatten
|
299
|
+
link = generate_request("TerminateInstances", amazonize_list('InstanceId', instance_aws_ids))
|
300
|
+
request_info(link, QEc2TerminateInstancesParser.new(:logger => @logger))
|
301
|
+
rescue Exception
|
302
|
+
on_exception
|
303
|
+
end
|
304
|
+
|
305
|
+
# Retreive EC2 instance OS logs. Returns a hash of data or an exception.
|
306
|
+
#
|
307
|
+
# ec2.get_console_output('i-f222222d') =>
|
308
|
+
# {:aws_instance_id => 'i-f222222d',
|
309
|
+
# :aws_timestamp => "2007-05-23T14:36:07.000-07:00",
|
310
|
+
# :timestamp => Wed May 23 21:36:07 UTC 2007, # Time instance
|
311
|
+
# :aws_output => "Linux version 2.6.16-xenU (builder@patchbat.amazonsa) (gcc version 4.0.1 20050727 ..."
|
312
|
+
def get_console_output(instance_id)
|
313
|
+
link = generate_request("GetConsoleOutput", { 'InstanceId.1' => instance_id })
|
314
|
+
request_info(link, QEc2GetConsoleOutputParser.new(:logger => @logger))
|
315
|
+
rescue Exception
|
316
|
+
on_exception
|
317
|
+
end
|
318
|
+
|
319
|
+
# Reboot an EC2 instance. Returns +true+ or an exception.
|
320
|
+
#
|
321
|
+
# ec2.reboot_instances(['i-f222222d','i-f222222e']) #=> true
|
322
|
+
#
|
323
|
+
def reboot_instances(*instances)
|
324
|
+
instances = instances.flatten
|
325
|
+
link = generate_request("RebootInstances", amazonize_list('InstanceId', instances))
|
326
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
327
|
+
rescue Exception
|
328
|
+
on_exception
|
329
|
+
end
|
330
|
+
|
331
|
+
# Describe instance attribute.
|
332
|
+
#
|
333
|
+
# Attributes: 'instanceType', 'kernel', 'ramdisk', 'userData', 'rootDeviceName', 'disableApiTermination',
|
334
|
+
# 'instanceInitiatedShutdownBehavior', 'sourceDestCheck', 'blockDeviceMapping', 'groupSet'
|
335
|
+
#
|
336
|
+
# ec2.describe_instance_attribute(instance, "blockDeviceMapping") #=>
|
337
|
+
# [{:ebs_delete_on_termination=>true,
|
338
|
+
# :ebs_volume_id=>"vol-683dc401",
|
339
|
+
# :device_name=>"/dev/sda1"}]
|
340
|
+
#
|
341
|
+
# ec2.describe_instance_attribute(instance, "instanceType") #=> "m1.small"
|
342
|
+
#
|
343
|
+
# ec2.describe_instance_attribute(instance, "instanceInitiatedShutdownBehavior") #=> "stop"
|
344
|
+
#
|
345
|
+
def describe_instance_attribute(instance_id, attribute)
|
346
|
+
link = generate_request('DescribeInstanceAttribute',
|
347
|
+
'InstanceId' => instance_id,
|
348
|
+
'Attribute' => attribute)
|
349
|
+
value = request_info(link, QEc2DescribeInstanceAttributeParser.new(:logger => @logger))
|
350
|
+
value = Base64.decode64(value) if attribute == "userData" && !value.right_blank?
|
351
|
+
value
|
352
|
+
rescue Exception
|
353
|
+
on_exception
|
354
|
+
end
|
355
|
+
|
356
|
+
# Describe instance attribute.
|
357
|
+
#
|
358
|
+
# Attributes: 'kernel', 'ramdisk', 'sourceDestCheck'
|
359
|
+
#
|
360
|
+
# ec2.reset_instance_attribute(instance, 'kernel') #=> true
|
361
|
+
#
|
362
|
+
def reset_instance_attribute(instance_id, attribute)
|
363
|
+
link = generate_request('ResetInstanceAttribute',
|
364
|
+
'InstanceId' => instance_id,
|
365
|
+
'Attribute' => attribute )
|
366
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
367
|
+
rescue Exception
|
368
|
+
on_exception
|
369
|
+
end
|
370
|
+
|
371
|
+
# Modify instance attribute.
|
372
|
+
#
|
373
|
+
# Attributes: 'InstanceType', 'Kernel', 'Ramdisk', 'UserData', 'DisableApiTermination',
|
374
|
+
# 'InstanceInitiatedShutdownBehavior', 'SourceDestCheck', 'GroupId'
|
375
|
+
#
|
376
|
+
# ec2.modify_instance_attribute(instance, 'instanceInitiatedShutdownBehavior", "stop") #=> true
|
377
|
+
#
|
378
|
+
def modify_instance_attribute(instance_id, attribute, value)
|
379
|
+
request_hash = {'InstanceId' => instance_id}
|
380
|
+
attribute = attribute.to_s.right_underscore.right_camelize
|
381
|
+
case attribute
|
382
|
+
when 'UserData' then request_hash["#{attribute}.Value"] = Base64.encode64(value).delete("\n")
|
383
|
+
when 'GroupId' then request_hash.merge!(amazonize_list('GroupId', value))
|
384
|
+
else request_hash["#{attribute}.Value"] = value
|
385
|
+
end
|
386
|
+
link = generate_request('ModifyInstanceAttribute', request_hash)
|
387
|
+
request_info(link, RightBoolResponseParser.new(:logger => @logger))
|
388
|
+
rescue Exception
|
389
|
+
on_exception
|
390
|
+
end
|
391
|
+
|
392
|
+
#-----------------------------------------------------------------
|
393
|
+
# Instances: Windows addons
|
394
|
+
#-----------------------------------------------------------------
|
395
|
+
|
396
|
+
# Get initial Windows Server setup password from an instance console output.
|
397
|
+
#
|
398
|
+
# my_awesome_key = ec2.create_key_pair('my_awesome_key') #=>
|
399
|
+
# {:aws_key_name => "my_awesome_key",
|
400
|
+
# :aws_fingerprint => "01:02:03:f4:25:e6:97:e8:9b:02:1a:26:32:4e:58:6b:7a:8c:9f:03",
|
401
|
+
# :aws_material => "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAK...Q8MDrCbuQ=\n-----END RSA PRIVATE KEY-----"}
|
402
|
+
#
|
403
|
+
# my_awesome_instance = ec2.run_instances('ami-a000000a',1,1,['my_awesome_group'],'my_awesome_key', 'WindowsInstance!!!') #=>
|
404
|
+
# [{:aws_image_id => "ami-a000000a",
|
405
|
+
# :aws_instance_id => "i-12345678",
|
406
|
+
# ...
|
407
|
+
# :aws_availability_zone => "us-east-1b"
|
408
|
+
# }]
|
409
|
+
#
|
410
|
+
# # wait until instance enters 'operational' state and get it's initial password
|
411
|
+
#
|
412
|
+
# puts ec2.get_initial_password(my_awesome_instance[:aws_instance_id], my_awesome_key[:aws_material]) #=> "MhjWcgZuY6"
|
413
|
+
#
|
414
|
+
def get_initial_password(instance_id, private_key)
|
415
|
+
console_output = get_console_output(instance_id)
|
416
|
+
crypted_password = console_output[:aws_output][%r{<Password>(.+)</Password>}m] && $1
|
417
|
+
unless crypted_password
|
418
|
+
raise AwsError.new("Initial password was not found in console output for #{instance_id}")
|
419
|
+
else
|
420
|
+
OpenSSL::PKey::RSA.new(private_key).private_decrypt(Base64.decode64(crypted_password))
|
421
|
+
end
|
422
|
+
rescue Exception
|
423
|
+
on_exception
|
424
|
+
end
|
425
|
+
|
426
|
+
# Get Initial windows instance password using Amazon API call GetPasswordData.
|
427
|
+
#
|
428
|
+
# puts ec2.get_initial_password_v2(my_awesome_instance[:aws_instance_id], my_awesome_key[:aws_material]) #=> "MhjWcgZuY6"
|
429
|
+
#
|
430
|
+
# P.S. To say the truth there is absolutely no any speedup if to compare to the old get_initial_password method... ;(
|
431
|
+
#
|
432
|
+
def get_initial_password_v2(instance_id, private_key)
|
433
|
+
link = generate_request('GetPasswordData',
|
434
|
+
'InstanceId' => instance_id )
|
435
|
+
response = request_info(link, QEc2GetPasswordDataParser.new(:logger => @logger))
|
436
|
+
if response[:password_data].right_blank?
|
437
|
+
raise AwsError.new("Initial password is not yet created for #{instance_id}")
|
438
|
+
else
|
439
|
+
OpenSSL::PKey::RSA.new(private_key).private_decrypt(Base64.decode64(response[:password_data]))
|
440
|
+
end
|
441
|
+
rescue Exception
|
442
|
+
on_exception
|
443
|
+
end
|
444
|
+
|
445
|
+
# Bundle a Windows image.
|
446
|
+
# Internally, it queues the bundling task and shuts down the instance.
|
447
|
+
# It then takes a snapshot of the Windows volume bundles it, and uploads it to
|
448
|
+
# S3. After bundling completes, Rightaws::Ec2#register_image may be used to
|
449
|
+
# register the new Windows AMI for subsequent launches.
|
450
|
+
#
|
451
|
+
# ec2.bundle_instance('i-e3e24e8a', 'my-awesome-bucket', 'my-win-image-1') #=>
|
452
|
+
# [{:aws_update_time => "2008-10-16T13:58:25.000Z",
|
453
|
+
# :s3_bucket => "kd-win-1",
|
454
|
+
# :s3_prefix => "win2pr",
|
455
|
+
# :aws_state => "pending",
|
456
|
+
# :aws_id => "bun-26a7424f",
|
457
|
+
# :aws_instance_id => "i-878a25ee",
|
458
|
+
# :aws_start_time => "2008-10-16T13:58:02.000Z"}]
|
459
|
+
#
|
460
|
+
def bundle_instance(instance_id, s3_bucket, s3_prefix,
|
461
|
+
s3_owner_aws_access_key_id=nil, s3_owner_aws_secret_access_key=nil,
|
462
|
+
s3_expires = S3Interface::DEFAULT_EXPIRES_AFTER,
|
463
|
+
s3_upload_policy='ec2-bundle-read')
|
464
|
+
# S3 access and signatures
|
465
|
+
s3_owner_aws_access_key_id ||= @aws_access_key_id
|
466
|
+
s3_owner_aws_secret_access_key ||= @aws_secret_access_key
|
467
|
+
s3_expires = Time.now.utc + s3_expires if s3_expires.is_a?(Fixnum) && (s3_expires < S3Interface::ONE_YEAR_IN_SECONDS)
|
468
|
+
# policy
|
469
|
+
policy = { 'expiration' => AwsUtils::utc_iso8601(s3_expires),
|
470
|
+
'conditions' => [ { 'bucket' => s3_bucket },
|
471
|
+
{ 'acl' => s3_upload_policy },
|
472
|
+
[ 'starts-with', '$key', s3_prefix ] ] }.to_json
|
473
|
+
policy64 = Base64.encode64(policy).gsub("\n","")
|
474
|
+
signed_policy64 = AwsUtils.sign(s3_owner_aws_secret_access_key, policy64)
|
475
|
+
# fill request params
|
476
|
+
params = { 'InstanceId' => instance_id,
|
477
|
+
'Storage.S3.AWSAccessKeyId' => s3_owner_aws_access_key_id,
|
478
|
+
'Storage.S3.UploadPolicy' => policy64,
|
479
|
+
'Storage.S3.UploadPolicySignature' => signed_policy64,
|
480
|
+
'Storage.S3.Bucket' => s3_bucket,
|
481
|
+
'Storage.S3.Prefix' => s3_prefix,
|
482
|
+
}
|
483
|
+
link = generate_request("BundleInstance", params)
|
484
|
+
request_info(link, QEc2BundleInstanceParser.new)
|
485
|
+
rescue Exception
|
486
|
+
on_exception
|
487
|
+
end
|
488
|
+
|
489
|
+
# Describe the status of the Windows AMI bundlings.
|
490
|
+
#
|
491
|
+
# Accepts a list of tasks and/or a set of filters as the last parameter.
|
492
|
+
#
|
493
|
+
# Filters" bundle-id, error-code, error-message, instance-id, progress, s3-aws-access-key-id, s3-bucket, s3-prefix,
|
494
|
+
# start-time, state, update-time
|
495
|
+
#
|
496
|
+
# ec2.describe_bundle_tasks('bun-4fa74226') #=>
|
497
|
+
# [{:s3_bucket => "my-awesome-bucket"
|
498
|
+
# :aws_id => "bun-0fa70206",
|
499
|
+
# :s3_prefix => "win1pr",
|
500
|
+
# :aws_start_time => "2008-10-14T16:27:57.000Z",
|
501
|
+
# :aws_update_time => "2008-10-14T16:37:10.000Z",
|
502
|
+
# :aws_error_code => "Client.S3Error",
|
503
|
+
# :aws_error_message =>
|
504
|
+
# "AccessDenied(403)- Invalid according to Policy: Policy Condition failed: [\"eq\", \"$acl\", \"aws-exec-read\"]",
|
505
|
+
# :aws_state => "failed",
|
506
|
+
# :aws_instance_id => "i-e3e24e8a"}]
|
507
|
+
#
|
508
|
+
# ec2.describe_bundle_tasks(:filters => { 'state' => 'pending' })
|
509
|
+
#
|
510
|
+
# P.S. filters: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeBundleTasks.html
|
511
|
+
#
|
512
|
+
def describe_bundle_tasks(*list_and_options)
|
513
|
+
describe_resources_with_list_and_options('DescribeBundleTasks', 'BundleId', QEc2DescribeBundleTasksParser, list_and_options)
|
514
|
+
end
|
515
|
+
|
516
|
+
# Cancel an in‐progress or pending bundle task by id.
|
517
|
+
#
|
518
|
+
# ec2.cancel_bundle_task('bun-73a7421a') #=>
|
519
|
+
# [{:s3_bucket => "my-awesome-bucket"
|
520
|
+
# :aws_id => "bun-0fa70206",
|
521
|
+
# :s3_prefix => "win02",
|
522
|
+
# :aws_start_time => "2008-10-14T13:00:29.000Z",
|
523
|
+
# :aws_error_message => "User has requested bundling operation cancellation",
|
524
|
+
# :aws_state => "failed",
|
525
|
+
# :aws_update_time => "2008-10-14T13:01:31.000Z",
|
526
|
+
# :aws_error_code => "Client.Cancelled",
|
527
|
+
# :aws_instance_id => "i-e3e24e8a"}
|
528
|
+
#
|
529
|
+
def cancel_bundle_task(bundle_id)
|
530
|
+
link = generate_request("CancelBundleTask", { 'BundleId' => bundle_id })
|
531
|
+
request_info(link, QEc2BundleInstanceParser.new)
|
532
|
+
rescue Exception
|
533
|
+
on_exception
|
534
|
+
end
|
535
|
+
|
536
|
+
#-----------------------------------------------------------------
|
537
|
+
# PARSERS: Instances
|
538
|
+
#-----------------------------------------------------------------
|
539
|
+
|
540
|
+
class QEc2DescribeInstancesParser < RightAWSParser #:nodoc:
|
541
|
+
def tagstart(name, attributes)
|
542
|
+
case full_tag_name
|
543
|
+
when %r{(RunInstancesResponse|DescribeInstancesResponse/reservationSet/item)$}
|
544
|
+
@reservation = { :aws_groups => [],
|
545
|
+
:instances_set => [] }
|
546
|
+
when %r{(/groupSet/item|instancesSet/item/placement)$}
|
547
|
+
@group = {}
|
548
|
+
when %r{instancesSet/item$}
|
549
|
+
# the optional params (sometimes are missing and we dont want them to be nil)
|
550
|
+
@item = { :aws_product_codes => [],
|
551
|
+
:groups => [],
|
552
|
+
:tags => {} }
|
553
|
+
when %r{blockDeviceMapping/item$}
|
554
|
+
@item[:block_device_mappings] ||= []
|
555
|
+
@block_device_mapping = {}
|
556
|
+
when %r{/tagSet/item$}
|
557
|
+
@aws_tag = {}
|
558
|
+
end
|
559
|
+
end
|
560
|
+
def tagend(name)
|
561
|
+
case name
|
562
|
+
when 'reservationId' then @reservation[:aws_reservation_id] = @text
|
563
|
+
when 'ownerId' then @reservation[:aws_owner] = @text
|
564
|
+
when 'instanceId' then @item[:aws_instance_id] = @text
|
565
|
+
when 'imageId' then @item[:aws_image_id] = @text
|
566
|
+
when 'privateDnsName' then @item[:private_dns_name] = @text
|
567
|
+
when 'dnsName' then @item[:dns_name] = @text
|
568
|
+
when 'reason' then @item[:aws_reason] = @text
|
569
|
+
when 'keyName' then @item[:ssh_key_name] = @text
|
570
|
+
when 'amiLaunchIndex' then @item[:ami_launch_index] = @text
|
571
|
+
when 'productCode' then @item[:aws_product_codes] << @text
|
572
|
+
when 'instanceType' then @item[:aws_instance_type] = @text
|
573
|
+
when 'launchTime' then @item[:aws_launch_time] = @text
|
574
|
+
when 'availabilityZone' then @item[:aws_availability_zone] = @text
|
575
|
+
when 'kernelId' then @item[:aws_kernel_id] = @text
|
576
|
+
when 'ramdiskId' then @item[:aws_ramdisk_id] = @text
|
577
|
+
when 'platform' then @item[:aws_platform] = @text
|
578
|
+
when 'subnetId' then @item[:subnet_id] = @text
|
579
|
+
when 'vpcId' then @item[:vpc_id] = @text
|
580
|
+
when 'privateIpAddress' then @item[:private_ip_address] = @text
|
581
|
+
when 'ipAddress' then @item[:ip_address] = @text
|
582
|
+
when 'architecture' then @item[:architecture] = @text
|
583
|
+
when 'rootDeviceType' then @item[:root_device_type] = @text
|
584
|
+
when 'rootDeviceName' then @item[:root_device_name] = @text
|
585
|
+
when 'instanceClass' then @item[:instance_class] = @text
|
586
|
+
when 'instanceLifecycle' then @item[:instance_lifecycle] = @text
|
587
|
+
when 'spotInstanceRequestId' then @item[:spot_instance_request_id] = @text
|
588
|
+
when 'requesterId' then @item[:requester_id] = @text
|
589
|
+
when 'virtualizationType' then @item[:virtualization_type] = @text
|
590
|
+
when 'clientToken' then @item[:client_token] = @text
|
591
|
+
when 'sourceDestCheck' then @item[:source_dest_check] = @text == 'true' ? true : false
|
592
|
+
when 'tenancy' then @item[:placement_tenancy] = @text
|
593
|
+
when 'hypervisor' then @item[:hypervisor] = @text
|
594
|
+
else
|
595
|
+
case full_tag_name
|
596
|
+
# EC2 Groups
|
597
|
+
when %r{(RunInstancesResponse|/reservationSet/item)/groupSet/item/groupId$} then @group[:group_id] = @text
|
598
|
+
when %r{(RunInstancesResponse|/reservationSet/item)/groupSet/item/groupName$} then @group[:group_name] = @text
|
599
|
+
when %r{(RunInstancesResponse|/reservationSet/item)/groupSet/item$} then @reservation[:aws_groups] << @group
|
600
|
+
# VPC Groups
|
601
|
+
# KD: It seems that these groups are always present when the groups above present for non VPC instances only
|
602
|
+
when %r{/instancesSet/item/groupSet/item/groupId$} then @group[:group_id] = @text
|
603
|
+
when %r{/instancesSet/item/groupSet/item/groupName$} then @group[:group_name] = @text
|
604
|
+
when %r{/instancesSet/item/groupSet/item$} then @item[:groups] << @group
|
605
|
+
# Placement Group Name
|
606
|
+
when %r{/placement/groupName$} then @group[:placement_group_name]= @text
|
607
|
+
# Codes
|
608
|
+
when %r{/stateReason/code$} then @item[:state_reason_code] = @text
|
609
|
+
when %r{/stateReason/message$} then @item[:state_reason_message] = @text
|
610
|
+
when %r{/instanceState/code$} then @item[:aws_state_code] = @text.to_i
|
611
|
+
when %r{/instanceState/name$} then @item[:aws_state] = @text
|
612
|
+
when %r{/monitoring/state$} then @item[:monitoring_state] = @text
|
613
|
+
when %r{/license/pool$} then @item[:license_pool] = @text
|
614
|
+
when %r{/blockDeviceMapping/item} # no trailing $
|
615
|
+
case name
|
616
|
+
when 'deviceName' then @block_device_mapping[:device_name] = @text
|
617
|
+
when 'virtualName' then @block_device_mapping[:virtual_name] = @text
|
618
|
+
when 'volumeId' then @block_device_mapping[:ebs_volume_id] = @text
|
619
|
+
when 'status' then @block_device_mapping[:ebs_status] = @text
|
620
|
+
when 'attachTime' then @block_device_mapping[:ebs_attach_time] = @text
|
621
|
+
when 'deleteOnTermination' then @block_device_mapping[:ebs_delete_on_termination] = @text == 'true' ? true : false
|
622
|
+
when 'item' then @item[:block_device_mappings] << @block_device_mapping
|
623
|
+
end
|
624
|
+
when %r{/instancesSet/item$} then @reservation[:instances_set] << @item
|
625
|
+
when %r{/tagSet/item/key$} then @aws_tag[:key] = @text
|
626
|
+
when %r{/tagSet/item/value$} then @aws_tag[:value] = @text
|
627
|
+
when %r{/tagSet/item$} then @item[:tags][@aws_tag[:key]] = @aws_tag[:value]
|
628
|
+
when %r{(RunInstancesResponse|DescribeInstancesResponse/reservationSet/item)$} then @result << @reservation
|
629
|
+
end
|
630
|
+
end
|
631
|
+
end
|
632
|
+
def reset
|
633
|
+
@result = []
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
class QEc2ConfirmProductInstanceParser < RightAWSParser #:nodoc:
|
638
|
+
def tagend(name)
|
639
|
+
@result = @text if name == 'ownerId'
|
640
|
+
end
|
641
|
+
end
|
642
|
+
|
643
|
+
class QEc2TerminateInstancesParser < RightAWSParser #:nodoc:
|
644
|
+
def tagstart(name, attributes)
|
645
|
+
@instance = {} if name == 'item'
|
646
|
+
end
|
647
|
+
def tagend(name)
|
648
|
+
case full_tag_name
|
649
|
+
when %r{/instanceId$} then @instance[:aws_instance_id] = @text
|
650
|
+
when %r{/currentState/code$} then @instance[:aws_current_state_code] = @text.to_i
|
651
|
+
when %r{/currentState/name$} then @instance[:aws_current_state_name] = @text
|
652
|
+
when %r{/previousState/code$} then @instance[:aws_prev_state_code] = @text.to_i
|
653
|
+
when %r{/previousState/name$} then @instance[:aws_prev_state_name] = @text
|
654
|
+
when %r{/item$} then @result << @instance
|
655
|
+
end
|
656
|
+
end
|
657
|
+
def reset
|
658
|
+
@result = []
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
class QEc2DescribeInstanceAttributeParser < RightAWSParser #:nodoc:
|
663
|
+
def tagstart(name, attributes)
|
664
|
+
case full_tag_name
|
665
|
+
when %r{groupSet$} then @result = []
|
666
|
+
when %r{groupSet/item$} then @group = {}
|
667
|
+
when %r{blockDeviceMapping$} then @result = []
|
668
|
+
when %r{blockDeviceMapping/item$} then @block_device_mapping = {}
|
669
|
+
end
|
670
|
+
end
|
671
|
+
def tagend(name)
|
672
|
+
case full_tag_name
|
673
|
+
when %r{/instanceType/value$} then @result = @text
|
674
|
+
when %r{/kernel/value$} then @result = @text
|
675
|
+
when %r{/ramdisk/value$} then @result = @text
|
676
|
+
when %r{/userData/value$} then @result = @text
|
677
|
+
when %r{/rootDeviceName/value$} then @result = @text
|
678
|
+
when %r{/disableApiTermination/value} then @result = @text == 'true' ? true : false
|
679
|
+
when %r{/instanceInitiatedShutdownBehavior/value$} then @result = @text
|
680
|
+
when %r{/sourceDestCheck/value$} then @result = @text == 'true' ? true : false
|
681
|
+
when %r{/groupSet/item} # no trailing $
|
682
|
+
case name
|
683
|
+
when 'groupId' then @group[:group_id] = @text
|
684
|
+
when 'groupName' then @group[:group_name] = @text
|
685
|
+
when 'item' then @result << @group
|
686
|
+
end
|
687
|
+
when %r{/blockDeviceMapping/item} # no trailing $
|
688
|
+
case name
|
689
|
+
when 'deviceName' then @block_device_mapping[:device_name] = @text
|
690
|
+
when 'virtualName' then @block_device_mapping[:virtual_name] = @text
|
691
|
+
when 'noDevice' then @block_device_mapping[:no_device] = @text
|
692
|
+
when 'volumeId' then @block_device_mapping[:ebs_volume_id] = @text
|
693
|
+
when 'status' then @block_device_mapping[:ebs_status] = @text
|
694
|
+
when 'attachTime' then @block_device_mapping[:ebs_attach_time] = @text
|
695
|
+
when 'deleteOnTermination' then @block_device_mapping[:ebs_delete_on_termination] = @text == 'true' ? true : false
|
696
|
+
when 'item' then @result << @block_device_mapping
|
697
|
+
end
|
698
|
+
end
|
699
|
+
end
|
700
|
+
def reset
|
701
|
+
@result = nil
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
#-----------------------------------------------------------------
|
706
|
+
# PARSERS: Console
|
707
|
+
#-----------------------------------------------------------------
|
708
|
+
|
709
|
+
class QEc2GetConsoleOutputParser < RightAWSParser #:nodoc:
|
710
|
+
def tagend(name)
|
711
|
+
case name
|
712
|
+
when 'instanceId' then @result[:aws_instance_id] = @text
|
713
|
+
when 'timestamp' then @result[:aws_timestamp] = @text
|
714
|
+
@result[:timestamp] = (Time.parse(@text)).utc
|
715
|
+
when 'output' then @result[:aws_output] = Base64.decode64(@text)
|
716
|
+
end
|
717
|
+
end
|
718
|
+
def reset
|
719
|
+
@result = {}
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
#-----------------------------------------------------------------
|
724
|
+
# Instances: Windows related part
|
725
|
+
#-----------------------------------------------------------------
|
726
|
+
|
727
|
+
class QEc2DescribeBundleTasksParser < RightAWSParser #:nodoc:
|
728
|
+
def tagstart(name, attributes)
|
729
|
+
@bundle = {} if name == 'item'
|
730
|
+
end
|
731
|
+
def tagend(name)
|
732
|
+
case name
|
733
|
+
# when 'requestId' then @bundle[:request_id] = @text
|
734
|
+
when 'instanceId' then @bundle[:aws_instance_id] = @text
|
735
|
+
when 'bundleId' then @bundle[:aws_id] = @text
|
736
|
+
when 'bucket' then @bundle[:s3_bucket] = @text
|
737
|
+
when 'prefix' then @bundle[:s3_prefix] = @text
|
738
|
+
when 'startTime' then @bundle[:aws_start_time] = @text
|
739
|
+
when 'updateTime' then @bundle[:aws_update_time] = @text
|
740
|
+
when 'state' then @bundle[:aws_state] = @text
|
741
|
+
when 'progress' then @bundle[:aws_progress] = @text
|
742
|
+
when 'code' then @bundle[:aws_error_code] = @text
|
743
|
+
when 'message' then @bundle[:aws_error_message] = @text
|
744
|
+
when 'item' then @result << @bundle
|
745
|
+
end
|
746
|
+
end
|
747
|
+
def reset
|
748
|
+
@result = []
|
749
|
+
end
|
750
|
+
end
|
751
|
+
|
752
|
+
class QEc2BundleInstanceParser < RightAWSParser #:nodoc:
|
753
|
+
def tagend(name)
|
754
|
+
case name
|
755
|
+
# when 'requestId' then @result[:request_id] = @text
|
756
|
+
when 'instanceId' then @result[:aws_instance_id] = @text
|
757
|
+
when 'bundleId' then @result[:aws_id] = @text
|
758
|
+
when 'bucket' then @result[:s3_bucket] = @text
|
759
|
+
when 'prefix' then @result[:s3_prefix] = @text
|
760
|
+
when 'startTime' then @result[:aws_start_time] = @text
|
761
|
+
when 'updateTime' then @result[:aws_update_time] = @text
|
762
|
+
when 'state' then @result[:aws_state] = @text
|
763
|
+
when 'progress' then @result[:aws_progress] = @text
|
764
|
+
when 'code' then @result[:aws_error_code] = @text
|
765
|
+
when 'message' then @result[:aws_error_message] = @text
|
766
|
+
end
|
767
|
+
end
|
768
|
+
def reset
|
769
|
+
@result = {}
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
class QEc2GetPasswordDataParser < RightAWSParser #:nodoc:
|
774
|
+
def tagend(name)
|
775
|
+
case name
|
776
|
+
when 'instanceId' then @result[:aws_instance_id] = @text
|
777
|
+
when 'timestamp' then @result[:timestamp] = @text
|
778
|
+
when 'passwordData' then @result[:password_data] = @text
|
779
|
+
end
|
780
|
+
end
|
781
|
+
def reset
|
782
|
+
@result = {}
|
783
|
+
end
|
784
|
+
end
|
785
|
+
|
786
|
+
end
|
787
|
+
|
788
|
+
end
|