aws-sdk 1.5.2 → 1.5.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.
Files changed (41) hide show
  1. data/lib/aws/api_config/AutoScaling-2011-01-01.yml +6 -2
  2. data/lib/aws/api_config/{EC2-2012-04-01.yml → EC2-2012-06-01.yml} +12 -0
  3. data/lib/aws/api_config/STS-2011-06-15.yml +0 -4
  4. data/lib/aws/auto_scaling/client.rb +6 -2
  5. data/lib/aws/auto_scaling/launch_configuration.rb +8 -0
  6. data/lib/aws/auto_scaling/launch_configuration_collection.rb +14 -4
  7. data/lib/aws/auto_scaling/scaling_policy.rb +17 -0
  8. data/lib/aws/auto_scaling/scaling_policy_options.rb +2 -0
  9. data/lib/aws/core.rb +13 -11
  10. data/lib/aws/core/cacheable.rb +1 -1
  11. data/lib/aws/core/client.rb +40 -39
  12. data/lib/aws/core/configuration.rb +24 -15
  13. data/lib/aws/core/credential_providers.rb +395 -0
  14. data/lib/aws/core/http/net_http_handler.rb +1 -0
  15. data/lib/aws/core/http/request.rb +4 -4
  16. data/lib/aws/core/log_formatter.rb +2 -0
  17. data/lib/aws/core/signature/version_2.rb +18 -5
  18. data/lib/aws/core/signature/version_3.rb +10 -10
  19. data/lib/aws/core/signature/version_4.rb +13 -13
  20. data/lib/aws/core/signer.rb +46 -0
  21. data/lib/aws/dynamo_db/batch_write.rb +2 -1
  22. data/lib/aws/dynamo_db/client.rb +9 -24
  23. data/lib/aws/dynamo_db/table.rb +0 -23
  24. data/lib/aws/ec2/client.rb +19 -1
  25. data/lib/aws/ec2/image.rb +4 -4
  26. data/lib/aws/ec2/instance.rb +17 -5
  27. data/lib/aws/ec2/instance_collection.rb +16 -1
  28. data/lib/aws/errors.rb +40 -0
  29. data/lib/aws/s3/client.rb +2 -1
  30. data/lib/aws/s3/presigned_post.rb +10 -8
  31. data/lib/aws/s3/request.rb +7 -5
  32. data/lib/aws/s3/s3_object.rb +10 -9
  33. data/lib/aws/simple_email_service.rb +1 -1
  34. data/lib/aws/simple_email_service/identity_collection.rb +1 -1
  35. data/lib/aws/sts.rb +2 -6
  36. data/lib/aws/sts/client.rb +14 -17
  37. metadata +7 -9
  38. data/lib/aws/api_config/EC2-2011-12-15.yml +0 -3638
  39. data/lib/aws/core/default_signer.rb +0 -67
  40. data/lib/aws/core/session_signer.rb +0 -90
  41. data/lib/aws/core/signature/version_3_http.rb +0 -72
@@ -19,37 +19,37 @@ module AWS
19
19
  module Signature
20
20
  module Version3
21
21
 
22
- def add_authorization!(signer)
22
+ def self.included base
23
+ base.send(:include, Signer)
24
+ end
23
25
 
24
- self.access_key_id = signer.access_key_id
26
+ def add_authorization! credentials
25
27
 
26
28
  headers["x-amz-date"] ||= (headers["date"] ||= Time.now.rfc822)
27
29
  headers["host"] ||= host
28
30
 
29
- headers["x-amz-security-token"] = signer.session_token if
30
- signer.respond_to?(:session_token) and signer.session_token
31
+ headers["x-amz-security-token"] = credentials.session_token if
32
+ credentials.session_token
31
33
 
32
34
  # compute the authorization
33
- request_hash = OpenSSL::Digest::SHA256.digest(string_to_sign)
34
- signature = signer.sign(request_hash)
35
35
  headers["x-amzn-authorization"] =
36
36
  "AWS3 "+
37
- "AWSAccessKeyId=#{signer.access_key_id},"+
37
+ "AWSAccessKeyId=#{credentials.access_key_id},"+
38
38
  "Algorithm=HmacSHA256,"+
39
39
  "SignedHeaders=#{headers_to_sign.join(';')},"+
