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.
@@ -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