redaranj-right_aws 1.11.1 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,6 +6,7 @@ lib/awsbase/benchmark_fix.rb
6
6
  lib/awsbase/right_awsbase.rb
7
7
  lib/awsbase/support.rb
8
8
  lib/ec2/right_ec2.rb
9
+ lib/ec2/right_ec2_images.rb
9
10
  lib/ec2/right_ec2_instances.rb
10
11
  lib/ec2/right_ec2_ebs.rb
11
12
  lib/ec2/right_ec2_reserved_instances.rb
@@ -0,0 +1,451 @@
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
+ # EBS: Volumes
30
+ #-----------------------------------------------------------------
31
+
32
+ # Describe all EBS volumes.
33
+ #
34
+ # ec2.describe_volumes #=>
35
+ # [{:aws_size => 94,
36
+ # :aws_device => "/dev/sdc",
37
+ # :aws_attachment_status => "attached",
38
+ # :zone => "merlot",
39
+ # :snapshot_id => nil,
40
+ # :aws_attached_at => Wed Jun 18 08:19:28 UTC 2008,
41
+ # :aws_status => "in-use",
42
+ # :aws_id => "vol-60957009",
43
+ # :aws_created_at => Wed Jun 18 08:19:20s UTC 2008,
44
+ # :aws_instance_id => "i-c014c0a9"},
45
+ # {:aws_size => 1,
46
+ # :zone => "merlot",
47
+ # :snapshot_id => nil,
48
+ # :aws_status => "available",
49
+ # :aws_id => "vol-58957031",
50
+ # :aws_created_at => Wed Jun 18 08:19:21 UTC 2008,}, ... ]
51
+ #
52
+ def describe_volumes(list=[])
53
+ link = generate_request("DescribeVolumes",
54
+ amazonize_list('VolumeId',list.to_a))
55
+ request_cache_or_info :describe_volumes, link, QEc2DescribeVolumesParser, @@bench, list.blank?
56
+ rescue Exception
57
+ on_exception
58
+ end
59
+
60
+ # Create new EBS volume based on previously created snapshot.
61
+ # +Size+ in Gigabytes.
62
+ #
63
+ # ec2.create_volume('snap-000000', 10, zone) #=>
64
+ # {:snapshot_id => "snap-e21df98b",
65
+ # :aws_status => "creating",
66
+ # :aws_id => "vol-fc9f7a95",
67
+ # :zone => "merlot",
68
+ # :aws_created_at => Tue Jun 24 18:13:32 UTC 2008,
69
+ # :aws_size => 94}
70
+ #
71
+ def create_volume(snapshot_id, size, zone)
72
+ hash = { "Size" => size.to_s,
73
+ "AvailabilityZone" => zone.to_s }
74
+ # Get rig of empty snapshot: e8s guys do not like it
75
+ hash["SnapshotId"] = snapshot_id.to_s unless snapshot_id.blank?
76
+ link = generate_request("CreateVolume", hash )
77
+ request_info(link, QEc2CreateVolumeParser.new(:logger => @logger))
78
+ rescue Exception
79
+ on_exception
80
+ end
81
+
82
+ # Delete the specified EBS volume.
83
+ # This does not deletes any snapshots created from this volume.
84
+ #
85
+ # ec2.delete_volume('vol-b48a6fdd') #=> true
86
+ #
87
+ def delete_volume(volume_id)
88
+ link = generate_request("DeleteVolume",
89
+ "VolumeId" => volume_id.to_s)
90
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
91
+ rescue Exception
92
+ on_exception
93
+ end
94
+
95
+ # Attach the specified EBS volume to a specified instance, exposing the
96
+ # volume using the specified device name.
97
+ #
98
+ # ec2.attach_volume('vol-898a6fe0', 'i-7c905415', '/dev/sdh') #=>
99
+ # { :aws_instance_id => "i-7c905415",
100
+ # :aws_device => "/dev/sdh",
101
+ # :aws_status => "attaching",
102
+ # :aws_attached_at => "2008-03-28T14:14:39.000Z",
103
+ # :aws_id => "vol-898a6fe0" }
104
+ #
105
+ def attach_volume(volume_id, instance_id, device)
106
+ link = generate_request("AttachVolume",
107
+ "VolumeId" => volume_id.to_s,
108
+ "InstanceId" => instance_id.to_s,
109
+ "Device" => device.to_s)
110
+ request_info(link, QEc2AttachAndDetachVolumeParser.new(:logger => @logger))
111
+ rescue Exception
112
+ on_exception
113
+ end
114
+
115
+ # Detach the specified EBS volume from the instance to which it is attached.
116
+ #
117
+ # ec2.detach_volume('vol-898a6fe0') #=>
118
+ # { :aws_instance_id => "i-7c905415",
119
+ # :aws_device => "/dev/sdh",
120
+ # :aws_status => "detaching",
121
+ # :aws_attached_at => "2008-03-28T14:38:34.000Z",
122
+ # :aws_id => "vol-898a6fe0"}
123
+ #
124
+ def detach_volume(volume_id, instance_id=nil, device=nil, force=nil)
125
+ hash = { "VolumeId" => volume_id.to_s }
126
+ hash["InstanceId"] = instance_id.to_s unless instance_id.blank?
127
+ hash["Device"] = device.to_s unless device.blank?
128
+ hash["Force"] = 'true' if force
129
+ #
130
+ link = generate_request("DetachVolume", hash)
131
+ request_info(link, QEc2AttachAndDetachVolumeParser.new(:logger => @logger))
132
+ rescue Exception
133
+ on_exception
134
+ end
135
+
136
+
137
+ #-----------------------------------------------------------------
138
+ # EBS: Snapshots
139
+ #-----------------------------------------------------------------
140
+
141
+ # Describe all EBS snapshots.
142
+ #
143
+ # ec2.describe_snapshots #=>
144
+ # [ {:aws_volume_id=>"vol-545fac3d",
145
+ # :aws_description=>"Wikipedia XML Backups (Linux)",
146
+ # :aws_progress=>"100%",
147
+ # :aws_started_at=>Mon Sep 28 23:49:50 UTC 2009,
148
+ # :aws_owner=>"amazon",
149
+ # :aws_id=>"snap-8041f2e9",
150
+ # :aws_volume_size=>500,
151
+ # :aws_status=>"completed"},
152
+ # {:aws_volume_id=>"vol-185fac71",
153
+ # :aws_description=>"Sloan Digital Sky Survey DR6 Subset (Linux)",
154
+ # :aws_progress=>"100%",
155
+ # :aws_started_at=>Mon Sep 28 23:56:10 UTC 2009,
156
+ # :aws_owner=>"amazon",
157
+ # :aws_id=>"snap-3740f35e",
158
+ # :aws_volume_size=>180,
159
+ # :aws_status=>"completed"}, ...]
160
+ #
161
+ def describe_snapshots(list=[])
162
+ link = generate_request("DescribeSnapshots",
163
+ amazonize_list('SnapshotId',list.to_a))
164
+ request_cache_or_info :describe_snapshots, link, QEc2DescribeSnapshotsParser, @@bench, list.blank?
165
+ rescue Exception
166
+ on_exception
167
+ end
168
+
169
+ # Create a snapshot of specified volume.
170
+ #
171
+ # ec2.create_snapshot('vol-898a6fe0', 'KD: WooHoo!!') #=>
172
+ # {:aws_volume_id=>"vol-e429db8d",
173
+ # :aws_started_at=>Thu Oct 01 09:23:38 UTC 2009,
174
+ # :aws_description=>"KD: WooHoo!!",
175
+ # :aws_owner=>"648770000000",
176
+ # :aws_progress=>"",
177
+ # :aws_status=>"pending",
178
+ # :aws_volume_size=>1,
179
+ # :aws_id=>"snap-3df54854"}
180
+ #
181
+ def create_snapshot(volume_id, description='')
182
+ link = generate_request("CreateSnapshot",
183
+ "VolumeId" => volume_id.to_s,
184
+ "Description" => description)
185
+ request_info(link, QEc2DescribeSnapshotsParser.new(:logger => @logger)).first
186
+ rescue Exception
187
+ on_exception
188
+ end
189
+
190
+ # Create a snapshot of specified volume, but with the normal retry algorithms disabled.
191
+ # This method will return immediately upon error. The user can specify connect and read timeouts (in s)
192
+ # for the connection to AWS. If the user does not specify timeouts, try_create_snapshot uses the default values
193
+ # in Rightscale::HttpConnection.
194
+ #
195
+ # ec2.try_create_snapshot('vol-898a6fe0', 'KD: WooHoo!!') #=>
196
+ # {:aws_volume_id=>"vol-e429db8d",
197
+ # :aws_started_at=>Thu Oct 01 09:23:38 UTC 2009,
198
+ # :aws_description=>"KD: WooHoo!!",
199
+ # :aws_owner=>"648770000000",
200
+ # :aws_progress=>"",
201
+ # :aws_status=>"pending",
202
+ # :aws_volume_size=>1,
203
+ # :aws_id=>"snap-3df54854"}
204
+ #
205
+ def try_create_snapshot(volume_id, connect_timeout = nil, read_timeout = nil, description='')
206
+ # For safety in the ensure block...we don't want to restore values
207
+ # if we never read them in the first place
208
+ orig_reiteration_time = nil
209
+ orig_http_params = nil
210
+
211
+ orig_reiteration_time = RightAws::AWSErrorHandler::reiteration_time
212
+ RightAws::AWSErrorHandler::reiteration_time = 0
213
+
214
+ orig_http_params = Rightscale::HttpConnection::params()
215
+ new_http_params = orig_http_params.dup
216
+ new_http_params[:http_connection_retry_count] = 0
217
+ new_http_params[:http_connection_open_timeout] = connect_timeout if !connect_timeout.nil?
218
+ new_http_params[:http_connection_read_timeout] = read_timeout if !read_timeout.nil?
219
+ Rightscale::HttpConnection::params = new_http_params
220
+
221
+ link = generate_request("CreateSnapshot",
222
+ "VolumeId" => volume_id.to_s,
223
+ "Description" => description)
224
+ request_info(link, QEc2DescribeSnapshotsParser.new(:logger => @logger)).first
225
+
226
+ rescue Exception
227
+ on_exception
228
+ ensure
229
+ RightAws::AWSErrorHandler::reiteration_time = orig_reiteration_time if orig_reiteration_time
230
+ Rightscale::HttpConnection::params = orig_http_params if orig_http_params
231
+ end
232
+
233
+ # Describe snapshot attribute.
234
+ #
235
+ # ec2.describe_snapshot_attribute('snap-36fe435f') #=>
236
+ # {:create_volume_permission=>
237
+ # {:users=>["826690000000", "826690000001"], :groups=>['all']}}
238
+ #
239
+ def describe_snapshot_attribute(snapshot_id, attribute='createVolumePermission')
240
+ link = generate_request("DescribeSnapshotAttribute",
241
+ 'SnapshotId'=> snapshot_id,
242
+ 'Attribute' => attribute)
243
+ request_info(link, QEc2DescribeSnapshotAttributeParser.new(:logger => @logger))
244
+ rescue Exception
245
+ on_exception
246
+ end
247
+
248
+ # Reset permission settings for the specified snapshot.
249
+ #
250
+ # ec2.reset_snapshot_attribute('snap-cecd29a7') #=> true
251
+ #
252
+ def reset_snapshot_attribute(snapshot_id, attribute='createVolumePermission')
253
+ link = generate_request("ResetSnapshotAttribute",
254
+ 'SnapshotId' => snapshot_id,
255
+ 'Attribute' => attribute)
256
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
257
+ rescue Exception
258
+ on_exception
259
+ end
260
+
261
+ # Modify snapshot attribute.
262
+ #
263
+ # attribute : currently, only 'createVolumePermission' is supported.
264
+ # operation_type : currently, only 'add' & 'remove' are supported.
265
+ # vars:
266
+ # :user_group : currently, only 'all' is supported.
267
+ # :user_id : an array of user ids
268
+ #
269
+ def modify_snapshot_attribute(snapshot_id, attribute='createVolumePermission', operation_type='add', vars = {})
270
+ params = {'SnapshotId' => snapshot_id,
271
+ 'Attribute' => attribute,
272
+ 'OperationType' => operation_type}
273
+ params.update(amazonize_list('UserId', vars[:user_id].to_a)) if vars[:user_id]
274
+ params.update(amazonize_list('UserGroup', vars[:user_group].to_a)) if vars[:user_group]
275
+ link = generate_request("ModifySnapshotAttribute", params)
276
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
277
+ rescue Exception
278
+ on_exception
279
+ end
280
+
281
+ # Grant create volume permission for a list of users.
282
+ #
283
+ # ec2.modify_snapshot_attribute_create_volume_permission_add_users('snap-36fe435f', '000000000000', '000000000001') #=> true
284
+ #
285
+ def modify_snapshot_attribute_create_volume_permission_add_users(snapshot_id, *user_id)
286
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'add', :user_id => user_id.flatten )
287
+ end
288
+
289
+ # Revoke create volume permission for a list of users.
290
+ #
291
+ # ec2.modify_snapshot_attribute_create_volume_permission_remove_users('snap-36fe435f', '000000000000', '000000000001') #=> true
292
+ #
293
+ def modify_snapshot_attribute_create_volume_permission_remove_users(snapshot_id, *user_id)
294
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'remove', :user_id => user_id.flatten )
295
+ end
296
+
297
+ # Grant create volume permission for user groups (currently only 'all' is supported).
298
+ #
299
+ # ec2.modify_snapshot_attribute_create_volume_permission_add_groups('snap-36fe435f') #=> true
300
+ #
301
+ def modify_snapshot_attribute_create_volume_permission_add_groups(snapshot_id, *user_group)
302
+ user_group.flatten!
303
+ user_group = ['all'] if user_group.blank?
304
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'add', :user_group => user_group )
305
+ end
306
+
307
+ # Remove create volume permission for user groups (currently only 'all' is supported).
308
+ #
309
+ # ec2.modify_snapshot_attribute_create_volume_permission_remove_groups('snap-36fe435f') #=> true
310
+ #
311
+ def modify_snapshot_attribute_create_volume_permission_remove_groups(snapshot_id, *user_group)
312
+ user_group.flatten!
313
+ user_group = ['all'] if user_group.blank?
314
+ modify_snapshot_attribute(snapshot_id, 'createVolumePermission', 'remove', :user_group => user_group )
315
+ end
316
+
317
+ # Delete the specified snapshot.
318
+ #
319
+ # ec2.delete_snapshot('snap-55a5403c') #=> true
320
+ #
321
+ def delete_snapshot(snapshot_id)
322
+ link = generate_request("DeleteSnapshot",
323
+ "SnapshotId" => snapshot_id.to_s)
324
+ request_info(link, RightBoolResponseParser.new(:logger => @logger))
325
+ rescue Exception
326
+ on_exception
327
+ end
328
+
329
+ #-----------------------------------------------------------------
330
+ # PARSERS: EBS - Volumes
331
+ #-----------------------------------------------------------------
332
+
333
+ class QEc2CreateVolumeParser < RightAWSParser #:nodoc:
334
+ def tagend(name)
335
+ case name
336
+ when 'volumeId' then @result[:aws_id] = @text
337
+ when 'status' then @result[:aws_status] = @text
338
+ when 'createTime' then @result[:aws_created_at] = Time.parse(@text)
339
+ when 'size' then @result[:aws_size] = @text.to_i ###
340
+ when 'snapshotId' then @result[:snapshot_id] = @text.blank? ? nil : @text ###
341
+ when 'availabilityZone' then @result[:zone] = @text ###
342
+ end
343
+ end
344
+ def reset
345
+ @result = {}
346
+ end
347
+ end
348
+
349
+ class QEc2AttachAndDetachVolumeParser < RightAWSParser #:nodoc:
350
+ def tagend(name)
351
+ case name
352
+ when 'volumeId' then @result[:aws_id] = @text
353
+ when 'instanceId' then @result[:aws_instance_id] = @text
354
+ when 'device' then @result[:aws_device] = @text
355
+ when 'status' then @result[:aws_attachment_status] = @text
356
+ when 'attachTime' then @result[:aws_attached_at] = Time.parse(@text)
357
+ end
358
+ end
359
+ def reset
360
+ @result = {}
361
+ end
362
+ end
363
+
364
+ class QEc2DescribeVolumesParser < RightAWSParser #:nodoc:
365
+ def tagstart(name, attributes)
366
+ case name
367
+ when 'item'
368
+ case @xmlpath
369
+ when 'DescribeVolumesResponse/volumeSet' then @volume = {}
370
+ end
371
+ end
372
+ end
373
+ def tagend(name)
374
+ case name
375
+ when 'volumeId'
376
+ case @xmlpath
377
+ when 'DescribeVolumesResponse/volumeSet/item' then @volume[:aws_id] = @text
378
+ end
379
+ when 'status'
380
+ case @xmlpath
381
+ when 'DescribeVolumesResponse/volumeSet/item' then @volume[:aws_status] = @text
382
+ when 'DescribeVolumesResponse/volumeSet/item/attachmentSet/item' then @volume[:aws_attachment_status] = @text
383
+ end
384
+ when 'size' then @volume[:aws_size] = @text.to_i
385
+ when 'createTime' then @volume[:aws_created_at] = Time.parse(@text)
386
+ when 'instanceId' then @volume[:aws_instance_id] = @text
387
+ when 'device' then @volume[:aws_device] = @text
388
+ when 'attachTime' then @volume[:aws_attached_at] = Time.parse(@text)
389
+ when 'snapshotId' then @volume[:snapshot_id] = @text.blank? ? nil : @text
390
+ when 'availabilityZone' then @volume[:zone] = @text
391
+ when 'item'
392
+ case @xmlpath
393
+ when 'DescribeVolumesResponse/volumeSet' then @result << @volume
394
+ end
395
+ end
396
+ end
397
+ def reset
398
+ @result = []
399
+ end
400
+ end
401
+
402
+ #-----------------------------------------------------------------
403
+ # PARSERS: EBS - Snapshots
404
+ #-----------------------------------------------------------------
405
+
406
+ class QEc2DescribeSnapshotsParser < RightAWSParser #:nodoc:
407
+ def tagstart(name, attributes)
408
+ case name
409
+ when *@each then @snapshot = {}
410
+ end
411
+ end
412
+ def tagend(name)
413
+ case name
414
+ when 'volumeId' then @snapshot[:aws_volume_id] = @text
415
+ when 'snapshotId' then @snapshot[:aws_id] = @text
416
+ when 'status' then @snapshot[:aws_status] = @text
417
+ when 'startTime' then @snapshot[:aws_started_at] = Time.parse(@text)
418
+ when 'progress' then @snapshot[:aws_progress] = @text
419
+ when 'description' then @snapshot[:aws_description] = @text
420
+ when 'ownerId' then @snapshot[:aws_owner] = @text
421
+ when 'volumeSize' then @snapshot[:aws_volume_size] = @text.to_i
422
+ when *@each then @result << @snapshot
423
+ end
424
+ end
425
+ def reset
426
+ @each = ['item', 'CreateSnapshotResponse']
427
+ @result = []
428
+ end
429
+ end
430
+
431
+ class QEc2DescribeSnapshotAttributeParser < RightAWSParser #:nodoc:
432
+ def tagstart(name, attributes)
433
+ case name
434
+ when 'createVolumePermission' then @result[:create_volume_permission] = { :groups => [], :users => [] }
435
+ end
436
+ end
437
+ def tagend(name)
438
+ case full_tag_name
439
+ when "#{@create_volume_permission}/group" then @result[:create_volume_permission][:groups] << @text
440
+ when "#{@create_volume_permission}/userId" then @result[:create_volume_permission][:users] << @text
441
+ end
442
+ end
443
+ def reset
444
+ @create_volume_permission = "DescribeSnapshotAttributeResponse/createVolumePermission/item"
445
+ @result = {}
446
+ end
447
+ end
448
+
449
+ end
450
+
451
+ end