40
- "Signature=#{signature}"
40
+ "Signature=#{sign(credentials.secret_access_key, string_to_sign)}"
41
41
  end
42
42
 
43
43
  protected
44
44
 
45
45
  def string_to_sign
46
- [
46
+ OpenSSL::Digest::SHA256.digest([
47
47
  http_method,
48
48
  "/",
49
49
  "",
50
50
  canonical_headers,
51
51
  body
52
- ].join("\n")
52
+ ].join("\n"))
53
53
  end
54
54
 
55
55
  def canonical_headers
@@ -20,28 +20,32 @@ module AWS
20
20
  module Signature
21
21
  module Version4
22
22
 
23
- def add_authorization! signer
24
- self.access_key_id = signer.access_key_id
23
+ def self.included base
24
+ base.send(:include, Signer)
25
+ end
26
+
27
+ def add_authorization! credentials
25
28
  datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
26
29
  headers['content-type'] ||= 'application/x-www-form-urlencoded'
27
30
  headers['host'] = host
28
31
  headers['x-amz-date'] = datetime
29
- headers['x-amz-security-token'] = signer.session_token if signer.session_token
30
- headers['authorization'] = authorization(signer, datetime)
32
+ headers['x-amz-security-token'] = credentials.session_token if
33
+ credentials.session_token
34
+ headers['authorization'] = authorization(credentials, datetime)
31
35
  end
32
36
 
33
37
  protected
34
38
 
35
- def authorization signer, datetime
39
+ def authorization credentials, datetime
36
40
  parts = []
37
- parts << "AWS4-HMAC-SHA256 Credential=#{access_key_id}/#{credential_string(datetime)}"
41
+ parts << "AWS4-HMAC-SHA256 Credential=#{credentials.access_key_id}/#{credential_string(datetime)}"
38
42
  parts << "SignedHeaders=#{signed_headers}"
39
- parts << "Signature=#{hex16(signature(signer, datetime))}"
43
+ parts << "Signature=#{hex16(signature(credentials, datetime))}"
40
44
  parts.join(', ')
41
45
  end
42
46
 
43
- def signature signer, datetime
44
- k_secret = signer.secret_access_key
47
+ def signature credentials, datetime
48
+ k_secret = credentials.secret_access_key
45
49
  k_date = hmac("AWS4" + k_secret, datetime[0,8])
46
50
  k_region = hmac(k_date, region)
47
51
  k_service = hmac(k_region, service)
@@ -124,10 +128,6 @@ module AWS
124
128
  string.unpack('H*').first
125
129
  end
126
130
 
127
- def hmac key, string
128
- OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, string)
129
- end
130
-
131
131
  def hash string
132
132
  Digest::SHA256.digest(string)
133
133
  end
@@ -0,0 +1,46 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'base64'
15
+
16
+ module AWS
17
+ module Core
18
+
19
+ # This module provides a {#sign} method that accepts a secret
20
+ # and a string to sign.
21
+ module Signer
22
+
23
+ # Signs a string using the credentials stored in memory.
24
+ # @param [String] secret Usually an AWS secret access key.
25
+ # @param [String] string_to_sign The string to sign.
26
+ # @param [String] digest_method The digest method to use when
27
+ # computing the HMAC digest.
28
+ # @return [String] Returns the computed signature.
29
+ def sign secret, string_to_sign, digest_method = 'sha256'
30
+ Base64.encode64(hmac(secret, string_to_sign, digest_method)).strip
31
+ end
32
+ module_function :sign
33
+
34
+ # Computes an HMAC digest of the passed string.
35
+ # @param [String] key
36
+ # @param [String] value
37
+ # @param [String] digest ('sha256')
38
+ # @return [String]
39
+ def hmac key, value, digest = 'sha256'
40
+ OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new(digest), key, value)
41
+ end
42
+ module_function :hmac
43
+
44
+ end
45
+ end
46
+ end
@@ -235,7 +235,8 @@ module AWS
235
235
  end
236
236
 
237
237
  def str2sym key_desc
238
- type, value = key_desc.to_a.flatten
238
+ type = key_desc.keys.first
239
+ value = key_desc[type]
239
240
  case type
240
241
  when "S" then { :s => value }
241
242
  when "N" then { :n => value }
@@ -35,12 +35,13 @@ module AWS
35
35
 
36
36
  super
37
37
 
