kunley-amazon-ec2 0.3.4 → 0.3.8

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 CHANGED
@@ -1,3 +1,17 @@
1
+ === 0.3.8 2009-04-16
2
+ * Applied patch, fixing an issue with EU Signature version 2 creation (delano).
3
+
4
+ === 0.3.7 2009-03-09
5
+ * Applied patch, with updated tests to fix issue with base64 encoded user data (rsanheim).
6
+
7
+ === 0.3.6 2009-03-02
8
+ * You can now specify any arbitrary SSL tcp port to connect to (kerryb)
9
+ * Added rake target to quickly install the gem without docs
10
+
11
+ === 0.3.5 2009-02-26
12
+ * Honor the EC2_URL env var if provided in the main lib
13
+ * Some minor modifications to the exceptions raised when unknown
14
+
1
15
  === 0.3.4 2009-01-31
2
16
  * Added support in the helper binaries for EC2_URL server url for Euro servers
3
17
  * AWS Signature v2 support
data/Rakefile CHANGED
@@ -16,6 +16,11 @@ task :install => [:package] do
16
16
  sh %{sudo gem install pkg/#{GEM}-#{VER}}
17
17
  end
18
18
 
19
+ desc "Package and then install the gem locally omitting documentation"
20
+ task :install_nodoc => [:package] do
21
+ sh %{sudo gem install --no-ri --no-rdoc pkg/#{GEM}-#{VER}}
22
+ end
23
+
19
24
  Rake::TestTask.new do |t|
20
25
  t.libs << "test"
21
26
  t.test_files = FileList['test/test*.rb']
@@ -28,3 +33,5 @@ Rake::RDocTask.new do |rd|
28
33
  rd.rdoc_dir = 'doc'
29
34
  rd.options = spec.rdoc_options
30
35
  end
36
+
37
+ task :default => :test
@@ -30,7 +30,16 @@ if ACCESS_KEY_ID.nil? || ACCESS_KEY_ID.empty?
30
30
  exit
31
31
  end
32
32
 
33
- ec2 = EC2::Base.new( :access_key_id => ACCESS_KEY_ID, :secret_access_key => SECRET_ACCESS_KEY )
33
+ # us-east-1.ec2.amazonaws.com == ec2.amazonaws.com
34
+ # eu-west-1.ec2.amazonaws.com for the european region
35
+ # test different servers by running something like:
36
+ # export EC2_URL='https://ec2.amazonaws.com';./bin/ec2-gem-example.rb
37
+ if ENV['EC2_URL']
38
+ ec2 = EC2::Base.new( :access_key_id => ACCESS_KEY_ID, :secret_access_key => SECRET_ACCESS_KEY, :server => URI.parse(ENV['EC2_URL']).host )
39
+ else
40
+ # default server is US ec2.amazonaws.com
41
+ ec2 = EC2::Base.new( :access_key_id => ACCESS_KEY_ID, :secret_access_key => SECRET_ACCESS_KEY )
42
+ end
34
43
 
35
44
  puts "----- ec2.methods.sort -----"
36
45
  p ec2.methods.sort
@@ -20,7 +20,6 @@ if ENV['AMAZON_ACCESS_KEY_ID'] && ENV['AMAZON_SECRET_ACCESS_KEY']
20
20
  @ec2 = EC2::Base.new(opts)
21
21
  end
22
22
 
23
- puts "Current Options:"
24
- pp opts
23
+ puts "EC2 Server: #{opts[:server]}"
25
24
 
26
25
  include EC2
data/lib/EC2.rb CHANGED
@@ -19,7 +19,19 @@ Dir[File.join(File.dirname(__FILE__), 'EC2/**/*.rb')].sort.each { |lib| require
19
19
  module EC2
20
20
 
21
21
  # Which host FQDN will we connect to for all API calls to AWS?
22
- DEFAULT_HOST = 'ec2.amazonaws.com'
22
+ # If EC2_URL is defined in the users ENV we can use that. It is
23
+ # expected that this var is set with something like:
24
+ # export EC2_URL='https://ec2.amazonaws.com'
25
+ #
26
+ if ENV['EC2_URL']
27
+ EC2_URL = ENV['EC2_URL']
28
+ VALID_HOSTS = ['https://ec2.amazonaws.com', 'https://us-east-1.ec2.amazonaws.com', 'https://eu-west-1.ec2.amazonaws.com']
29
+ raise ArgumentError, "Invalid EC2_URL environment variable : #{EC2_URL}" unless VALID_HOSTS.include?(EC2_URL)
30
+ DEFAULT_HOST = URI.parse(EC2_URL).host
31
+ else
32
+ # default US host
33
+ DEFAULT_HOST = 'ec2.amazonaws.com'
34
+ end
23
35
 
24
36
  # This is the version of the API as defined by Amazon Web Services
25
37
  API_VERSION = '2008-12-01'
@@ -32,7 +44,7 @@ module EC2
32
44
  # Sort, and encode parameters into a canonical string.
33
45
  sorted_params = params.sort {|x,y| x[0] <=> y[0]}
34
46
  encoded_params = sorted_params.collect do |p|
35
- encoded = (CGI::escape(p[0].to_s) +
47
+ encoded = (CGI::escape(p[0].to_s) +
36
48
  "=" + CGI::escape(p[1].to_s))
37
49
  # Ensure spaces are encoded as '%20', not '+'
38
50
  encoded.gsub('+', '%20')
@@ -40,10 +52,10 @@ module EC2
40
52
  sigquery = encoded_params.join("&")
41
53
 
42
54
  # Generate the request description string
43
- req_desc =
44
- method + "\n" +
45
- host + "\n" +
46
- base + "\n" +
55
+ req_desc =
56
+ method + "\n" +
57
+ host + "\n" +
58
+ base + "\n" +
47
59
  sigquery
48
60
 
49
61
  end
@@ -106,14 +118,14 @@ module EC2
106
118
  raise ArgumentError, "No :use_ssl value provided" if options[:use_ssl].nil?
107
119
  raise ArgumentError, "Invalid :use_ssl value provided, only 'true' or 'false' allowed" unless options[:use_ssl] == true || options[:use_ssl] == false
108
120
  raise ArgumentError, "No :server provided" if options[:server].nil? || options[:server].empty?
109
-
110
-
111
- # based on the :use_ssl boolean, determine which port we should connect to
112
- case @use_ssl
113
- when true
121
+
122
+ if options[:port]
123
+ # user-specified port
124
+ @port = options[:port]
125
+ elsif @use_ssl
114
126
  # https
115
127
  @port = 443
116
- when false
128
+ else
117
129
  # http
118
130
  @port = 80
119
131
  end
@@ -170,7 +182,7 @@ module EC2
170
182
  "Version" => API_VERSION,
171
183
  "Timestamp"=>Time.now.getutc.iso8601} )
172
184
 
173
- sig = get_aws_auth_param(params, @secret_access_key)
185
+ sig = get_aws_auth_param(params, @secret_access_key, @server)
174
186
 
175
187
  query = params.sort.collect do |param|
176
188
  CGI::escape(param[0]) + "=" + CGI::escape(param[1])
@@ -193,8 +205,8 @@ module EC2
193
205
  end
194
206
 
195
207
  # Set the Authorization header using AWS signed header authentication
196
- def get_aws_auth_param(params, secret_access_key)
197
- canonical_string = EC2.canonical_string(params)
208
+ def get_aws_auth_param(params, secret_access_key, server)
209
+ canonical_string = EC2.canonical_string(params, server)
198
210
  encoded_canonical = EC2.encode(secret_access_key, canonical_string)
199
211
  end
200
212
 
@@ -248,7 +260,7 @@ module EC2
248
260
  if EC2.const_defined?(error_code)
249
261
  raise EC2.const_get(error_code), error_message
250
262
  else
251
- raise Error, "This is an undefined error code which needs to be added to exceptions.rb : error_code => #{error_code} : error_message => #{error_message}"
263
+ raise EC2::Error, error_message
252
264
  end
253
265
 
254
266
  end
@@ -32,6 +32,14 @@ module EC2
32
32
  class AuthFailure < Error #:nodoc:
33
33
  end
34
34
 
35
+ # Invalid AWS Account
36
+ class InvalidClientTokenId < Error #:nodoc:
37
+ end
38
+
39
+ # Invalid Parameters for Value
40
+ class InvalidParameterValue < Error #:nodoc:
41
+ end
42
+
35
43
  # Specified AMI has an unparsable manifest.
36
44
  class InvalidManifest < Error #:nodoc:
37
45
  end
@@ -133,4 +141,7 @@ module EC2
133
141
  class Unavailable < Error #:nodoc:
134
142
  end
135
143
 
144
+ class SignatureDoesNotMatch < Error #:nodoc:
145
+ end
146
+
136
147
  end
@@ -90,18 +90,7 @@ module EC2
90
90
  raise ArgumentError, ":instance_type must be 'm1.small', 'm1.large', 'm1.xlarge', 'c1.medium', or 'c1.xlarge'" unless options[:instance_type] == "m1.small" || options[:instance_type] == "m1.large" || options[:instance_type] == "m1.xlarge" || options[:instance_type] == "c1.medium" || options[:instance_type] == "c1.xlarge"
91
91
  raise ArgumentError, ":base64_encoded must be 'true' or 'false'" unless options[:base64_encoded] == true || options[:base64_encoded] == false
92
92
 
93
- # If :user_data is passed in then URL escape and Base64 encode it
94
- # as needed. Need for URL Escape + Base64 encoding is determined
95
- # by :base64_encoded param.
96
- if options[:user_data]
97
- if options[:base64_encoded]
98
- user_data = options[:user_data]
99
- else
100
- user_data = Base64.encode64(options[:user_data]).gsub(/\n/,"").strip()
101
- end
102
- else
103
- user_data = nil
104
- end
93
+ user_data = extract_user_data(options)
105
94
 
106
95
  params = {
107
96
  "ImageId" => options[:image_id],
@@ -119,6 +108,20 @@ module EC2
119
108
  return response_generator(:action => "RunInstances", :params => params)
120
109
 
121
110
  end
111
+
112
+ # If :user_data is passed in then URL escape and Base64 encode it
113
+ # as needed. Need for URL Escape + Base64 encoding is determined
114
+ # by :base64_encoded param.
115
+ def extract_user_data(options)
116
+ return unless options[:user_data]
117
+ if options[:user_data]
118
+ if options[:base64_encoded]
119
+ Base64.encode64(options[:user_data]).gsub(/\n/,"").strip()
120
+ else
121
+ options[:user_data]
122
+ end
123
+ end
124
+ end
122
125
 
123
126
 
124
127
  #Amazon Developer Guide Docs:
@@ -17,31 +17,47 @@ context "The EC2 method " do
17
17
 
18
18
  specify "EC2::Base attribute readers should be available" do
19
19
  @ec2 = EC2::Base.new( :access_key_id => "not a key",
20
- :secret_access_key => "not a secret",
21
- :use_ssl => true,
22
- :server => "foo.example.com" )
20
+ :secret_access_key => "not a secret",
21
+ :use_ssl => true,
22
+ :server => "foo.example.com" )
23
23
 
24
24
  @ec2.use_ssl.should.equal true
25
25
  @ec2.port.should.equal 443
26
26
  @ec2.server.should.equal "foo.example.com"
27
27
  end
28
28
 
29
-
30
29
  specify "EC2::Base should work with insecure connections as well" do
31
30
  @ec2 = EC2::Base.new( :access_key_id => "not a key",
32
- :secret_access_key => "not a secret",
33
- :use_ssl => false,
34
- :server => "foo.example.com" )
31
+ :secret_access_key => "not a secret",
32
+ :use_ssl => false,
33
+ :server => "foo.example.com" )
35
34
 
36
35
  @ec2.use_ssl.should.equal false
37
36
  @ec2.port.should.equal 80
38
37
  @ec2.server.should.equal "foo.example.com"
39
38
  end
40
39
 
40
+ specify "EC2::Base should allow specification of port" do
41
+ @ec2 = EC2::Base.new( :access_key_id => "not a key",
42
+ :secret_access_key => "not a secret",
43
+ :use_ssl => true,
44
+ :server => "foo.example.com",
45
+ :port => 8443 )
46
+
47
+ @ec2.use_ssl.should.equal true
48
+ @ec2.port.should.equal 8443
49
+ @ec2.server.should.equal "foo.example.com"
50
+ end
41
51
 
42
52
  specify "EC2.canonical_string(path) should conform to Amazon's requirements " do
43
53
  path = {"name1" => "value1", "name2" => "value2", "name3" => "value3"}
44
- EC2.canonical_string(path).should.equal "POST\nec2.amazonaws.com\n/\nname1=value1&name2=value2&name3=value3"
54
+ if ENV['EC2_URL'].nil? || ENV['EC2_URL'] == 'https://ec2.amazonaws.com'
55
+ EC2.canonical_string(path).should.equal "POST\nec2.amazonaws.com\n/\nname1=value1&name2=value2&name3=value3"
56
+ elsif ENV['EC2_URL'] == 'https://us-east-1.ec2.amazonaws.com'
57
+ EC2.canonical_string(path).should.equal "POST\nus-east-1.ec2.amazonaws.com\n/\nname1=value1&name2=value2&name3=value3"
58
+ elsif ENV['EC2_URL'] == 'https://eu-west-1.ec2.amazonaws.com'
59
+ EC2.canonical_string(path).should.equal "POST\neu-west-1.ec2.amazonaws.com\n/\nname1=value1&name2=value2&name3=value3"
60
+ end
45
61
  end
46
62
 
47
63
  specify "EC2.encode should return the expected string" do
@@ -221,28 +221,40 @@ context "EC2 instances " do
221
221
 
222
222
 
223
223
  specify "should be able specify an availability_zone" do
224
- @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "Placement.AvailabilityZone" => "zone123", "UserData" => "foo", "AddressingType" => 'public', 'InstanceType' => 'm1.small').
224
+ @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "Placement.AvailabilityZone" => "zone123", "UserData" => "Zm9v", "AddressingType" => 'public', 'InstanceType' => 'm1.small').
225
225
  returns stub(:body => @run_instances_response_body, :is_a? => true)
