amazon-ec2 0.0.2 → 0.0.3
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/CHANGELOG.txt +27 -5
- data/History.txt +0 -8
- data/Manifest.txt +7 -0
- data/README.txt +1 -1
- data/lib/EC2.rb +108 -497
- data/lib/EC2/image_attributes.rb +47 -0
- data/lib/EC2/images.rb +87 -0
- data/lib/EC2/instances.rb +95 -0
- data/lib/EC2/keypairs.rb +38 -0
- data/lib/EC2/responses.rb +340 -0
- data/lib/EC2/security_groups.rb +140 -0
- data/lib/EC2/version.rb +1 -1
- metadata +8 -2
@@ -0,0 +1,47 @@
|
|
1
|
+
# Amazon Web Services EC2 Query API Ruby Library
|
2
|
+
# This library has been packaged as a Ruby Gem
|
3
|
+
# by Glenn Rempe ( glenn @nospam@ elasticworkbench.com ).
|
4
|
+
#
|
5
|
+
# Source code and gem hosted on RubyForge
|
6
|
+
# under the Ruby License as of 12/14/2006:
|
7
|
+
# http://amazon-ec2.rubyforge.org
|
8
|
+
|
9
|
+
module EC2
|
10
|
+
|
11
|
+
class AWSAuthConnection
|
12
|
+
|
13
|
+
# The ModifyImageAttribute operation modifies an attribute of an AMI.
|
14
|
+
#
|
15
|
+
# Currently the only attribute supported is launchPermission. By
|
16
|
+
# modifying this attribute it is possible to make an AMI public or
|
17
|
+
# to grant specific users launch permissions for the AMI. To make the
|
18
|
+
# AMI public add the group=all attribute item. To grant launch permissions
|
19
|
+
# for a specific user add a userId=<userid> attribute item.
|
20
|
+
def modify_image_attribute(imageId, attribute, operationType, attributeValueHash)
|
21
|
+
params = {
|
22
|
+
"ImageId" => imageId,
|
23
|
+
"Attribute" => attribute,
|
24
|
+
"OperationType" => operationType
|
25
|
+
}
|
26
|
+
if attribute == "launchPermission"
|
27
|
+
params.merge!(pathlist("UserGroup", attributeValueHash[:userGroups])) if attributeValueHash.has_key? :userGroups
|
28
|
+
params.merge!(pathlist("UserId", attributeValueHash[:userIds])) if attributeValueHash.has_key? :userIds
|
29
|
+
end
|
30
|
+
ModifyImageAttributeResponse.new(make_request("ModifyImageAttribute", params))
|
31
|
+
end
|
32
|
+
|
33
|
+
# The DescribeImageAttribute operation returns information about an attribute of an AMI.
|
34
|
+
def describe_image_attribute(imageId, attribute)
|
35
|
+
params = { "ImageId" => imageId, "Attribute" => attribute }
|
36
|
+
DescribeImageAttributeResponse.new(make_request("DescribeImageAttribute", params))
|
37
|
+
end
|
38
|
+
|
39
|
+
# The ResetImageAttribute operation resets an attribute of an AMI to its default value.
|
40
|
+
def reset_image_attribute(imageId, attribute)
|
41
|
+
params = { "ImageId" => imageId, "Attribute" => attribute }
|
42
|
+
ResetImageAttributeResponse.new(make_request("ResetImageAttribute", params))
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/EC2/images.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Amazon Web Services EC2 Query API Ruby Library
|
2
|
+
# This library has been packaged as a Ruby Gem
|
3
|
+
# by Glenn Rempe ( glenn @nospam@ elasticworkbench.com ).
|
4
|
+
#
|
5
|
+
# Source code and gem hosted on RubyForge
|
6
|
+
# under the Ruby License as of 12/14/2006:
|
7
|
+
# http://amazon-ec2.rubyforge.org
|
8
|
+
|
9
|
+
module EC2
|
10
|
+
|
11
|
+
class AWSAuthConnection
|
12
|
+
|
13
|
+
# The RegisterImage operation registers an AMI with Amazon EC2.
|
14
|
+
# Images must be registered before they can be launched. Each
|
15
|
+
# AMI is associated with an unique ID which is provided by the
|
16
|
+
# EC2 service via the Registerimage operation. As part of the
|
17
|
+
# registration process, Amazon EC2 will retrieve the specified
|
18
|
+
# image manifest from Amazon S3 and verify that the image is
|
19
|
+
# owned by the user requesting image registration. The image
|
20
|
+
# manifest is retrieved once and stored within the Amazon EC2
|
21
|
+
# network. Any modifications to an image in Amazon S3 invalidate
|
22
|
+
# this registration. If you do have to make changes and upload
|
23
|
+
# a new image deregister the previous image and register the new image.
|
24
|
+
def register_image(imageLocation)
|
25
|
+
params = { "ImageLocation" => imageLocation }
|
26
|
+
RegisterImageResponse.new(make_request("RegisterImage", params))
|
27
|
+
end
|
28
|
+
|
29
|
+
# The DescribeImages operation returns information about AMIs available
|
30
|
+
# for use by the user. This includes both public AMIs (those available
|
31
|
+
# for any user to launch) and private AMIs (those owned by the user
|
32
|
+
# making the request and those owned by other users that the user
|
33
|
+
# making the request has explicit launch permissions for).
|
34
|
+
#
|
35
|
+
# The list of AMIs returned can be modified via optional lists of AMI IDs,
|
36
|
+
# owners or users with launch permissions. If all three optional lists
|
37
|
+
# are empty all AMIs the user has launch permissions for are returned.
|
38
|
+
# Launch permissions fall into three categories:
|
39
|
+
#
|
40
|
+
# Launch Permission Description
|
41
|
+
# * public The all group has launch permissions for the AMI. All users have
|
42
|
+
# launch permissions for these AMIs.
|
43
|
+
# * explicit The owner of the AMIs has granted a specific user launch permissions for the AMI.
|
44
|
+
# * implicit A user has implicit launch permissions for all AMIs he or she owns.
|
45
|
+
#
|
46
|
+
# If one or more of the lists are specified the result set is the intersection
|
47
|
+
# of AMIs matching the criteria of the individual lists.
|
48
|
+
#
|
49
|
+
# Providing the list of AMI IDs requests information for those AMIs only.
|
50
|
+
# If no AMI IDs are provided, information of all relevant AMIs will be
|
51
|
+
# returned. If an AMI is specified that does not exist a fault is returned.
|
52
|
+
# If an AMI is specified that exists but the user making the request does
|
53
|
+
# not have launch permissions for, then that AMI will not be included in
|
54
|
+
# the returned results.
|
55
|
+
#
|
56
|
+
# Providing the list of owners requests information for AMIs owned
|
57
|
+
# by the specified owners only. Only AMIs the user has launch permissions
|
58
|
+
# for are returned. The items of the list may be account ids for AMIs
|
59
|
+
# owned by users with those account ids, amazon for AMIs owned by Amazon
|
60
|
+
# or self for AMIs owned by the user making the request.
|
61
|
+
#
|
62
|
+
# The executable list may be provided to request information for AMIs
|
63
|
+
# that only the specified users have launch permissions for. The items of
|
64
|
+
# the list may be account ids for AMIs owned by the user making the request
|
65
|
+
# that the users with the specified account ids have explicit launch permissions
|
66
|
+
# for, self for AMIs the user making the request has explicit launch permissions
|
67
|
+
# for or all for public AMIs.
|
68
|
+
#
|
69
|
+
# Deregistered images will be included in the returned results for an
|
70
|
+
# unspecified interval subsequent to deregistration.
|
71
|
+
def describe_images(imageIds=[], owners=[], executableBy=[])
|
72
|
+
params = pathlist("ImageId", imageIds)
|
73
|
+
params.merge!(pathlist("Owner", owners))
|
74
|
+
params.merge!(pathlist("ExecutableBy", executableBy))
|
75
|
+
DescribeImagesResponse.new(make_request("DescribeImages", params))
|
76
|
+
end
|
77
|
+
|
78
|
+
# The DeregisterImage operation deregisters an AMI. Once deregistered,
|
79
|
+
# instances of the AMI may no longer be launched.
|
80
|
+
def deregister_image(imageId)
|
81
|
+
params = { "ImageId" => imageId }
|
82
|
+
DeregisterImageResponse.new(make_request("DeregisterImage", params))
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Amazon Web Services EC2 Query API Ruby Library
|
2
|
+
# This library has been packaged as a Ruby Gem
|
3
|
+
# by Glenn Rempe ( glenn @nospam@ elasticworkbench.com ).
|
4
|
+
#
|
5
|
+
# Source code and gem hosted on RubyForge
|
6
|
+
# under the Ruby License as of 12/14/2006:
|
7
|
+
# http://amazon-ec2.rubyforge.org
|
8
|
+
|
9
|
+
module EC2
|
10
|
+
|
11
|
+
class AWSAuthConnection
|
12
|
+
|
13
|
+
# The RunInstances operation launches a specified number of instances.
|
14
|
+
#
|
15
|
+
# Note:
|
16
|
+
# The Query version of RunInstances only allows instances of a
|
17
|
+
# single AMI to be launched in one call. This is different
|
18
|
+
# from the SOAP API call of the same name but similar to the
|
19
|
+
# ec2-run-instances command line tool.
|
20
|
+
#
|
21
|
+
# A call to RunInstances is guaranteed to start no fewer than the
|
22
|
+
# requested minimum. If there is insufficient capacity available
|
23
|
+
# then no instances will be started. Amazon EC2 will make a best
|
24
|
+
# effort attempt to satisfy the requested maximum values.
|
25
|
+
#
|
26
|
+
# Every instance is launched in a security group. This may be
|
27
|
+
# specified as part of the launch request. If a security group is
|
28
|
+
# not indicated then instances are started in a the default security group.
|
29
|
+
#
|
30
|
+
# An optional keypair ID may be provided for each image in the launch
|
31
|
+
# request. All instances that are created from images for which this
|
32
|
+
# is provided will have access to the associated public key at boot
|
33
|
+
# time (detailed below). This key may be used to provide secure access
|
34
|
+
# to an instance of an image on a per-instance basis. Amazon EC2 public
|
35
|
+
# images make use of this functionality to provide secure passwordless
|
36
|
+
# access to instances (and launching those images without a keypair ID
|
37
|
+
# will leave them inaccessible).
|
38
|
+
#
|
39
|
+
# The public key material is made available to the instance at boot
|
40
|
+
# time by placing it in a file named openssh_id.pub on a logical
|
41
|
+
# device that is exposed to the instance as /dev/sda2 (the ephemeral store).
|
42
|
+
# The format of this file is suitable for use as an entry within
|
43
|
+
# ~/.ssh/authorized_keys (the OpenSSH format). This can be done at boot
|
44
|
+
# time (as part of rclocal, for example) allowing for secure
|
45
|
+
# password-less access. As the need arises, other formats will
|
46
|
+
# also be considered.
|
47
|
+
def run_instances(imageId, kwargs={})
|
48
|
+
in_params = { :minCount=>1, :maxCount=>1, :keyname=>nil, :groupIds=>[], :userData=>nil, :base64Encoded=>false }
|
49
|
+
in_params.merge!(kwargs)
|
50
|
+
userData = Base64.encode64(userData) if userData and not base64Encoded
|
51
|
+
|
52
|
+
params = {
|
53
|
+
"ImageId" => imageId,
|
54
|
+
"MinCount" => in_params[:minCount].to_s,
|
55
|
+
"MaxCount" => in_params[:maxCount].to_s,
|
56
|
+
}.merge(pathlist("SecurityGroup", in_params[:groupIds]))
|
57
|
+
|
58
|
+
params["KeyName"] = in_params[:keyname] unless in_params[:keyname].nil?
|
59
|
+
|
60
|
+
RunInstancesResponse.new(make_request("RunInstances", params))
|
61
|
+
end
|
62
|
+
|
63
|
+
# The DescribeInstances operation returns information about instances owned
|
64
|
+
# by the user making the request.
|
65
|
+
#
|
66
|
+
# An optional list of instance IDs may be provided to request information
|
67
|
+
# for those instances only. If no instance IDs are provided, information of
|
68
|
+
# all relevant instances information will be returned. If an instance is
|
69
|
+
# specified that does not exist a fault is returned. If an instance is specified
|
70
|
+
# that exists but is not owned by the user making the request, then that
|
71
|
+
# instance will not be included in the returned results.
|
72
|
+
#
|
73
|
+
# Recently terminated instances will be included in the returned results
|
74
|
+
# for a small interval subsequent to their termination. This interval
|
75
|
+
# is typically of the order of one hour.
|
76
|
+
def describe_instances(instanceIds=[])
|
77
|
+
params = pathlist("InstanceId", instanceIds)
|
78
|
+
DescribeInstancesResponse.new(make_request("DescribeInstances", params))
|
79
|
+
end
|
80
|
+
|
81
|
+
# The TerminateInstances operation shuts down one or more instances.
|
82
|
+
# This operation is idempotent and terminating an instance that is
|
83
|
+
# in the process of shutting down (or already terminated) will succeed.
|
84
|
+
#
|
85
|
+
# Terminated instances remain visible for a short period of time
|
86
|
+
# (approximately one hour) after termination, after which their
|
87
|
+
# instance ID is invalidated.
|
88
|
+
def terminate_instances(instanceIds)
|
89
|
+
params = pathlist("InstanceId", instanceIds)
|
90
|
+
TerminateInstancesResponse.new(make_request("TerminateInstances", params))
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
data/lib/EC2/keypairs.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Amazon Web Services EC2 Query API Ruby Library
|
2
|
+
# This library has been packaged as a Ruby Gem
|
3
|
+
# by Glenn Rempe ( glenn @nospam@ elasticworkbench.com ).
|
4
|
+
#
|
5
|
+
# Source code and gem hosted on RubyForge
|
6
|
+
# under the Ruby License as of 12/14/2006:
|
7
|
+
# http://amazon-ec2.rubyforge.org
|
8
|
+
|
9
|
+
module EC2
|
10
|
+
|
11
|
+
class AWSAuthConnection
|
12
|
+
|
13
|
+
# The CreateKeyPair operation creates a new 2048 bit RSA keypair
|
14
|
+
# and returns a unique ID that can be used to reference this
|
15
|
+
# keypair when launching new instances.
|
16
|
+
def create_keypair(keyName)
|
17
|
+
params = { "KeyName" => keyName }
|
18
|
+
CreateKeyPairResponse.new(make_request("CreateKeyPair", params))
|
19
|
+
end
|
20
|
+
|
21
|
+
# The DescribeKeyPairs operation returns information about keypairs
|
22
|
+
# available for use by the user making the request. Selected keypairs
|
23
|
+
# may be specified or the list may be left empty if information for
|
24
|
+
# all registered keypairs is required.
|
25
|
+
def describe_keypairs(keyNames=[])
|
26
|
+
params = pathlist("KeyName", keyNames)
|
27
|
+
DescribeKeyPairsResponse.new(make_request("DescribeKeyPairs", params))
|
28
|
+
end
|
29
|
+
|
30
|
+
# The DeleteKeyPair operation deletes a keypair.
|
31
|
+
def delete_keypair(keyName)
|
32
|
+
params = { "KeyName" => keyName }
|
33
|
+
DeleteKeyPairResponse.new(make_request("DeleteKeyPair", params))
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,340 @@
|
|
1
|
+
# Amazon Web Services EC2 Query API Ruby Library
|
2
|
+
# This library has been packaged as a Ruby Gem
|
3
|
+
# by Glenn Rempe ( glenn @nospam@ elasticworkbench.com ).
|
4
|
+
#
|
5
|
+
# Source code and gem hosted on RubyForge
|
6
|
+
# under the Ruby License as of 12/14/2006:
|
7
|
+
# http://amazon-ec2.rubyforge.org
|
8
|
+
|
9
|
+
module EC2
|
10
|
+
|
11
|
+
class Response
|
12
|
+
attr_reader :http_response
|
13
|
+
attr_reader :http_xml
|
14
|
+
attr_reader :structure
|
15
|
+
|
16
|
+
ERROR_XPATH = "Response/Errors/Error"
|
17
|
+
|
18
|
+
def initialize(http_response)
|
19
|
+
@http_response = http_response
|
20
|
+
@http_xml = http_response.body
|
21
|
+
@is_error = false
|
22
|
+
if http_response.is_a? Net::HTTPSuccess
|
23
|
+
@structure = parse
|
24
|
+
else
|
25
|
+
@is_error = true
|
26
|
+
@structure = parse_error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def is_error?
|
31
|
+
@is_error
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_error
|
35
|
+
doc = Document.new(@http_xml)
|
36
|
+
element = XPath.first(doc, ERROR_XPATH)
|
37
|
+
|
38
|
+
errorCode = XPath.first(element, "Code").text
|
39
|
+
errorMessage = XPath.first(element, "Message").text
|
40
|
+
|
41
|
+
[["#{errorCode}: #{errorMessage}"]]
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse
|
45
|
+
# Placeholder -- this method should be overridden in child classes.
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
@structure.collect do |line|
|
51
|
+
line.join("\t")
|
52
|
+
end.join("\n")
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class DescribeImagesResponse < Response
|
59
|
+
ELEMENT_XPATH = "DescribeImagesResponse/imagesSet/item"
|
60
|
+
def parse
|
61
|
+
doc = Document.new(@http_xml)
|
62
|
+
lines = []
|
63
|
+
|
64
|
+
doc.elements.each(ELEMENT_XPATH) do |element|
|
65
|
+
imageId = XPath.first(element, "imageId").text
|
66
|
+
imageLocation = XPath.first(element, "imageLocation").text
|
67
|
+
imageOwnerId = XPath.first(element, "imageOwnerId").text
|
68
|
+
imageState = XPath.first(element, "imageState").text
|
69
|
+
isPublic = XPath.first(element, "isPublic").text
|
70
|
+
lines << ["IMAGE", imageId, imageLocation, imageOwnerId, imageState, isPublic]
|
71
|
+
end
|
72
|
+
lines
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
class RegisterImageResponse < Response
|
78
|
+
ELEMENT_XPATH = "RegisterImageResponse/imageId"
|
79
|
+
def parse
|
80
|
+
doc = Document.new(@http_xml)
|
81
|
+
lines = [["IMAGE", XPath.first(doc, ELEMENT_XPATH).text]]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
class DeregisterImageResponse < Response
|
87
|
+
def parse
|
88
|
+
# If we don't get an error, the deregistration succeeded.
|
89
|
+
[["Image deregistered."]]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
class CreateKeyPairResponse < Response
|
95
|
+
ELEMENT_XPATH = "CreateKeyPairResponse"
|
96
|
+
def parse
|
97
|
+
doc = Document.new(@http_xml)
|
98
|
+
element = XPath.first(doc, ELEMENT_XPATH)
|
99
|
+
|
100
|
+
keyName = XPath.first(element, "keyName").text
|
101
|
+
keyFingerprint = XPath.first(element, "keyFingerprint").text
|
102
|
+
keyMaterial = XPath.first(element, "keyMaterial").text
|
103
|
+
|
104
|
+
line = [["KEYPAIR", keyName, keyFingerprint], [keyMaterial]]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
class DescribeKeyPairsResponse < Response
|
110
|
+
ELEMENT_XPATH = "DescribeKeyPairsResponse/keySet/item"
|
111
|
+
def parse
|
112
|
+
doc = Document.new(@http_xml)
|
113
|
+
lines = []
|
114
|
+
|
115
|
+
doc.elements.each(ELEMENT_XPATH) do |element|
|
116
|
+
keyName = XPath.first(element, "keyName").text
|
117
|
+
keyFingerprint = XPath.first(element, "keyFingerprint").text
|
118
|
+
lines << ["KEYPAIR", keyName, keyFingerprint]
|
119
|
+
end
|
120
|
+
lines
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
class DeleteKeyPairResponse < Response
|
126
|
+
def parse
|
127
|
+
# If we don't get an error, the deletion succeeded.
|
128
|
+
[["Keypair deleted."]]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
class RunInstancesResponse < Response
|
134
|
+
ELEMENT_XPATH = "RunInstancesResponse"
|
135
|
+
def parse
|
136
|
+
doc = Document.new(@http_xml)
|
137
|
+
lines = []
|
138
|
+
|
139
|
+
rootelement = XPath.first(doc, ELEMENT_XPATH)
|
140
|
+
|
141
|
+
reservationId = XPath.first(rootelement, "reservationId").text
|
142
|
+
ownerId = XPath.first(rootelement, "ownerId").text
|
143
|
+
groups = nil
|
144
|
+
rootelement.elements.each("groupSet/item/groupId") do |element|
|
145
|
+
if not groups
|
146
|
+
groups = element.text
|
147
|
+
else
|
148
|
+
groups += "," + element.text
|
149
|
+
end
|
150
|
+
end
|
151
|
+
lines << ["RESERVATION", reservationId, ownerId, groups]
|
152
|
+
|
153
|
+
# rootelement = XPath.first(doc, ELEMENT_XPATH)
|
154
|
+
rootelement.elements.each("instancesSet/item") do |element|
|
155
|
+
instanceId = XPath.first(element, "instanceId").text
|
156
|
+
imageId = XPath.first(element, "imageId").text
|
157
|
+
instanceState = XPath.first(element, "instanceState/name").text
|
158
|
+
# Only for debug mode, which we don't support yet:
|
159
|
+
instanceStateCode = XPath.first(element, "instanceState/code").text
|
160
|
+
dnsName = XPath.first(element, "dnsName").text
|
161
|
+
# We don't return this, but still:
|
162
|
+
reason = XPath.first(element, "reason").text
|
163
|
+
lines << ["INSTANCE", instanceId, imageId, dnsName, instanceState]
|
164
|
+
end
|
165
|
+
lines
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
class DescribeInstancesResponse < Response
|
171
|
+
ELEMENT_XPATH = "DescribeInstancesResponse/reservationSet/item"
|
172
|
+
def parse
|
173
|
+
doc = Document.new(@http_xml)
|
174
|
+
lines = []
|
175
|
+
|
176
|
+
doc.elements.each(ELEMENT_XPATH) do |rootelement|
|
177
|
+
reservationId = XPath.first(rootelement, "reservationId").text
|
178
|
+
ownerId = XPath.first(rootelement, "ownerId").text
|
179
|
+
groups = nil
|
180
|
+
rootelement.elements.each("groupSet/item/groupId") do |element|
|
181
|
+
if not groups
|
182
|
+
groups = element.text
|
183
|
+
else
|
184
|
+
groups += "," + element.text
|
185
|
+
end
|
186
|
+
end
|
187
|
+
lines << ["RESERVATION", reservationId, ownerId, groups]
|
188
|
+
|
189
|
+
rootelement.elements.each("instancesSet/item") do |element|
|
190
|
+
instanceId = XPath.first(element, "instanceId").text
|
191
|
+
imageId = XPath.first(element, "imageId").text
|
192
|
+
instanceState = XPath.first(element, "instanceState/name").text
|
193
|
+
# Only for debug mode, which we don't support yet:
|
194
|
+
instanceStateCode = XPath.first(element, "instanceState/code").text
|
195
|
+
dnsName = XPath.first(element, "dnsName").text
|
196
|
+
# We don't return this, but still:
|
197
|
+
reason = XPath.first(element, "reason").text
|
198
|
+
lines << ["INSTANCE", instanceId, imageId, dnsName, instanceState]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
lines
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
class TerminateInstancesResponse < Response
|
207
|
+
ELEMENT_XPATH = "TerminateInstancesResponse/instancesSet/item"
|
208
|
+
def parse
|
209
|
+
doc = Document.new(@http_xml)
|
210
|
+
lines = []
|
211
|
+
|
212
|
+
doc.elements.each(ELEMENT_XPATH) do |element|
|
213
|
+
instanceId = XPath.first(element, "instanceId").text
|
214
|
+
shutdownState = XPath.first(element, "shutdownState/name").text
|
215
|
+
# Only for debug mode, which we don't support yet:
|
216
|
+
shutdownStateCode = XPath.first(element, "shutdownState/code").text
|
217
|
+
previousState = XPath.first(element, "previousState/name").text
|
218
|
+
# Only for debug mode, which we don't support yet:
|
219
|
+
previousStateCode = XPath.first(element, "previousState/code").text
|
220
|
+
lines << ["INSTANCE", instanceId, previousState, shutdownState]
|
221
|
+
end
|
222
|
+
lines
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
class CreateSecurityGroupResponse < Response
|
228
|
+
def parse
|
229
|
+
# If we don't get an error, the creation succeeded.
|
230
|
+
[["Security Group created."]]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
class DescribeSecurityGroupsResponse < Response
|
236
|
+
ELEMENT_XPATH = "DescribeSecurityGroupsResponse/securityGroupInfo/item"
|
237
|
+
def parse
|
238
|
+
doc = Document.new(@http_xml)
|
239
|
+
lines = []
|
240
|
+
|
241
|
+
doc.elements.each(ELEMENT_XPATH) do |rootelement|
|
242
|
+
groupName = XPath.first(rootelement, "groupName").text
|
243
|
+
ownerId = XPath.first(rootelement, "ownerId").text
|
244
|
+
groupDescription = XPath.first(rootelement, "groupDescription").text
|
245
|
+
lines << ["GROUP", ownerId, groupName, groupDescription]
|
246
|
+
rootelement.elements.each("ipPermissions/item") do |element|
|
247
|
+
ipProtocol = XPath.first(element, "ipProtocol").text
|
248
|
+
fromPort = XPath.first(element, "fromPort").text
|
249
|
+
toPort = XPath.first(element, "toPort").text
|
250
|
+
permArr = [
|
251
|
+
"PERMISSION",
|
252
|
+
ownerId,
|
253
|
+
groupName,
|
254
|
+
"ALLOWS",
|
255
|
+
ipProtocol,
|
256
|
+
fromPort,
|
257
|
+
toPort,
|
258
|
+
"FROM"
|
259
|
+
]
|
260
|
+
element.elements.each("groups/item") do |subelement|
|
261
|
+
userId = XPath.first(subelement, "userId").text
|
262
|
+
targetGroupName = XPath.first(subelement, "groupName").text
|
263
|
+
lines << permArr + ["USER", userId, "GRPNAME", targetGroupName]
|
264
|
+
end
|
265
|
+
element.elements.each("ipRanges/item") do |subelement|
|
266
|
+
cidrIp = XPath.first(subelement, "cidrIp").text
|
267
|
+
lines << permArr + ["CIDR", cidrIp]
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
lines
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
class DeleteSecurityGroupResponse < Response
|
277
|
+
def parse
|
278
|
+
# If we don't get an error, the deletion succeeded.
|
279
|
+
[["Security Group deleted."]]
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
class AuthorizeSecurityGroupIngressResponse < Response
|
285
|
+
def parse
|
286
|
+
# If we don't get an error, the authorization succeeded.
|
287
|
+
[["Ingress authorized."]]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
class RevokeSecurityGroupIngressResponse < Response
|
293
|
+
def parse
|
294
|
+
# If we don't get an error, the revocation succeeded.
|
295
|
+
[["Ingress revoked."]]
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
class ModifyImageAttributeResponse < Response
|
301
|
+
def parse
|
302
|
+
# If we don't get an error, modification succeeded.
|
303
|
+
[["Image attribute modified."]]
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
class ResetImageAttributeResponse < Response
|
309
|
+
def parse
|
310
|
+
# If we don't get an error, reset succeeded.
|
311
|
+
[["Image attribute reset."]]
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
class DescribeImageAttributeResponse < Response
|
317
|
+
ELEMENT_XPATH = "DescribeImageAttributeResponse"
|
318
|
+
def parse
|
319
|
+
doc = Document.new(@http_xml)
|
320
|
+
lines = []
|
321
|
+
|
322
|
+
rootelement = XPath.first(doc, ELEMENT_XPATH)
|
323
|
+
imageId = XPath.first(rootelement, "imageId").text
|
324
|
+
|
325
|
+
# Handle launchPermission attributes:
|
326
|
+
rootelement.elements.each("launchPermission/item/*") do |element|
|
327
|
+
lines << [
|
328
|
+
"launchPermission",
|
329
|
+
imageId,
|
330
|
+
element.name,
|
331
|
+
element.text
|
332
|
+
]
|
333
|
+
end
|
334
|
+
lines
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
# end EC2 Module
|
339
|
+
end
|
340
|
+
|