38
- # If the signer does not provide a session token, then we will
39
- # replace it with another signer that manages an AWS STS session.
40
- # This session will auto renew whenever it has expired and will
41
- # be shared across threads.
42
- if config.signer.session_token.nil?
43
- @signer = Core::SessionSigner.for(config)
38
+ # Replaces the current credential provider with a SessionProvider
39
+ # that provides refreshable STS session credentials. DynamoDB
40
+ # requires session credentials.
41
+ if credential_provider.session_token.nil?
42
+ long_term_credentials = credential_provider.credentials
43
+ @credential_provider = Core::CredentialProviders::SessionProvider.for(
44
+ long_term_credentials)
44
45
  end
45
46
 
46
47
  end
@@ -839,26 +840,17 @@ module AWS
839
840
  end
840
841
 
841
842
  def should_retry? response
842
- if possible_expired_credentials?(response)
843
- true
844
- elsif response.error.is_a?(Errors::ProvisionedThroughputExceededException)
843
+ if response.error.is_a?(Errors::ProvisionedThroughputExceededException)
845
844
  config.dynamo_db_retry_throughput_errors?
846
845
  else
847
846
  super
848
847
  end
849
848
  end
850
849
 
851
- def rebuild_http_request response
852
- # called when a request is going to be retried, in case of
853
- # expired credentials we should refresh the session
854
- signer.refresh_session if possible_expired_credentials?(response)
855
- super
856
- end
857
-
858
850
  def sleep_durations response
859
851
 
860
852
  retry_count =
861
- if possible_expired_credentials?(response)
853
+ if expired_credentials?(response)
862
854
  config.max_retries == 0 ? 0 : 1
863
855
  else
864
856
  config.max_retries { 10 }
@@ -876,13 +868,6 @@ module AWS
876
868
 
877
869
  end
878
870
 
879
- # Returns true if we get an access denied error from the service AND
880
- # our signer is capible of getting new short-term credentials
881
- def possible_expired_credentials? response
882
- signer.respond_to?(:refresh_session) and
883
- response.error.is_a?(Errors::ExpiredTokenException)
884
- end
885
-
886
871
  end
887
872
  end
888
873
  end
@@ -420,29 +420,6 @@ module AWS
420
420
  #
421
421
  # @return (see BatchWrite#process!)
422
422
  #
423
- def batch_put items
424
- batch = BatchWrite.new(:config => config)
425
- batch.put(self, options)
426
- batch.process!
427
- end
428
-
429
- # Batch delets up to 25 items.
430
- #
431
- # table.batch_delete(%w(id1 id2 id3 id4))
432
- #
433
- # @param [Array<String>,Array<Array>] items A list of item keys to
434
- # delete. For tables without a range key, items should be an array
435
- # of hash key strings.
436
- #
437
- # batch.delete('table-name', ['hk1', 'hk2', 'hk3'])
438
- #
439
- # For tables with a range key, items should be an array of
440
- # hash key and range key pairs.
441
- #
442
- # batch.delete('table-name', [['hk1', 'rk1'], ['hk1', 'rk2']])
443
- #
444
- # @return (see BatchWrite#process!)
445
- #
446
423
  def batch_put items
447
424
  batch = BatchWrite.new(:config => config)
448
425
  batch.put(self, items)
@@ -17,7 +17,7 @@ module AWS
17
17
  # Client class for Amazon Elastic Compute Cloud (EC2).
18
18
  class Client < Core::Client
19
19
 
20
- API_VERSION = '2012-04-01'
20
+ API_VERSION = '2012-06-01'
21
21
 
22
22
  extend Core::Client::QueryXML
23
23
 
@@ -1883,6 +1883,9 @@ module AWS
1883
1883
  # * +:association+ - (Hash)
1884
1884
  # * +:public_ip+ - (String)
1885
1885
  # * +:ip_owner_id+ - (String)
1886
+ # * +:iam_instance_profile+ - (Hash)
1887
+ # * +:arn+ - (String)
1888
+ # * +:id+ - (String)
1886
1889
  #
1887
1890
  # @return [Core::Response]
1888
1891
  #
@@ -2471,6 +2474,9 @@ module AWS
2471
2474
  # * +:private_ip_address+ - (String)
2472
2475
  # * +:security_group_id+ - (Array<String>)