226
226
  @ec2.run_instances( :image_id => "ami-60a54009", :min_count => 1, :max_count => 1, :availability_zone => "zone123", :group_id => [], :user_data => "foo", :base64_encoded => true ).should.be.an.instance_of Hash
227
227
  end
228
228
 
229
229
  specify "should be able to call run_instances with :user_data and :base64_encoded => true (default is false)" do
230
- @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "UserData" => "foo", "AddressingType" => 'public', 'InstanceType' => 'm1.small').
230
+ @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "UserData" => "Zm9v", "AddressingType" => 'public', 'InstanceType' => 'm1.small').
231
231
  returns stub(:body => @run_instances_response_body, :is_a? => true)
232
232
  @ec2.run_instances( :image_id => "ami-60a54009", :min_count => 1, :max_count => 1, :group_id => [], :user_data => "foo", :base64_encoded => true ).should.be.an.instance_of Hash
233
233
  end
234
234
 
235
235
  specify "should be able specify an kernel_id" do
236
- @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "Placement.AvailabilityZone" => "zone123", "UserData" => "foo", "AddressingType" => 'public', 'InstanceType' => 'm1.small', 'KernelId' => 'kernfoo').
236
+ @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "Placement.AvailabilityZone" => "zone123", "UserData" => "Zm9v", "AddressingType" => 'public', 'InstanceType' => 'm1.small', 'KernelId' => 'kernfoo').
237
237
  returns stub(:body => @run_instances_response_body, :is_a? => true)
