aws-sdk 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/aws.rb CHANGED
@@ -53,7 +53,7 @@ module AWS; end
53
53
 
54
54
  require 'aws/common'
55
55
 
56
- %w(ec2 s3 simple_db simple_email_service sns sqs record rails).each do |service|
56
+ %w(ec2 s3 simple_db simple_email_service sns sqs sts record rails).each do |service|
57
57
  $:.each do |load_path|
58
58
  if (Pathname.new(load_path) + "aws" + "#{service}.rb").exist?
59
59
  require "aws/#{service}"
@@ -0,0 +1,56 @@
1
+ # Copyright 2011 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
+ ---
15
+ :operations:
16
+ GetSessionToken:
17
+ :input:
18
+ DurationSeconds:
19
+ - :integer
20
+ :output:
21
+ - Credentials:
22
+ - Expiration:
23
+ - :timestamp
24
+ GetFederationToken:
25
+ :input:
26
+ Name:
27
+ - :string
28
+ - :pattern: !ruby/regexp /[\w+=,.@-]*/
29
+ - :required
30
+ Policy:
31
+ - :string
32
+ - :pattern: !ruby/regexp /[\u0009\u000A\u000D\u0020-\u00FF]+/
33
+ DurationSeconds:
34
+ - :integer
35
+ :output:
36
+ - Credentials:
37
+ - Expiration:
38
+ - :timestamp
39
+ - PackedPolicySize:
40
+ - :integer
41
+ :client_errors:
42
+ MalformedQueryString: []
43
+ InvalidParameterCombination: []
44
+ InvalidParameterValue: []
45
+ InvalidQueryParameter: []
46
+ MissingAction: []
47
+ MissingParameter: []
48
+ RequestExpired: []
49
+ AccessDenied: []
50
+ NotAuthorized: []
51
+ DelegationFailure: []
52
+ MalformedHttpRequest: []
53
+ MalformedPolicyDocument: []
54
+ PackedPolicyTooLarge: []
55
+ :server_errors:
56
+ ServiceUnavailable: []
@@ -0,0 +1,29 @@
1
+ # Copyright 2011 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
+ module AWS
15
+
16
+ module AuthorizeWithSessionToken
17
+
18
+ def add_authorization! signer
19
+ if signer.respond_to?(:session_token) and
20
+ token = signer.session_token
21
+ add_param("SecurityToken", token)
22
+ end
23
+
24
+ super
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -22,6 +22,7 @@ require 'aws/http/request'
22
22
  require 'aws/http/response'
23
23
  require 'aws/xml_grammar'
24
24
  require 'aws/option_grammar'
25
+ require 'aws/client_logging'
25
26
  require 'benchmark'
26
27
  require 'set'
27
28
 
@@ -32,6 +33,7 @@ module AWS
32
33
  class BaseClient
33
34
 
34
35
  include Configurable
36
+ include ClientLogging
35
37
 
36
38
  extend Naming
37
39
 
@@ -163,60 +165,8 @@ module AWS
163
165
  end
164
166
 
165
167
  protected
166
- def new_response(*args)
167
- Response.new(*args)
168
- end
169
-
170
- private
171
- def log severity, message
172
- config.logger.send(severity, message + "\n") if config.logger
173
- end
174
-
175
- private
176
- def log_client_request method_name, options, &block
177
-
178
- response = nil
179
- time = Benchmark.measure do
180
- response = yield
181
- end
182
-
183
- if options[:async]
184
- response.on_success { log_client_request_on_success(method_name,
185
- options,
186
- response,
187
- time) }
188
- else
189
- log_client_request_on_success(method_name,
190
- options,
191
- response,
192
- time)
193
- end
194
-
195
- response
196
-
197
- end
198
-
199
- private
200
- def log_client_request_on_success(method_name, options, response, time)
201
- status = response.http_response.status
202
- service = self.class.service_name
203
-
204
- pattern = "[AWS %s %s %.06f] %s %s"
205
- parts = [service, status, time.real, method_name, options.inspect]
206
- severity = :info
207
-
208
- if response.error
209
- pattern += " %s: %s"
210
- parts << response.error.class
211
- parts << response.error.message
212
- severity = :error
213
- end
214
-
215
- if response.cached
216
- pattern << " [CACHED]"
217
- end
218
-
219
- log(severity, pattern % parts)
168
+ def new_response(*args, &block)
169
+ Response.new(*args, &block)
220
170
  end
221
171
 
222
172
  private
@@ -244,8 +194,9 @@ module AWS
244
194
  populate_error(response)
245
195
  retry_delays ||= sleep_durations(response)