2473
2476
  # * +:delete_on_termination+ - (Boolean)
2477
+ # * +:iam_instance_profile+ - (Hash)
2478
+ # * +:arn+ - (String)
2479
+ # * +:name+ - (String)
2474
2480
  # * +:instance_id+ - (String)
2475
2481
  # * +:create_time+ - (Time)
2476
2482
  # * +:product_description+ - (String)
@@ -3612,6 +3618,9 @@ module AWS
3612
3618
  # * +:private_ip_address+ - (String)
3613
3619
  # * +:groups+ - (Array<String>)
3614
3620
  # * +:delete_on_termination+ - (Boolean)
3621
+ # * +:iam_instance_profile+ - (Hash)
3622
+ # * +:arn+ - (String)
3623
+ # * +:name+ - (String)
3615
3624
  #
3616
3625
  # === Response Structure:
3617
3626
  #
@@ -3659,6 +3668,9 @@ module AWS
3659
3668
  # * +:private_ip_address+ - (String)
3660
3669
  # * +:security_group_id+ - (Array<String>)
3661
3670
  # * +:delete_on_termination+ - (Boolean)
3671
+ # * +:iam_instance_profile+ - (Hash)
3672
+ # * +:arn+ - (String)
3673
+ # * +:name+ - (String)
3662
3674
  # * +:instance_id+ - (String)
3663
3675
  # * +:create_time+ - (Time)
3664
3676
  # * +:product_description+ - (String)
@@ -3929,6 +3941,9 @@ module AWS
3929
3941
  # * +:private_ip_address+ - (String)
3930
3942
  # * +:groups+ - (Array<String>)
3931
3943
  # * +:delete_on_termination+ - (Boolean)
3944
+ # * +:iam_instance_profile+ - (Hash)
3945
+ # * +:arn+ - (String)
3946
+ # * +:name+ - (String)
3932
3947
  #
3933
3948
  # === Response Structure:
3934
3949
  #
@@ -4016,6 +4031,9 @@ module AWS
4016
4031
  # * +:association+ - (Hash)
4017
4032
  # * +:public_ip+ - (String)
4018
4033
  # * +:ip_owner_id+ - (String)
4034
+ # * +:iam_instance_profile+ - (Hash)
4035
+ # * +:arn+ - (String)
4036
+ # * +:id+ - (String)
4019
4037
  #
4020
4038
  # @return [Core::Response]
4021
4039
  #
@@ -146,15 +146,15 @@ module AWS
146
146
  # @return [Hash] Returns a hash of block
147
147
  # device mappings for the image. In each entry, the key is
148
148
  # the device name (e.g. +"/dev/sda1"+) and the value is an
149
- # object with the following methods that return information
149
+ # hash with the following keys that return information
150
150
  # about the block device:
151
151
  #
152
- # [snapshot_id] The ID of the snapshot that will be used to
152
+ # [:snapshot_id] The ID of the snapshot that will be used to
153
153
  # create this device (may be nil).
154
154
  #
155
- # [volume_size] The size of the volume, in GiBs.
155
+ # [:volume_size] The size of the volume, in GiBs.
156
156
  #
157
- # [delete_on_termination] True if the Amazon EBS volume is
157
+ # [:delete_on_termination] True if the Amazon EBS volume is
158
158
  # deleted on instance termination.
159
159
  def block_device_mappings
160
160
  (block_device_mapping || []).inject({}) do |h,mapping|
@@ -144,6 +144,10 @@ module AWS
144
144
  # @attr_reader [String,nil] subnet_id Instances launched in a VPC have
145
145
  # a subnet_id. Normal EC2 instances return nil.
146
146
  #
147
+ # @attr_reader [String,nil] iam_instance_profile_id
148
+ #
149
+ # @attr_reader [String,nil] iam_instance_profile_arn
150
+ #
147
151
  class Instance < Resource
148
152
 
149
153
  include TaggedItem
@@ -260,6 +264,18 @@ module AWS
260
264
 
261
265
  describe_call_attribute :subnet_id, :static => true
262
266
 
267
+ describe_call_attribute :iam_instance_profile_id,
268
+ :as => :iam_instance_profile,
269
+ :static => true do
270
+ translates_output{|profile| profile[:id] }
271
+ end
272
+
273
+ describe_call_attribute :iam_instance_profile_arn,
274
+ :as => :iam_instance_profile,
275
+ :static => true do
276
+ translates_output{|profile| profile[:arn] }
277
+ end
278
+
263
279
  attribute :status do