238
238
  @ec2.run_instances( :image_id => "ami-60a54009", :min_count => 1, :max_count => 1, :availability_zone => "zone123", :group_id => [], :user_data => "foo", :base64_encoded => true, :kernel_id => 'kernfoo' ).should.be.an.instance_of Hash
239
239
  end
240
240
 
241
241
  specify "should be able to call run_instances with :user_data and :base64_encoded => false" do
242
- @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "UserData" => "Zm9v", "AddressingType" => 'public', 'InstanceType' => 'm1.small').
242
+ @ec2.stubs(:make_request).with('RunInstances', "ImageId" => "ami-60a54009", "MinCount" => '1', "MaxCount" => '1', "UserData" => "foo", "AddressingType" => 'public', 'InstanceType' => 'm1.small').
243
243
  returns stub(:body => @run_instances_response_body, :is_a? => true)
244
244
  @ec2.run_instances( :image_id => "ami-60a54009", :min_count => 1, :max_count => 1, :group_id => [], :user_data => "foo", :base64_encoded => false ).should.be.an.instance_of Hash
245
245
  end
246
+
247
+ specify "should get no user data for when options has no user_data key" do
248
+ @ec2.extract_user_data({}).should == nil
249
+ end
250
+
251
+ specify "should get plain string user data when options has user_data and no base64 key" do
252
+ @ec2.extract_user_data({:user_data => "foo\nbar"}).should == "foo\nbar"
253
+ end
254
+
255
+ specify "should strip new lines and base64 encode when options has both user_data and base64" do
256
+ @ec2.extract_user_data({:user_data => "binary\ndata\nhere\n", :base64_encoded => true}).should == "YmluYXJ5CmRhdGEKaGVyZQo="
257
+ end
246
258
 
247
259
 
248
260
  specify "should be able to be described and return the correct Ruby response class" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kunley-amazon-ec2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Glenn Rempe
@@ -9,11 +9,12 @@ autorequire: EC2
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-11 00:00:00 -08:00
12
+ date: 2009-04-08 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: xml-simple
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
@@ -22,7 +23,7 @@ dependencies:
22
23
  version: 1.0.11
23
24
  version:
24
25
  description: An interface library that allows Ruby applications to easily connect to the HTTP 'Query API' for the Amazon Web Services Elastic Compute Cloud (EC2) and manipulate cloud servers.
25
- email: glenn.rempe@gmail.com
26
+ email: glenn@rempe.us
26
27
  executables:
27
28
  - ec2-gem-example.rb
28
29
  - ec2sh