246
196
  if should_retry?(response) and !retry_delays.empty?
197
+ response.rebuild_request
247
198
  @http_handler.sleep_with_callback(retry_delays.shift) do
248
- async_request_with_retries(response, http_request, retry_delays)
199
+ async_request_with_retries(response, response.http_request, retry_delays)
249
200
  end
250
201
  else
251
202
  response.error ?
@@ -284,6 +235,9 @@ module AWS
284
235
  while should_retry?(response)
285
236
  break if sleeps.empty?
286
237
  Kernel.sleep(sleeps.shift)
238
+
239
+ # rebuild the request to get a fresh signature
240
+ response.rebuild_request
287
241
  response = yield
288
242
  end
289
243
 
@@ -375,38 +329,21 @@ module AWS
375
329
  return_or_raise(options) do
376
330
  log_client_request(name, options) do
377
331
 
378
- # we dont want to pass the async option to the configure block
379
- opts = options.dup
380
- opts.delete(:async)
381
-
382
- http_request = new_request
383
-
384
- # configure the http request
385
- http_request.host = endpoint
386
- http_request.proxy_uri = config.proxy_uri
387
- http_request.use_ssl = config.use_ssl?
388
- http_request.ssl_verify_peer = config.ssl_verify_peer?
389
- http_request.ssl_ca_file = config.ssl_ca_file
390
-
391
- send("configure_#{name}_request", http_request, opts, &block)
392
- http_request.headers["user-agent"] = user_agent_string
393
- http_request.add_authorization!(signer)
394
-
395
332
  if config.stub_requests?
396
333
 
397
- response = stub_for(name)
398
- response.http_request = http_request
334
+ response = stub_for(name)
335
+ response.http_request = build_request(name, options, &block)
399
336
  response.request_options = options
400
337
  response
401
338
 
402
339
  else
403
340
 
404
- response = new_response(http_request)
341
+ client = self
342
+ response = new_response { client.send(:build_request, name, options, &block) }
405
343
  response.request_type = name
406
344
  response.request_options = options
407
345
 
408
- if self.class::CACHEABLE_REQUESTS.
409
- include?(name) and
346
+ if self.class::CACHEABLE_REQUESTS.include?(name) and
410
347
  cache = AWS.response_cache and
411
348
  cached_response = cache.cached(response)
412
349
  cached_response.cached = true
@@ -435,6 +372,27 @@ module AWS
435
372
  end
436
373
  end
437
374
 
375
+ private
376
+ def build_request(name, options, &block)
377
+ # we dont want to pass the async option to the configure block
378
+ opts = options.dup
379
+ opts.delete(:async)
380
+
381
+ http_request = new_request
382
+
383
+ # configure the http request
384
+ http_request.host = endpoint
385
+ http_request.proxy_uri = config.proxy_uri
386
+ http_request.use_ssl = config.use_ssl?
387
+ http_request.ssl_verify_peer = config.ssl_verify_peer?
388
+ http_request.ssl_ca_file = config.ssl_ca_file
389
+
390
+ send("configure_#{name}_request", http_request, opts, &block)
391
+ http_request.headers["user-agent"] = user_agent_string
392
+ http_request.add_authorization!(signer)
393
+ http_request
394
+ end
395
+
438
396
  private
439
397
  def user_agent_string
440
398
  engine = (RUBY_ENGINE rescue nil or "ruby")