264
280
  translates_output{|state| state.name.tr("-","_").to_sym }
265
281
  end
@@ -631,20 +647,17 @@ module AWS
631
647
  instance_action :stop
632
648
  end
633
649
 
634
- # @private
635
650
  protected
651
+
636
652
  def find_in_response resp
637
653
  resp.instance_index[id]
638
654
  end
639
655
 
640
- # @private
641
- protected
642
656
  def instance_action name
643
657
  client.send("#{name}_instances", :instance_ids => [id])
644
658
  nil
645
659
  end
646
660
 
647
- protected
648
661
  def get_resource attribute
649
662
  if self.class.mutable_describe_attributes.include?(attribute.name)
650
663
  describe_attribute_call(attribute)
@@ -653,7 +666,6 @@ module AWS
653
666
  end
654
667
  end
655
668
 
656
- protected
657
669
  def attributes_from_response_object(obj)
658
670
  if atts = super(obj)
659
671
  if obj[:instance_state]
@@ -76,13 +76,17 @@ module AWS
76
76
  # @param [Hash] options Options for new instance. +:image_id+ is
77
77
  # the only required option.
78
78
  #
79
- # @option options :count How many instances to request. By
79
+ # @option options [Integer] :count How many instances to request. By
80
80
  # default one instance is requested. You can specify this
81
81
  # either as an integer or as a Range, to indicate the
82
82
  # minimum and maximum number of instances to run. Note that
83
83
  # for a new account you can request at most 20 instances at
84
84
  # once.
85
85
  #
86
+ # @option options [String] :iam_instance_profile The name or
87
+ # ARN of an IAM instance profile. This provides credentials
88
+ # to the EC2 instance(s) via the instance metadata service.
89
+ #
86
90
  # @option options [Hash] :block_device_mappings This must be a
87
91
  # hash; the keys are device names to map, and the value for
88
92
  # each entry determines how that device is mapped. Valid
@@ -192,6 +196,17 @@ module AWS
192
196
  #
193
197
  def create options = {}
194
198
 
199
+ if profile = options.delete(:iam_instance_profile)
200
+ profile = case profile
201
+ when /^arn:aws:iam::/ then { :arn => profile }
202
+ when String then { :name => profile }
203
+ when Hash then profile
204
+ else
205
+ msg = "expected a name or ARN string for :iam_instance_profile"
206
+ end
207
+ options[:iam_instance_profile] = profile
208
+ end
209
+
195
210
  if image = options.delete(:image)
196
211
  options[:image_id] = image.id
197
212
  end
@@ -118,5 +118,45 @@ module AWS
118
118
  extend ExceptionMixinClassMethods
119
119
  end
120
120
 
121
+ # Raised when AWS credentials could not be found.
122
+ class MissingCredentialsError < StandardError
123
+
124
+ def initialize msg = nil
125
+ msg ||= <<-MSG
126
+
127
+ Missing Credentials.
128
+
129
+ Unable to find AWS credentials. You can configure your AWS credentials
130
+ a few different ways:
131
+
132
+ * Call AWS.config with :access_key_id and :secret_access_key
133
+
134
+ * Export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to ENV
135
+
136
+ * On EC2 you can run instances with an IAM instance profile and credentials
137
+ will be auto loaded from the instance metadata service on those
138
+ instances.
139
+
140
+ * Call AWS.config with :credential_provider. A credential provider should
141
+ either include AWS::Core::CredentialProviders::Provider or respond to
142
+ the same public methods.
143
+
144
+ = Ruby on Rails
145
+
146
+ In a Ruby on Rails application you may also specify your credentials in
147
+ the following ways:
148
+
149
+ * Via a config initializer script using any of the methods mentioned above
150
+ (e.g. RAILS_ROOT/config/initializers/aws-sdk.rb).
151
+
152
+ * Via a yaml configuration file located at RAILS_ROOT/config/aws.yml.
153
+ This file should be formated like the default RAILS_ROOT/config/database.yml
154
+ file.
155
+
156
+ MSG
157
+ super(msg)
158
+ end
159
+ end
160
+
121
161
  end
122
162
  end