awsum 0.5 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Gemfile.lock +14 -20
- data/README.rdoc +1 -1
- data/Rakefile +3 -3
- data/functional/ec2/instances_spec.rb +46 -0
- data/functional/spec_helper.rb +71 -0
- data/lib/awsum.rb +2 -2
- data/lib/awsum/ec2.rb +85 -68
- data/lib/awsum/ec2/image.rb +1 -1
- data/lib/awsum/ec2/instance.rb +35 -6
- data/lib/awsum/ec2/parsers/image_parser.rb +3 -5
- data/lib/awsum/ec2/parsers/instance_parser.rb +24 -15
- data/lib/awsum/ec2/parsers/snapshot_parser.rb +3 -3
- data/lib/awsum/ec2/parsers/tag_parser.rb +56 -0
- data/lib/awsum/ec2/parsers/volume_parser.rb +3 -5
- data/lib/awsum/ec2/region.rb +8 -5
- data/lib/awsum/ec2/security_group.rb +12 -16
- data/lib/awsum/ec2/snapshot.rb +9 -0
- data/lib/awsum/ec2/state.rb +22 -0
- data/lib/awsum/ec2/tag.rb +17 -0
- data/lib/awsum/ec2/volume.rb +12 -2
- data/lib/awsum/requestable.rb +53 -3
- data/spec/fixtures/ec2/authorize_group_access.xml +12 -0
- data/spec/fixtures/ec2/create_security_group.xml +3 -3
- data/spec/fixtures/ec2/delete_security_group.xml +3 -3
- data/spec/fixtures/ec2/purchase_reserved_instances_offering2.xml +5 -0
- data/spec/fixtures/ec2/tags.xml +12 -0
- data/spec/lib/awsum/ec2/image_spec.rb +60 -0
- data/spec/lib/awsum/ec2/instance_spec.rb +39 -1
- data/spec/lib/awsum/ec2/parsers/instance_parser_spec.rb +4 -3
- data/spec/lib/awsum/ec2/parsers/tag_parser_spec.rb +29 -0
- data/spec/lib/awsum/ec2/region_spec.rb +31 -2
- data/spec/lib/awsum/ec2/reserved_instance_spec.rb +3 -19
- data/spec/lib/awsum/ec2/security_group_spec.rb +123 -51
- data/spec/lib/awsum/ec2/snapshots_spec.rb +27 -1
- data/spec/lib/awsum/ec2/state_spec.rb +11 -0
- data/spec/lib/awsum/ec2/tag_spec.rb +45 -0
- data/spec/lib/awsum/ec2/volume_spec.rb +47 -0
- data/spec/lib/awsum/requestable_spec.rb +1 -1
- data/tools/dump.rb +55 -0
- metadata +176 -32
- data/.gitignore +0 -5
- data/spec/fixtures/ec2/purchase_reserved_instances_offerings.xml +0 -6
data/lib/awsum/ec2/image.rb
CHANGED
@@ -48,7 +48,7 @@ module Awsum
|
|
48
48
|
# * <tt>:key_name</tt> - The name of the key pair with which to launch instances
|
49
49
|
# * <tt>:security_groups</tt> - The names of security groups to associate launched instances with
|
50
50
|
# * <tt>:user_data</tt> - User data made available to instances (Note: Must be 16K or less, will be base64 encoded by Awsum)
|
51
|
-
# * <tt>:instance_type</tt> - The size of the instances to launch, can be one of [m1.small, m1.large, m1.xlarge, c1.medium, c1.xlarge], default is m1.small
|
51
|
+
# * <tt>:instance_type</tt> - The size of the instances to launch, can be one of [m1.small, m1.large, m1.xlarge, c1.medium, c1.xlarge, m2.xlarge, m2.2xlarge, m2.4xlarge, cc1.4xlarge, cg1.4xlarge, t1.micro], default is m1.small
|
52
52
|
# * <tt>:availability_zone</tt> - The name of the availability zone to launch this instance in
|
53
53
|
# * <tt>:kernel_id</tt> - The ID of the kernel with which to launch instances
|
54
54
|
# * <tt>:ramdisk_id</tt> - The ID of the RAM disk with which to launch instances
|
data/lib/awsum/ec2/instance.rb
CHANGED
@@ -23,6 +23,24 @@ module Awsum
|
|
23
23
|
@launch_index = launch_index
|
24
24
|
end
|
25
25
|
|
26
|
+
def reload
|
27
|
+
replacement_instance = @ec2.instance id
|
28
|
+
#TODO: Make this easier
|
29
|
+
@image_id = replacement_instance.image_id
|
30
|
+
@type = replacement_instance.type
|
31
|
+
@state = replacement_instance.state
|
32
|
+
@dns_name = replacement_instance.dns_name
|
33
|
+
@private_dns_name = replacement_instance.private_dns_name
|
34
|
+
@key_name = replacement_instance.key_name
|
35
|
+
@kernel_id = replacement_instance.kernel_id
|
36
|
+
@launch_time = replacement_instance.launch_time
|
37
|
+
@availability_zone = replacement_instance.availability_zone
|
38
|
+
@product_codes = replacement_instance.product_codes
|
39
|
+
@ramdisk_id = replacement_instance.ramdisk_id
|
40
|
+
@reason = replacement_instance.reason
|
41
|
+
@launch_index = replacement_instance.launch_index
|
42
|
+
end
|
43
|
+
|
26
44
|
# Terminates this instance
|
27
45
|
def terminate
|
28
46
|
@ec2.terminate_instances(id)
|
@@ -36,15 +54,26 @@ module Awsum
|
|
36
54
|
|
37
55
|
# Will create and attach a Volume to this Instance
|
38
56
|
# You must specify a size or a snapshot_id
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
57
|
+
#
|
58
|
+
# ===Options:
|
59
|
+
# :tags => Hash of tags
|
60
|
+
# :device => Will automatically attach the volume to the specified device
|
61
|
+
def create_volume(size_or_snapshot_id, options = {})
|
62
|
+
options = {:device => '/dev/sdh'}.merge(options)
|
63
|
+
if size_or_snapshot_id.is_a?(Numeric)
|
64
|
+
volume = @ec2.create_volume availability_zone, :size => size_or_snapshot_id
|
65
|
+
else
|
66
|
+
volume = @ec2.create_volume availability_zone, :snapshot_id => size_or_snapshot_id
|
67
|
+
end
|
68
|
+
if options[:tags]
|
69
|
+
@ec2.create_tags(volume.id, options[:tags])
|
70
|
+
end
|
44
71
|
while volume.status != 'available'
|
45
72
|
volume.reload
|
46
73
|
end
|
47
|
-
|
74
|
+
if options[:device]
|
75
|
+
attach volume, options[:device]
|
76
|
+
end
|
48
77
|
volume
|
49
78
|
end
|
50
79
|
|
@@ -10,8 +10,8 @@ module Awsum
|
|
10
10
|
|
11
11
|
def tag_start(tag, attributes)
|
12
12
|
case tag
|
13
|
-
when 'imagesSet'
|
14
|
-
@stack <<
|
13
|
+
when 'imagesSet', 'blockDeviceMapping', 'productCodes'
|
14
|
+
@stack << tag
|
15
15
|
when 'item'
|
16
16
|
case @stack[-1]
|
17
17
|
when 'imagesSet'
|
@@ -21,8 +21,6 @@ module Awsum
|
|
21
21
|
@product_codes = []
|
22
22
|
@text = ''
|
23
23
|
end
|
24
|
-
when 'productCodes'
|
25
|
-
@stack << 'productCodes'
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
@@ -34,7 +32,7 @@ module Awsum
|
|
34
32
|
case tag
|
35
33
|
when 'DescribeImagesResponse', 'requestId'
|
36
34
|
#no-op
|
37
|
-
when 'imagesSet', 'productCodes'
|
35
|
+
when 'imagesSet', 'productCodes', 'blockDeviceMapping'
|
38
36
|
@stack.pop
|
39
37
|
when 'item'
|
40
38
|
case @stack[-1]
|
@@ -12,16 +12,8 @@ module Awsum
|
|
12
12
|
|
13
13
|
def tag_start(tag, attributes)
|
14
14
|
case tag
|
15
|
-
when 'reservationSet'
|
16
|
-
@stack <<
|
17
|
-
when 'instancesSet'
|
18
|
-
@stack << 'instancesSet'
|
19
|
-
when 'productCodes'
|
20
|
-
@stack << 'productCodes'
|
21
|
-
when 'instanceState'
|
22
|
-
@stack << 'instanceState'
|
23
|
-
when 'placement'
|
24
|
-
@stack << 'placement'
|
15
|
+
when 'reservationSet', 'instancesSet', 'productCodes', 'instanceState', 'blockDeviceMapping', 'tagSet', 'placement'
|
16
|
+
@stack << tag
|
25
17
|
when 'item'
|
26
18
|
case @stack[-1]
|
27
19
|
when 'reservationSet'
|
@@ -30,6 +22,10 @@ module Awsum
|
|
30
22
|
@state = {}
|
31
23
|
when 'productCodes'
|
32
24
|
@product_codes = []
|
25
|
+
when 'blockDeviceMapping'
|
26
|
+
@blockDeviceMapping = {}
|
27
|
+
when 'tagSet'
|
28
|
+
@tagSet = {}
|
33
29
|
end
|
34
30
|
end
|
35
31
|
@text = ''
|
@@ -43,7 +39,7 @@ module Awsum
|
|
43
39
|
case tag
|
44
40
|
when 'DescribeInstancesResponse', 'requestId', 'reservationId'
|
45
41
|
#no-op
|
46
|
-
when 'reservationSet', 'instancesSet', 'productCodes', 'instanceState', 'placement'
|
42
|
+
when 'reservationSet', 'instancesSet', 'productCodes', 'instanceState', 'placement', 'blockDeviceMapping', 'tagSet'
|
47
43
|
@stack.pop
|
48
44
|
when 'item'
|
49
45
|
case @stack[-1]
|
@@ -53,7 +49,7 @@ module Awsum
|
|
53
49
|
@current['instanceId'],
|
54
50
|
@current['imageId'],
|
55
51
|
@current['instanceType'],
|
56
|
-
@state,
|
52
|
+
State.new(@state[:code], @state[:name]),
|
57
53
|
@current['dnsName'],
|
58
54
|
@current['privateDnsName'],
|
59
55
|
@current['keyName'],
|
@@ -75,9 +71,22 @@ module Awsum
|
|
75
71
|
when 'name'
|
76
72
|
@state[:name] = @text.strip if @stack[-1] == 'instanceState'
|
77
73
|
else
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
case @stack[-1]
|
75
|
+
when 'blockDeviceMapping'
|
76
|
+
unless @text.nil? || @blockDeviceMapping.nil?
|
77
|
+
text = @text.strip
|
78
|
+
@blockDeviceMapping[tag] = (text == '' ? nil : text)
|
79
|
+
end
|
80
|
+
when 'tagSet'
|
81
|
+
unless @text.nil? || @blockDeviceMapping.nil?
|
82
|
+
text = @text.strip
|
83
|
+
@blockDeviceMapping[tag] = (text == '' ? nil : text)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
unless @text.nil? || @current.nil?
|
87
|
+
text = @text.strip
|
88
|
+
@current[tag] = (text == '' ? nil : text)
|
89
|
+
end
|
81
90
|
end
|
82
91
|
end
|
83
92
|
end
|
@@ -15,8 +15,8 @@ module Awsum
|
|
15
15
|
end
|
16
16
|
|
17
17
|
case tag
|
18
|
-
when 'snapshotSet'
|
19
|
-
@stack <<
|
18
|
+
when 'snapshotSet', 'tagSet'
|
19
|
+
@stack << tag
|
20
20
|
when 'item', 'CreateSnapshotResponse'
|
21
21
|
case @stack[-1]
|
22
22
|
when 'snapshotSet'
|
@@ -34,7 +34,7 @@ module Awsum
|
|
34
34
|
case tag
|
35
35
|
when 'DescribeSnapshotsResponts'
|
36
36
|
#no-op
|
37
|
-
when 'snapshotSet'
|
37
|
+
when 'snapshotSet', 'tagSet'
|
38
38
|
@stack.pop
|
39
39
|
when 'item', 'CreateSnapshotResponse'
|
40
40
|
case @stack[-1]
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Awsum
|
2
|
+
class Ec2
|
3
|
+
class TagParser < Awsum::Parser #:nodoc:
|
4
|
+
def initialize(ec2)
|
5
|
+
@ec2 = ec2
|
6
|
+
@tags = []
|
7
|
+
@text = nil
|
8
|
+
@stack = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def tag_start(tag, attributes)
|
12
|
+
case tag
|
13
|
+
when 'tagSet'
|
14
|
+
@stack << tag
|
15
|
+
when 'item'
|
16
|
+
case @stack[-1]
|
17
|
+
when 'tagSet'
|
18
|
+
@current = {}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@text = ''
|
22
|
+
end
|
23
|
+
|
24
|
+
def text(text)
|
25
|
+
@text << text unless @text.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def tag_end(tag)
|
29
|
+
case tag
|
30
|
+
when 'tagSet'
|
31
|
+
@stack.pop
|
32
|
+
when 'item'
|
33
|
+
case @stack[-1]
|
34
|
+
when 'tagSet'
|
35
|
+
@tags << Tag.new(
|
36
|
+
@ec2,
|
37
|
+
@current['resourceId'],
|
38
|
+
@current['resourceType'],
|
39
|
+
@current['key'],
|
40
|
+
@current['value']
|
41
|
+
)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
unless @text.nil? || @current.nil?
|
45
|
+
text = @text.strip
|
46
|
+
@current[tag] = (text == '' ? nil : text)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def result
|
52
|
+
@tags
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -15,10 +15,8 @@ module Awsum
|
|
15
15
|
end
|
16
16
|
|
17
17
|
case tag
|
18
|
-
when 'volumeSet'
|
19
|
-
@stack <<
|
20
|
-
when 'attachmentSet'
|
21
|
-
@stack << 'attachmentSet'
|
18
|
+
when 'volumeSet', 'attachmentSet', 'tagSet'
|
19
|
+
@stack << tag
|
22
20
|
when 'item', 'CreateVolumeResponse'
|
23
21
|
case @stack[-1]
|
24
22
|
when 'volumeSet'
|
@@ -37,7 +35,7 @@ module Awsum
|
|
37
35
|
case tag
|
38
36
|
when 'DescribeVolumesResponse'
|
39
37
|
#no-op
|
40
|
-
when 'volumeSet', 'attachmentSet'
|
38
|
+
when 'volumeSet', 'attachmentSet', 'tagSet'
|
41
39
|
@stack.pop
|
42
40
|
when 'item', 'CreateVolumeResponse'
|
43
41
|
case @stack[-1]
|
data/lib/awsum/ec2/region.rb
CHANGED
@@ -30,15 +30,18 @@ module Awsum
|
|
30
30
|
# region.availability_zones
|
31
31
|
# end
|
32
32
|
def use(&block)
|
33
|
-
old_host = @ec2.host
|
34
|
-
@ec2.host = end_point
|
35
33
|
if block_given?
|
36
|
-
|
34
|
+
begin
|
35
|
+
old_host = @ec2.host
|
36
|
+
@ec2.host = end_point
|
37
|
+
block.arity < 1 ? instance_eval(&block) : block[self]
|
38
|
+
ensure
|
39
|
+
@ec2.host = old_host
|
40
|
+
end
|
37
41
|
else
|
42
|
+
@ec2.host = end_point
|
38
43
|
self
|
39
44
|
end
|
40
|
-
ensure
|
41
|
-
@ec2.host = old_host
|
42
45
|
end
|
43
46
|
|
44
47
|
private
|
@@ -14,24 +14,20 @@ module Awsum
|
|
14
14
|
@group_permissions = group_permissions
|
15
15
|
end
|
16
16
|
|
17
|
-
# Authorize access
|
18
|
-
|
19
|
-
|
17
|
+
# Authorize access
|
18
|
+
#
|
19
|
+
# ===Options:
|
20
|
+
# See Ec2#authorize_security_group_ingress
|
21
|
+
def authorize(arguments)
|
22
|
+
@ec2.authorize_security_group_ingress(@name, arguments)
|
20
23
|
end
|
21
24
|
|
22
|
-
# Revoke access
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def authorize_ip(from_port, to_port, protocol = 'tcp', cidr_ip = '0.0.0.0/0')
|
29
|
-
@ec2.authorize_security_group_ingress(@name, :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => cidr_ip)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Revoke access from an ip address
|
33
|
-
def revoke_ip(from_port, to_port, protocol = 'tcp', cidr_ip = '0.0.0.0/0')
|
34
|
-
@ec2.revoke_security_group_ingress(@name, :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => cidr_ip)
|
25
|
+
# Revoke access
|
26
|
+
#
|
27
|
+
# ===Options:
|
28
|
+
# See Ec2#revoke_security_group_ingress
|
29
|
+
def revoke(arguments)
|
30
|
+
@ec2.revoke_security_group_ingress(@name, arguments)
|
35
31
|
end
|
36
32
|
|
37
33
|
# Delete this SecurityGroup
|
data/lib/awsum/ec2/snapshot.rb
CHANGED
@@ -18,6 +18,15 @@ module Awsum
|
|
18
18
|
def delete
|
19
19
|
@ec2.delete_snapshot id
|
20
20
|
end
|
21
|
+
|
22
|
+
def reload
|
23
|
+
reloaded_snapshot = @ec2.snapshot id
|
24
|
+
|
25
|
+
@volume_id = reloaded_snapshot.volume_id
|
26
|
+
@status = reloaded_snapshot.status
|
27
|
+
@start_time = reloaded_snapshot.start_time
|
28
|
+
@progress = reloaded_snapshot.progress
|
29
|
+
end
|
21
30
|
end
|
22
31
|
end
|
23
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Awsum
|
2
|
+
class Ec2
|
3
|
+
class State
|
4
|
+
attr_reader :code, :name
|
5
|
+
|
6
|
+
def initialize(code, name)
|
7
|
+
@code = code.to_i
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
if other.is_a?(Numeric)
|
13
|
+
@code == other
|
14
|
+
elsif other.is_a?(String)
|
15
|
+
@name == other
|
16
|
+
else
|
17
|
+
@code = other.code && @name == other.name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'awsum/ec2/parsers/tag_parser'
|
2
|
+
|
3
|
+
module Awsum
|
4
|
+
class Ec2
|
5
|
+
class Tag
|
6
|
+
attr_reader :resource_id, :resource_type, :key, :value
|
7
|
+
|
8
|
+
def initialize(ec2, resource_id, resource_type, key, value) #:nodoc:
|
9
|
+
@ec2 = ec2
|
10
|
+
@resource_id = resource_id
|
11
|
+
@resource_type = resource_type
|
12
|
+
@key = key
|
13
|
+
@value = value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/awsum/ec2/volume.rb
CHANGED
@@ -50,9 +50,19 @@ module Awsum
|
|
50
50
|
@ec2.delete_volume id
|
51
51
|
end
|
52
52
|
|
53
|
+
# Force delete this volume
|
54
|
+
# will detach it first
|
55
|
+
def delete!
|
56
|
+
detach true
|
57
|
+
while status != 'available'
|
58
|
+
reload
|
59
|
+
end
|
60
|
+
@ec2.delete_volume id
|
61
|
+
end
|
62
|
+
|
53
63
|
# Creates a Snapshot of this Volume
|
54
|
-
def create_snapshot
|
55
|
-
@ec2.create_snapshot id
|
64
|
+
def create_snapshot(options = {})
|
65
|
+
@ec2.create_snapshot id, options
|
56
66
|
end
|
57
67
|
|
58
68
|
# Lists the Snapshot(s) of this Volume
|
data/lib/awsum/requestable.rb
CHANGED
@@ -197,14 +197,64 @@ module Awsum
|
|
197
197
|
|
198
198
|
# Converts an array of paramters into <param_name>.<num> format
|
199
199
|
def array_to_params(arr, param_name)
|
200
|
-
arr = [arr]
|
200
|
+
arr = [arr].flatten
|
201
201
|
params = {}
|
202
|
-
arr.each_with_index do |value,i|
|
203
|
-
|
202
|
+
arr.each_with_index do |value, i|
|
203
|
+
if value.respond_to?(:keys)
|
204
|
+
value.each do |key, val|
|
205
|
+
param_key = "#{param_name}.#{i+1}.#{parameterize(key)}"
|
206
|
+
if val.is_a?(Array) || val.respond_to?(:keys)
|
207
|
+
params.merge! array_to_params(val, param_key)
|
208
|
+
else
|
209
|
+
params[param_key] = val
|
210
|
+
end
|
211
|
+
end
|
212
|
+
else
|
213
|
+
params["#{param_name}.#{i+1}"] = value
|
214
|
+
end
|
204
215
|
end
|
205
216
|
params
|
206
217
|
end
|
207
218
|
|
219
|
+
def parameterize(string)
|
220
|
+
string.to_s.split(/_/).map{ |w| w.downcase.sub(/^(.)/){ $1.upcase } }.join
|
221
|
+
end
|
222
|
+
|
223
|
+
def parse_filters(filters, tags = nil)
|
224
|
+
result = []
|
225
|
+
if filters
|
226
|
+
filters.each do |k,v|
|
227
|
+
values = v.is_a?(Array) ? v : [v]
|
228
|
+
result << {:name => k, :value => values}
|
229
|
+
end
|
230
|
+
end
|
231
|
+
if tags
|
232
|
+
tags.each do |k,v|
|
233
|
+
values = v.is_a?(Array) ? v : [v]
|
234
|
+
result << {:name => "tag:#{k}", :value => values}
|
235
|
+
end
|
236
|
+
end
|
237
|
+
if result.size > 0
|
238
|
+
array_to_params(result, "Filter")
|
239
|
+
else
|
240
|
+
{}
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def parse_tag_keys(tags)
|
245
|
+
result = []
|
246
|
+
if tags
|
247
|
+
tags.each do |k,v|
|
248
|
+
result << {:key => k, :value => v}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
if result.size > 0
|
252
|
+
array_to_params(result, "Tag")
|
253
|
+
else
|
254
|
+
{}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
208
258
|
# Sign a string with a digest, wrap in HMAC digest and base64 encode
|
209
259
|
#
|
210
260
|
# ===Returns
|