@@ -0,0 +1,117 @@
1
+ # Copyright 2011 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
+ module AWS
15
+
16
+ # @private
17
+ module ClientLogging
18
+
19
+ MAX_STRING_LENGTH = 50
20
+
21
+ def log_client_request(name, options)
22
+ response = nil
23
+ time = Benchmark.measure do
24
+ response = yield
25
+ end
26
+
27
+ if options[:async]
28
+ response.on_complete do
29
+ log_client_request_on_success(name, options, response, time)
30
+ end
31
+ else
32
+ log_client_request_on_success(name, options, response, time)
33
+ end
34
+ response
35
+ end
36
+
37
+ # Summarizes long strings and adds file size information
38
+ # @private
39
+ def sanitize_options(options)
40
+ sanitize_hash(options)
41
+ end
42
+
43
+ protected
44
+ def log severity, message
45
+ config.logger.send(severity, message + "\n") if config.logger
46
+ end
47
+
48
+ protected
49
+ def log_client_request_on_success(method_name, options, response, time)
50
+ status = response.http_response.status
51
+ service = self.class.service_name
52
+
53
+ pattern = "[AWS %s %s %.06f] %s %s"
54
+ parts = [service, status, time.real, method_name, sanitize_options(options)]
55
+ severity = :info
56
+
57
+ if response.error
58
+ pattern += " %s: %s"
59
+ parts << response.error.class
60
+ parts << response.error.message
61
+ severity = :error
62
+ end
63
+
64
+ if response.cached
65
+ pattern << " [CACHED]"
66
+ end
67
+
68
+ log(severity, pattern % parts)
69
+ end
70
+
71
+ protected
72
+ def sanitize_value(value)
73
+ case value
74
+ when Hash
75
+ sanitize_hash(value)
76
+ when Array
77
+ sanitize_array(value)
78
+ when File
79
+ sanitize_file(value)
80
+ when String
81
+ sanitize_string(value)
82
+ else
83
+ value.inspect
84
+ end
85
+ end
86
+
87
+ protected
88
+ def sanitize_string(str)
89
+ if str.size > MAX_STRING_LENGTH
90
+ "#<String \"#{str[0,6]}\" ... \"#{str[-6,6]}\" (#{str.size} characters)>"
91
+ else
92
+ str.inspect
93
+ end
94
+ end
95
+
96
+ protected
97
+ def sanitize_file(file)
98
+ "#<File:#{file.path} (#{File.size(file.path)} bytes)>"
99
+ end
100
+
101
+ protected
102
+ def sanitize_array(ary)
103
+ "[" +
104
+ ary.map { |v| sanitize_value(v) }.join(",") +
105
+ "]"
106
+ end
107
+
108
+ protected
109
+ def sanitize_hash(hash)
110
+ "{" + hash.map do |k,v|
111
+ "#{sanitize_value(k)}=>#{sanitize_value(v)}"
112
+ end.sort.join(",") + "}"
113
+ end
114
+
115
+ end
116
+
117
+ end
@@ -81,6 +81,7 @@ module AWS
81
81
  :simple_email_service_endpoint => 'email.us-east-1.amazonaws.com',
82
82
  :sns_endpoint => 'sns.us-east-1.amazonaws.com',
83
83
  :sqs_endpoint => 'sqs.us-east-1.amazonaws.com',
84
+ :sts_endpoint => 'sts.amazonaws.com',
84
85
  :stub_requests => false,
85
86
  :proxy_uri => nil,
86
87
  :use_ssl => true,
@@ -124,6 +125,12 @@ module AWS
124
125
  @options[:secret_access_key]
125
126
  end
126
127
 
128
+ # @return [String] Your AWS session token credential.
129
+ # @see STS
130
+ def session_token
131
+ @options[:session_token]
132
+ end
133
+
127
134
  # Used to create a new Configuration object with the given modifications.
128
135
  # The current configuration object is not modified.
129
136
  #
@@ -186,6 +193,11 @@ module AWS
186
193
  @options[:sqs_endpoint]
187
194
  end
188
195
 
196
+ # @return [String] The service endpoint for AWS Security Token Service.
197
+ def sts_endpoint
198
+ @options[:sts_endpoint]
199
+ end
200
+
189
201
  # @return [Boolean] Returns true if all reads to SimpleDB default to
190
202
  # consistent reads.
191
203
  def simple_db_consistent_reads?
@@ -207,7 +219,8 @@ module AWS
207
219
  def signer
208
220
  return @options[:signer] if @options[:signer]
209
221
  raise "Missing credentials" unless access_key_id and secret_access_key
210
- @options[:signer] ||= DefaultSigner.new(access_key_id, secret_access_key)
222
+ @options[:signer] ||=
223
+ DefaultSigner.new(access_key_id, secret_access_key, session_token)
211
224
  end
212
225
 
213
226
  # @return [Object,nil] Returns the current logger.
@@ -25,14 +25,24 @@ module AWS
25
25
  # @return [String] The Secret Access Key used to sign requests.
26
26
  attr_reader :secret_access_key
27
27
 
28
+ # @return [String] The Session Token used to sign requests.
29
+ attr_reader :session_token
30
+
28
31
  # @param [String] access_key_id The Access Key ID used to sign
29
32
  # requests.
30
33
  #
31
34
  # @param [String] secret_access_key The Secret Access Key used to
32
35
  # sign requests.
33
- def initialize(access_key_id, secret_access_key)
36
+ #
37
+ # @param [String] session_token The Session Token used to sign
38
+ # requests. You can get credentials that include a session
39
+ # token using the {STS} class.
40
+ def initialize(access_key_id,
41
+ secret_access_key,
42
+ session_token = nil)
34
43
  @access_key_id = access_key_id
35
44
  @secret_access_key = secret_access_key
45
+ @session_token = session_token
36
46
  end
37
47
 
38
48
  # Signs a string using the credentials stored in memory.