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 +1 -1
- data/lib/aws/api_config/STS-2011-06-15.yml +56 -0
- data/lib/aws/authorize_with_session_token.rb +29 -0
- data/lib/aws/base_client.rb +35 -77
- data/lib/aws/client_logging.rb +117 -0
- data/lib/aws/configuration.rb +14 -1
- data/lib/aws/default_signer.rb +11 -1
- data/lib/aws/ec2/request.rb +2 -0
- data/lib/aws/option_grammar.rb +22 -1
- data/lib/aws/policy.rb +6 -4
- data/lib/aws/response.rb +9 -2
- data/lib/aws/s3/client.rb +6 -1
- data/lib/aws/s3/object_metadata.rb +33 -2
- data/lib/aws/s3/request.rb +4 -0
- data/lib/aws/s3/s3_object.rb +71 -20
- data/lib/aws/sns/request.rb +2 -0
- data/lib/aws/sqs/request.rb +3 -1
- data/lib/aws/sts.rb +143 -0
- data/lib/aws/sts/client.rb +38 -0
- data/lib/aws/sts/client/xml.rb +38 -0
- data/lib/aws/sts/errors.rb +29 -0
- data/lib/aws/sts/federated_session.rb +58 -0
- data/lib/aws/sts/policy.rb +32 -0
- data/lib/aws/sts/request.rb +27 -0
- data/lib/aws/sts/session.rb +48 -0
- metadata +62 -83
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
|
data/lib/aws/base_client.rb
CHANGED
@@ -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 =
|
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
|
-
|
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
|
data/lib/aws/configuration.rb
CHANGED
@@ -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] ||=
|
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.
|
data/lib/aws/default_signer.rb
CHANGED
@@ -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
|
-
|
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.
|