amazon-ec2 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -37,8 +37,6 @@ test/test_EC2_responses.rb
37
37
  test/test_EC2_security_groups.rb
38
38
  test/test_EC2_version.rb
39
39
  test/test_helper.rb
40
- website/announce.html
41
- website/announce.txt
42
40
  website/index.html
43
41
  website/index.txt
44
42
  website/javascripts/rounded_corners_lite.inc.js
data/README.txt CHANGED
@@ -137,7 +137,7 @@ Try out the following bit of code. This should walk through each image returned
137
137
 
138
138
  === Related Projects
139
139
 
140
- * Capazon : http://capazon.rubyforge.org
140
+ * Capsize : http://capsize.rubyforge.org
141
141
 
142
142
  == Credits
143
143
 
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-03-01'
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
@@ -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
@@ -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