amazon-ec2 0.2.5 → 0.2.6
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 +9 -0
- data/Manifest.txt +0 -2
- data/README.txt +1 -1
- data/lib/EC2.rb +60 -60
- data/lib/EC2/console.rb +11 -11
- data/lib/EC2/exceptions.rb +35 -35
- data/lib/EC2/image_attributes.rb +39 -39
- data/lib/EC2/images.rb +58 -58
- data/lib/EC2/instances.rb +86 -73
- data/lib/EC2/keypairs.rb +26 -26
- data/lib/EC2/products.rb +10 -10
- data/lib/EC2/responses.rb +37 -37
- data/lib/EC2/security_groups.rb +79 -79
- data/lib/EC2/version.rb +1 -1
- data/test/test_EC2.rb +10 -10
- data/test/test_EC2_console.rb +15 -15
- data/test/test_EC2_image_attributes.rb +74 -74
- data/test/test_EC2_images.rb +45 -45
- data/test/test_EC2_instances.rb +103 -88
- data/test/test_EC2_keypairs.rb +24 -24
- data/test/test_EC2_products.rb +10 -10
- data/test/test_EC2_responses.rb +29 -29
- data/test/test_EC2_security_groups.rb +50 -50
- data/test/test_EC2_version.rb +13 -13
- data/test/test_helper.rb +1 -1
- data/website/index.html +1 -1
- metadata +2 -4
- data/website/announce.html +0 -109
- data/website/announce.txt +0 -36
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 0.2.6 2007-10-16
|
2
|
+
* Updated to support EC2 API version 2007-08-29 released on 2007-10-16
|
3
|
+
* Supports new instances type feature. Specify an instance type to launch
|
4
|
+
(m1.small, m1.large, m1.xlarge) when you call the 'run_instances' method.
|
5
|
+
|
6
|
+
e.g. add to the params hash ':instance_type => "m1.small"'
|
7
|
+
* RunInstances and DescribeInstances now return the time when the Amazon EC2 instance was launched.
|
8
|
+
* Code Tidyup : Removed trailing spaces in code docs.
|
9
|
+
|
1
10
|
=== 0.2.5 2007-09-26
|
2
11
|
* Updated using Dr. Nic's newgem v. 0.13.5
|
3
12
|
* Updated email address.
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
data/lib/EC2.rb
CHANGED
@@ -12,25 +12,25 @@
|
|
12
12
|
|
13
13
|
# Require any lib files that we have bundled with this Ruby Gem in the lib/EC2 directory.
|
14
14
|
# Parts of the EC2 module and Base class are broken out into separate
|
15
|
-
# files for maintainability and are organized by the functional groupings defined
|
15
|
+
# files for maintainability and are organized by the functional groupings defined
|
16
16
|
# in the EC2 API developers guide.
|
17
17
|
Dir[File.join(File.dirname(__FILE__), 'EC2/**/*.rb')].sort.each { |lib| require lib }
|
18
18
|
|
19
19
|
module EC2
|
20
|
-
|
20
|
+
|
21
21
|
# Which host FQDN will we connect to for all API calls to AWS?
|
22
22
|
DEFAULT_HOST = 'ec2.amazonaws.com'
|
23
|
-
|
23
|
+
|
24
24
|
# This is the version of the API as defined by Amazon Web Services
|
25
|
-
API_VERSION = '2007-
|
26
|
-
|
25
|
+
API_VERSION = '2007-08-29'
|
26
|
+
|
27
27
|
# This release version is passed in with each request as part
|
28
|
-
# of the HTTP 'User-Agent' header. Set this be the same value
|
28
|
+
# of the HTTP 'User-Agent' header. Set this be the same value
|
29
29
|
# as what is stored in the lib/EC2/version.rb module constant instead.
|
30
|
-
# This way we keep it nice and DRY and only have to define the
|
31
|
-
# version number in a single place.
|
30
|
+
# This way we keep it nice and DRY and only have to define the
|
31
|
+
# version number in a single place.
|
32
32
|
RELEASE_VERSION = EC2::VERSION::STRING
|
33
|
-
|
33
|
+
|
34
34
|
# Builds the canonical string for signing. This strips out all '&', '?', and '='
|
35
35
|
# from the query string to be signed.
|
36
36
|
# Note: The parameters in the path passed in must already be sorted in
|
@@ -42,7 +42,7 @@ module EC2
|
|
42
42
|
}
|
43
43
|
return buf
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# Encodes the given string with the secret_access_key, by taking the
|
47
47
|
# hmac-sha1 sum, and then base64 encoding it. Optionally, it will also
|
48
48
|
# url encode the result of that to protect the string if it's going to
|
@@ -52,20 +52,20 @@ module EC2
|
|
52
52
|
b64_hmac =
|
53
53
|
Base64.encode64(
|
54
54
|
OpenSSL::HMAC.digest(digest, secret_access_key, str)).strip
|
55
|
-
|
55
|
+
|
56
56
|
if urlencode
|
57
57
|
return CGI::escape(b64_hmac)
|
58
58
|
else
|
59
59
|
return b64_hmac
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
63
|
-
|
62
|
+
|
63
|
+
|
64
64
|
#Introduction:
|
65
65
|
#
|
66
66
|
# The library exposes one main interface class, 'EC2::Base'.
|
67
|
-
# This class provides all the methods for using the EC2 service
|
68
|
-
# including the handling of header signing and other security issues .
|
67
|
+
# This class provides all the methods for using the EC2 service
|
68
|
+
# including the handling of header signing and other security issues .
|
69
69
|
# This class uses Net::HTTP to interface with the EC2 Query API interface.
|
70
70
|
#
|
71
71
|
#Required Arguments:
|
@@ -79,27 +79,27 @@ module EC2
|
|
79
79
|
# :server => String (default : 'ec2.amazonaws.com')
|
80
80
|
#
|
81
81
|
class Base
|
82
|
-
|
82
|
+
|
83
83
|
attr_reader :use_ssl, :server, :port
|
84
|
-
|
84
|
+
|
85
85
|
def initialize( options = {} )
|
86
|
-
|
86
|
+
|
87
87
|
options = { :access_key_id => "",
|
88
88
|
:secret_access_key => "",
|
89
89
|
:use_ssl => true,
|
90
90
|
:server => DEFAULT_HOST
|
91
91
|
}.merge(options)
|
92
|
-
|
92
|
+
|
93
93
|
@server = options[:server]
|
94
94
|
@use_ssl = options[:use_ssl]
|
95
|
-
|
95
|
+
|
96
96
|
raise ArgumentError, "No :access_key_id provided" if options[:access_key_id].nil? || options[:access_key_id].empty?
|
97
97
|
raise ArgumentError, "No :secret_access_key provided" if options[:secret_access_key].nil? || options[:secret_access_key].empty?
|
98
98
|
raise ArgumentError, "No :use_ssl value provided" if options[:use_ssl].nil?
|
99
99
|
raise ArgumentError, "Invalid :use_ssl value provided, only 'true' or 'false' allowed" unless options[:use_ssl] == true || options[:use_ssl] == false
|
100
100
|
raise ArgumentError, "No :server provided" if options[:server].nil? || options[:server].empty?
|
101
|
-
|
102
|
-
|
101
|
+
|
102
|
+
|
103
103
|
# based on the :use_ssl boolean, determine which port we should connect to
|
104
104
|
case @use_ssl
|
105
105
|
when true
|
@@ -109,24 +109,24 @@ module EC2
|
|
109
109
|
# http
|
110
110
|
@port = 80
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
@access_key_id = options[:access_key_id]
|
114
114
|
@secret_access_key = options[:secret_access_key]
|
115
115
|
@http = Net::HTTP.new(options[:server], @port)
|
116
116
|
@http.use_ssl = @use_ssl
|
117
|
-
|
117
|
+
|
118
118
|
# Don't verify the SSL certificates. Avoids SSL Cert warning in log on every GET.
|
119
119
|
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
120
|
-
|
120
|
+
|
121
121
|
end
|
122
|
-
|
123
|
-
|
122
|
+
|
123
|
+
|
124
124
|
private
|
125
|
-
|
125
|
+
|
126
126
|
# pathlist is a utility method which takes a key string and and array as input.
|
127
127
|
# It converts the array into a Hash with the hash key being 'Key.n' where
|
128
|
-
# 'n' increments by 1 for each iteration. So if you pass in args
|
129
|
-
# ("ImageId", ["123", "456"]) you should get
|
128
|
+
# 'n' increments by 1 for each iteration. So if you pass in args
|
129
|
+
# ("ImageId", ["123", "456"]) you should get
|
130
130
|
# {"ImageId.1"=>"123", "ImageId.2"=>"456"} returned.
|
131
131
|
def pathlist(key, arr)
|
132
132
|
params = {}
|
@@ -135,81 +135,81 @@ module EC2
|
|
135
135
|
end
|
136
136
|
params
|
137
137
|
end
|
138
|
-
|
139
|
-
|
140
|
-
# Make the connection to AWS EC2 passing in our request. This is generally called from
|
138
|
+
|
139
|
+
|
140
|
+
# Make the connection to AWS EC2 passing in our request. This is generally called from
|
141
141
|
# within a 'Response' class object or one of its sub-classes so the response is interpreted
|
142
142
|
# in its proper context. See lib/EC2/responses.rb
|
143
143
|
def make_request(action, params, data='')
|
144
|
-
|
144
|
+
|
145
145
|
@http.start do
|
146
|
-
|
146
|
+
|
147
147
|
# remove any keys that have nil or empty values
|
148
148
|
params.reject! { |key, value| value.nil? or value.empty?}
|
149
|
-
|
149
|
+
|
150
150
|
params.merge!( {"Action" => action,
|
151
151
|
"SignatureVersion" => "1",
|
152
152
|
"AWSAccessKeyId" => @access_key_id,
|
153
153
|
"Version" => API_VERSION,
|
154
154
|
"Timestamp"=>Time.now.getutc.iso8601} )
|
155
|
-
|
155
|
+
|
156
156
|
sigpath = "?" + params.sort_by { |param| param[0].downcase }.collect { |param| param.join("=") }.join("&")
|
157
|
-
|
157
|
+
|
158
158
|
sig = get_aws_auth_param(sigpath, @secret_access_key)
|
159
|
-
|
159
|
+
|
160
160
|
path = "?" + params.sort.collect do |param|
|
161
161
|
CGI::escape(param[0]) + "=" + CGI::escape(param[1])
|
162
162
|
end.join("&") + "&Signature=" + sig
|
163
|
-
|
163
|
+
|
164
164
|
req = Net::HTTP::Get.new("/#{path}")
|
165
|
-
|
165
|
+
|
166
166
|
# Ruby will automatically add a random content-type on some verbs, so
|
167
167
|
# here we add a dummy one to 'supress' it. Change this logic if having
|
168
168
|
# an empty content-type header becomes semantically meaningful for any
|
169
169
|
# other verb.
|
170
170
|
req['Content-Type'] ||= ''
|
171
171
|
req['User-Agent'] = "rubyforge-amazon-ec2-ruby-gem-query-api v-#{RELEASE_VERSION}"
|
172
|
-
|
172
|
+
|
173
173
|
#data = nil unless req.request_body_permitted?
|
174
174
|
response = @http.request(req, nil)
|
175
|
-
|
175
|
+
|
176
176
|
# Make a call to see if we need to throw an error based on the response given by EC2
|
177
177
|
# All error classes are defined in EC2/exceptions.rb
|
178
178
|
ec2_error?(response)
|
179
|
-
|
179
|
+
|
180
180
|
return response
|
181
|
-
|
181
|
+
|
182
182
|
end
|
183
|
-
|
183
|
+
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
# Set the Authorization header using AWS signed header authentication
|
187
187
|
def get_aws_auth_param(path, secret_access_key)
|
188
188
|
canonical_string = EC2.canonical_string(path)
|
189
189
|
encoded_canonical = EC2.encode(secret_access_key, canonical_string)
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
# allow us to have a one line call in each method which will do all of the work
|
193
193
|
# in making the actual request to AWS.
|
194
194
|
def response_generator( options = {} )
|
195
|
-
|
195
|
+
|
196
196
|
options = {
|
197
197
|
:action => "",
|
198
198
|
:params => {}
|
199
199
|
}.merge(options)
|
200
|
-
|
200
|
+
|
201
201
|
raise ArgumentError, ":action must be provided to response_generator" if options[:action].nil? || options[:action].empty?
|
202
|
-
|
202
|
+
|
203
203
|
http_response = make_request(options[:action], options[:params])
|
204
204
|
http_xml = http_response.body
|
205
205
|
return Response.parse(:xml => http_xml)
|
206
|
-
|
206
|
+
|
207
207
|
end
|
208
|
-
|
208
|
+
|
209
209
|
# Raises the appropriate error if the specified Net::HTTPResponse object
|
210
210
|
# contains an Amazon EC2 error; returns +false+ otherwise.
|
211
211
|
def ec2_error?(response)
|
212
|
-
|
212
|
+
|
213
213
|
# return false if we got a HTTP 200 code,
|
214
214
|
# otherwise there is some type of error (40x,50x) and
|
215
215
|
# we should try to raise an appropriate exception
|
@@ -219,13 +219,13 @@ module EC2
|
|
219
219
|
|
220
220
|
# parse the XML document so we can walk through it
|
221
221
|
doc = REXML::Document.new(response.body)
|
222
|
-
|
222
|
+
|
223
223
|
# Check that the Error element is in the place we would expect.
|
224
224
|
# and if not raise a generic error exception
|
225
225
|
unless doc.root.elements['Errors'].elements['Error'].name == 'Error'
|
226
226
|
raise Error, "Unexpected error format. response.body is: #{response.body}"
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
# An valid error response looks like this:
|
230
230
|
# <?xml version="1.0"?><Response><Errors><Error><Code>InvalidParameterCombination</Code><Message>Unknown parameter: foo</Message></Error></Errors><RequestID>291cef62-3e86-414b-900e-17246eccfae8</RequestID></Response>
|
231
231
|
# AWS EC2 throws some exception codes that look like Error.SubError. Since we can't name classes this way
|
@@ -233,7 +233,7 @@ module EC2
|
|
233
233
|
# non '.' name as well.
|
234
234
|
error_code = doc.root.elements['Errors'].elements['Error'].elements['Code'].text.gsub('.', '')
|
235
235
|
error_message = doc.root.elements['Errors'].elements['Error'].elements['Message'].text
|
236
|
-
|
236
|
+
|
237
237
|
# Raise one of our specific error classes if it exists.
|
238
238
|
# otherwise, throw a generic EC2 Error with a few details.
|
239
239
|
if EC2.const_defined?(error_code)
|
@@ -241,9 +241,9 @@ module EC2
|
|
241
241
|
else
|
242
242
|
raise Error, "This is an undefined error code which needs to be added to exceptions.rb : error_code => #{error_code} : error_message => #{error_message}"
|
243
243
|
end
|
244
|
-
|
244
|
+
|
245
245
|
end
|
246
|
-
|
246
|
+
|
247
247
|
end
|
248
|
-
|
248
|
+
|
249
249
|
end
|
data/lib/EC2/console.rb
CHANGED
@@ -9,15 +9,15 @@
|
|
9
9
|
#++
|
10
10
|
|
11
11
|
module EC2
|
12
|
-
|
12
|
+
|
13
13
|
class Base
|
14
|
-
|
14
|
+
|
15
15
|
#Amazon Developer Guide Docs:
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# The GetConsoleOutput operation retrieves console output that has been posted for the specified instance.
|
18
18
|
#
|
19
|
-
# Instance console output is buffered and posted shortly after instance boot, reboot and once the instance
|
20
|
-
# is terminated. Only the most recent 64 KB of posted output is available. Console output is available for
|
19
|
+
# Instance console output is buffered and posted shortly after instance boot, reboot and once the instance
|
20
|
+
# is terminated. Only the most recent 64 KB of posted output is available. Console output is available for
|
21
21
|
# at least 1 hour after the most recent post.
|
22
22
|
#
|
23
23
|
#Required Arguments:
|
@@ -29,16 +29,16 @@ module EC2
|
|
29
29
|
# none
|
30
30
|
#
|
31
31
|
def get_console_output( options ={} )
|
32
|
-
|
32
|
+
|
33
33
|
options = {:instance_id => ""}.merge(options)
|
34
|
-
|
34
|
+
|
35
35
|
raise ArgumentError, "No instance ID provided" if options[:instance_id].nil? || options[:instance_id].empty?
|
36
|
-
|
36
|
+
|
37
37
|
params = { "InstanceId" => options[:instance_id] }
|
38
|
-
|
38
|
+
|
39
39
|
return response_generator(:action => "GetConsoleOutput", :params => params)
|
40
|
-
|
40
|
+
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
end
|
data/lib/EC2/exceptions.rb
CHANGED
@@ -9,128 +9,128 @@
|
|
9
9
|
#++
|
10
10
|
|
11
11
|
module EC2
|
12
|
-
|
12
|
+
|
13
13
|
# OUR CUSTOM ERROR CODES
|
14
|
-
|
14
|
+
|
15
15
|
# All of our errors are superclassed by Error < RuntimeError
|
16
16
|
class Error < RuntimeError #:nodoc:
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# A client side only argument error
|
20
20
|
class ArgumentError < Error #:nodoc:
|
21
21
|
end
|
22
|
-
|
23
|
-
|
22
|
+
|
23
|
+
|
24
24
|
# AWS EC2 CLIENT ERROR CODES
|
25
|
-
|
25
|
+
|
26
26
|
# AWS EC2 can throw error exceptions that contain a '.' in them.
|
27
27
|
# since we can't name an exception class with that '.' I compressed
|
28
28
|
# each class name into the non-dot version. This allows us to retain
|
29
29
|
# the granularity of the exception.
|
30
|
-
|
30
|
+
|
31
31
|
# User not authorized.
|
32
32
|
class AuthFailure < Error #:nodoc:
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
# Specified AMI has an unparsable manifest.
|
36
36
|
class InvalidManifest < Error #:nodoc:
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# Specified AMI ID is not valid.
|
40
40
|
class InvalidAMIIDMalformed < Error #:nodoc:
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
# Specified AMI ID does not exist.
|
44
44
|
class InvalidAMIIDNotFound < Error #:nodoc:
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
# Specified AMI ID has been deregistered and is no longer available.
|
48
48
|
class InvalidAMIIDUnavailable < Error #:nodoc:
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
# Specified instance ID is not valid.
|
52
52
|
class InvalidInstanceIDMalformed < Error #:nodoc:
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
# Specified instance ID does not exist.
|
56
56
|
class InvalidInstanceIDNotFound < Error #:nodoc:
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# Specified keypair name does not exist.
|
60
60
|
class InvalidKeyPairNotFound < Error #:nodoc:
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
# Attempt to create a duplicate keypair.
|
64
64
|
class InvalidKeyPairDuplicate < Error #:nodoc:
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# Specified group name does not exist.
|
68
68
|
class InvalidGroupNotFound < Error #:nodoc:
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
# Attempt to create a duplicate group.
|
72
72
|
class InvalidGroupDuplicate < Error #:nodoc:
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
# Specified group can not be deleted because it is in use.
|
76
76
|
class InvalidGroupInUse < Error #:nodoc:
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
# Specified group name is a reserved name.
|
80
80
|
class InvalidGroupReserved < Error #:nodoc:
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
# Attempt to authorize a permission that has already been authorized.
|
84
84
|
class InvalidPermissionDuplicate < Error #:nodoc:
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
# Specified permission is invalid.
|
88
88
|
class InvalidPermissionMalformed < Error #:nodoc:
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
# Specified reservation ID is invalid.
|
92
92
|
class InvalidReservationIDMalformed < Error #:nodoc:
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
# Specified reservation ID does not exist.
|
96
96
|
class InvalidReservationIDNotFound < Error #:nodoc:
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
# User has reached max allowed concurrent running instances.
|
100
100
|
class InstanceLimitExceeded < Error #:nodoc:
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
# An invalid set of parameters were passed as arguments
|
104
104
|
# e.g. RunInstances was called with minCount and maxCount set to 0 or minCount > maxCount.
|
105
105
|
class InvalidParameterCombination < Error #:nodoc:
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
# An unknown parameter was passed as an argument
|
109
109
|
class UnknownParameter < Error #:nodoc:
|
110
110
|
end
|
111
|
-
|
112
|
-
# The user ID is neither in the form of an AWS account ID or one
|
113
|
-
# of the special values accepted by the owner or executableBy flags
|
111
|
+
|
112
|
+
# The user ID is neither in the form of an AWS account ID or one
|
113
|
+
# of the special values accepted by the owner or executableBy flags
|
114
114
|
# in the DescribeImages call.
|
115
115
|
class InvalidUserIDMalformed < Error #:nodoc:
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
# The value of an item added to, or removed from, an image attribute is invalid.
|
119
119
|
class InvalidAMIAttributeItemValue < Error #:nodoc:
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
# AWS EC2 SERVER ERROR CODES
|
123
|
-
|
123
|
+
|
124
124
|
# Internal AWS EC2 Error.
|
125
125
|
class InternalError < Error #:nodoc:
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
# There are not enough available instances to satify your minimum request.
|
129
129
|
class InsufficientInstanceCapacity < Error #:nodoc:
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
# The server is overloaded and cannot handle request.
|
133
133
|
class Unavailable < Error #:nodoc:
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
end
|