aws-sdk 1.9.5 → 1.10.0

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 (49) hide show
  1. data/lib/aws/api_config/DynamoDB-2012-08-10.yml +4 -0
  2. data/lib/aws/api_config/EC2-2013-02-01.yml +1 -1
  3. data/lib/aws/api_config/ElasticTranscoder-2012-09-25.yml +948 -19
  4. data/lib/aws/api_config/OpsWorks-2013-02-18.yml +83 -2
  5. data/lib/aws/auto_scaling/client.rb +15 -0
  6. data/lib/aws/cloud_formation/client.rb +11 -0
  7. data/lib/aws/cloud_front/client.rb +58 -40
  8. data/lib/aws/cloud_search/client.rb +20 -0
  9. data/lib/aws/cloud_watch/client.rb +5 -0
  10. data/lib/aws/core.rb +5 -4
  11. data/lib/aws/core/configuration.rb +3 -1
  12. data/lib/aws/core/policy.rb +27 -1
  13. data/lib/aws/data_pipeline/client.rb +12 -0
  14. data/lib/aws/direct_connect/client.rb +11 -0
  15. data/lib/aws/dynamo_db/client.rb +17 -0
  16. data/lib/aws/dynamo_db/client_v2.rb +905 -417
  17. data/lib/aws/ec2.rb +1 -1
  18. data/lib/aws/ec2/client.rb +88 -0
  19. data/lib/aws/ec2/instance.rb +3 -1
  20. data/lib/aws/ec2/security_group.rb +1 -1
  21. data/lib/aws/elastic_beanstalk/client.rb +21 -0
  22. data/lib/aws/elastic_transcoder/client.rb +681 -114
  23. data/lib/aws/elasticache/client.rb +23 -0
  24. data/lib/aws/elb/client.rb +13 -0
  25. data/lib/aws/emr/client.rb +3 -0
  26. data/lib/aws/glacier/client.rb +7 -0
  27. data/lib/aws/iam/client.rb +35 -0
  28. data/lib/aws/import_export/client.rb +5 -0
  29. data/lib/aws/ops_works/client.rb +718 -238
  30. data/lib/aws/rds/client.rb +46 -0
  31. data/lib/aws/redshift/client.rb +30 -0
  32. data/lib/aws/route_53/client.rb +10 -0
  33. data/lib/aws/s3.rb +1 -1
  34. data/lib/aws/s3/client.rb +42 -27
  35. data/lib/aws/s3/client/xml.rb +10 -0
  36. data/lib/aws/s3/multipart_upload.rb +43 -16
  37. data/lib/aws/s3/s3_object.rb +61 -26
  38. data/lib/aws/s3/uploaded_part.rb +3 -1
  39. data/lib/aws/s3/uploaded_part_collection.rb +1 -1
  40. data/lib/aws/simple_db/client.rb +10 -0
  41. data/lib/aws/simple_email_service/client.rb +11 -0
  42. data/lib/aws/simple_workflow/client.rb +18 -0
  43. data/lib/aws/sns/client.rb +9 -0
  44. data/lib/aws/sqs/client.rb +9 -0
  45. data/lib/aws/storage_gateway/client.rb +72 -37
  46. data/lib/aws/sts/client.rb +3 -0
  47. data/lib/aws/version.rb +1 -1
  48. metadata +17 -9
  49. checksums.yaml +0 -7
@@ -142,6 +142,7 @@ module AWS
142
142
  # @return [Core::Response]
143
143
  # The #data method of the response object returns
144
144
  # a hash with the following structure:
145
+ #
145
146
  # * `:change_info` - (Hash)
146
147
  # * `:id` - (String)
147
148
  # * `:status` - (String)
@@ -180,6 +181,7 @@ module AWS
180
181
  # @return [Core::Response]
181
182
  # The #data method of the response object returns
182
183
  # a hash with the following structure:
184
+ #
183
185
  # * `:health_check` - (Hash)
184
186
  # * `:id` - (String)
185
187
  # * `:caller_reference` - (String)
@@ -219,6 +221,7 @@ module AWS
219
221
  # @return [Core::Response]
220
222
  # The #data method of the response object returns
221
223
  # a hash with the following structure:
224
+ #
222
225
  # * `:hosted_zone` - (Hash)
223
226
  # * `:id` - (String)
224
227
  # * `:name` - (String)
@@ -250,6 +253,7 @@ module AWS
250
253
  # @return [Core::Response]
251
254
  # The #data method of the response object returns
252
255
  # a hash with the following structure:
256
+ #
253
257
  # * `:change_info` - (Hash)
254
258
  # * `:id` - (String)
255
259
  # * `:status` - (String)
@@ -266,6 +270,7 @@ module AWS
266
270
  # @return [Core::Response]
267
271
  # The #data method of the response object returns
268
272
  # a hash with the following structure:
273
+ #
269
274
  # * `:change_info` - (Hash)
270
275
  # * `:id` - (String)
271
276
  # * `:status` - (String)
@@ -280,6 +285,7 @@ module AWS
280
285
  # @return [Core::Response]
281
286
  # The #data method of the response object returns
282
287
  # a hash with the following structure:
288
+ #
283
289
  # * `:health_check` - (Hash)
284
290
  # * `:id` - (String)
285
291
  # * `:caller_reference` - (String)
@@ -298,6 +304,7 @@ module AWS
298
304
  # @return [Core::Response]
299
305
  # The #data method of the response object returns
300
306
  # a hash with the following structure:
307
+ #
301
308
  # * `:hosted_zone` - (Hash)
302
309
  # * `:id` - (String)
303
310
  # * `:name` - (String)
@@ -320,6 +327,7 @@ module AWS
320
327
  # @return [Core::Response]
321
328
  # The #data method of the response object returns
322
329
  # a hash with the following structure:
330
+ #
323
331
  # * `:health_checks` - (Array<Hash>)
324
332
  # * `:id` - (String)
325
333
  # * `:caller_reference` - (String)
@@ -346,6 +354,7 @@ module AWS
346
354
  # @return [Core::Response]
347
355
  # The #data method of the response object returns
348
356
  # a hash with the following structure:
357
+ #
349
358
  # * `:hosted_zones` - (Array<Hash>)
350
359
  # * `:id` - (String)
351
360
  # * `:name` - (String)
@@ -393,6 +402,7 @@ module AWS
393
402
  # @return [Core::Response]
394
403
  # The #data method of the response object returns
395
404
  # a hash with the following structure:
405
+ #
396
406
  # * `:resource_record_sets` - (Array<Hash>)
397
407
  # * `:name` - (String)
398
408
  # * `:type` - (String)
data/lib/aws/s3.rb CHANGED
@@ -81,7 +81,7 @@ module AWS
81
81
  # obj.write(Pathname.new('/path/to/file.txt'))
82
82
  #
83
83
  # # streaming download from S3 to a file on disk
84
- # File.open('file.txt', 'w') do |file|
84
+ # File.open('file.txt', 'wb') do |file|
85
85
  # obj.read do |chunk|
86
86
  # file.write(chunk)
87
87
  # end
data/lib/aws/s3/client.rb CHANGED
@@ -771,33 +771,6 @@ module AWS
771
771
  # :data => 'This is the readme for ...',
772
772
  # })
773
773
  #
774
- # ## Block Form
775
- #
776
- # In block form, this method yields a stream to the block that
777
- # accepts data chunks. For example:
778
- #
779
- # s3_client.put_object(
780
- # :bucket_name => 'mybucket',
781
- # :key => 'some/key'
782
- # :content_length => File.size('myfile')
783
- # ) do |buffer|
784
- #
785
- # File.open('myfile') do |io|
786
- # buffer.write(io.read(length)) until io.eof?
787
- # end
788
- #
789
- # end
790
- #
791
- # This form is useful if you need finer control over how
792
- # potentially large amounts of data are read from another
793
- # source before being sent to S3; for example, if you are
794
- # using a non-blocking IO model and reading from a large file
795
- # on disk or from another network stream. Some HTTP handlers
796
- # do not support streaming request bodies, so if you plan to
797
- # upload large objects using this interface you should make
798
- # sure the HTTP handler you configure for the client meets
799
- # your needs.
800
- #
801
774
  # @overload put_object(options = {})
802
775
  # @param [Hash] options
803
776
  # @option options [required,String] :bucket_name
@@ -1364,6 +1337,39 @@ module AWS
1364
1337
 
1365
1338
  end
1366
1339
 
1340
+ object_method(:copy_part, :put, XML::CopyPart, :header_options => {
1341
+ :copy_source => 'x-amz-copy-source',
1342
+ :copy_source_range => 'x-amz-copy-source-range',
1343
+ }) do
1344
+
1345
+ configure_request do |request, options|
1346
+
1347
+ validate!(:copy_source, options[:copy_source]) do
1348
+ "may not be blank" if options[:copy_source].to_s.empty?
1349
+ end
1350
+
1351
+ validate!(:copy_source_range, options[:copy_source_range]) do
1352
+ "must start with bytes=" if options[:copy_source_range] && !options[:copy_source_range].start_with?("bytes=")
1353
+ end
1354
+
1355
+ options = options.merge(:copy_source => escape_path(options[:copy_source]))
1356
+
1357
+ require_upload_id!(options[:upload_id])
1358
+ request.add_param('uploadId', options[:upload_id])
1359
+
1360
+ require_part_number!(options[:part_number])
1361
+ request.add_param('partNumber', options[:part_number])
1362
+
1363
+ super(request, options)
1364
+
1365
+ if options[:version_id]
1366
+ req.headers['x-amz-copy-source'] += "?versionId=#{options[:version_id]}"
1367
+ end
1368
+
1369
+ end
1370
+
1371
+ end
1372
+
1367
1373
  protected
1368
1374
 
1369
1375
  def extract_error_details response
@@ -1434,6 +1440,15 @@ module AWS
1434
1440
  Base64.encode64(Digest::MD5.digest(str)).strip
1435
1441
  end
1436
1442
 
1443
+ def parse_copy_part_response resp
1444
+ doc = REXML::Document.new(resp.http_response.body)
1445
+ resp[:etag] = doc.root.elements["ETag"].text
1446
+ resp[:last_modified] = doc.root.elements["LastModified"].text
1447
+ if header = resp.http_response.headers['x-amzn-requestid']
1448
+ data[:request_id] = [header].flatten.first
1449
+ end
1450
+ end
1451
+
1437
1452
  def extract_object_headers resp
1438
1453
  meta = {}
1439
1454
  resp.http_response.headers.each_pair do |name,value|
@@ -225,6 +225,16 @@ module AWS
225
225
  end
226
226
  end
227
227
 
228
+ CopyPart = BaseGrammar.customize do
229
+ element "ETag" do
230
+ rename :etag
231
+ end
232
+ element "LastModified" do
233
+ datetime_value
234
+ rename :last_modified
235
+ end
236
+ end
237
+
228
238
  end
229
239
  end
230
240
  end
@@ -204,6 +204,36 @@ module AWS
204
204
  UploadedPart.new(self, part_number)
205
205
  end
206
206
 
207
+ # Copies a part.
208
+ #
209
+ # @param [string] copy_source Full S3 name of source, ie bucket/key
210
+ #
211
+ # @param [Hash] options Additional options for the copy.
212
+ #
213
+ # @option options [Integer] :part_number The part number.
214
+ #
215
+ # @option options [Integer] :copy_source_range Range of bytes to copy, ie bytes=0-45687
216
+ def copy_part(copy_source, options = {})
217
+ part_options = base_opts.merge(options)
218
+ part_options.merge!(:copy_source => copy_source)
219
+
220
+ unless part_options[:part_number]
221
+ @increment_mutex.synchronize do
222
+ part_options[:part_number] = (@last_part += 1)
223
+ end
224
+ end
225
+ part_number = part_options[:part_number]
226
+
227
+ resp = client.copy_part(part_options)
228
+ @completed_mutex.synchronize do
229
+ @completed_parts[part_number] = {
230
+ :part_number => part_number,
231
+ :etag => resp[:etag]
232
+ }
233
+ end
234
+ UploadedPart.new(self, part_number)
235
+ end
236
+
207
237
  # Completes the upload by assembling previously uploaded
208
238
  # parts.
209
239
  #
@@ -282,26 +312,23 @@ module AWS
282
312
  "<#{self.class}:#{object.bucket.name}/#{object.key}:#{id}>"
283
313
  end
284
314
 
285
- # @api private
286
315
  private
316
+
287
317
  def get_complete_opts(part_numbers = nil)
288
- parts_resp = client.list_parts(base_opts)
289
- complete_opts =
290
- base_opts.merge(:parts =>
291
- parts_resp.parts.map do |part|
292
- { :part_number => part.part_number,
293
- :etag => part.etag }
294
- end)
295
-
296
- complete_opts[:parts].reject! do |part|
297
- !part_numbers.include?(part[:part_number])
298
- end if part_numbers
299
-
300
- complete_opts
318
+ parts = []
319
+ self.parts.each do |part|
320
+ parts << { :part_number => part.part_number, :etag => part.etag }
321
+ end
322
+
323
+ if part_numbers
324
+ parts.reject! do |part|
325
+ !part_numbers.include?(part[:part_number])
326
+ end
327
+ end
328
+
329
+ base_opts.merge(:parts => parts)
301
330
  end
302
331
 
303
- # @api private
304
- private
305
332
  def base_opts
306
333
  opts = {
307
334
  :bucket_name => object.bucket.name,
@@ -63,7 +63,7 @@ module AWS
63
63
  # obj.write(:file => path_to_file)
64
64
  #
65
65
  # # Also accepts an open file object
66
- # file = File.open(path_to_file, 'r')
66
+ # file = File.open(path_to_file, 'rb')
67
67
  # obj.write(file)
68
68
  #
69
69
  # All three examples above produce the same result. The file
@@ -72,8 +72,8 @@ module AWS
72
72
  #
73
73
  # ## Streaming Uploads
74
74
  #
75
- # When you call {#write} with any IO-like object (must respond to
76
- # #read and #eof?), it will be streamed to S3 in chunks.
75
+ # When you call {#write} with an IO-like object, it will be streamed
76
+ # to S3 in chunks.
77
77
  #
78
78
  # While it is possible to determine the size of many IO objects, you may
79
79
  # have to specify the :content_length of your IO object.
@@ -104,7 +104,7 @@ module AWS
104
104
  # If you want to stream an object from S3, you can pass a block
105
105
  # to {#read}.
106
106
  #
107
- # File.open('output', 'w') do |file|
107
+ # File.open('output', 'wb') do |file|
108
108
  # large_object.read do |chunk|
109
109
  # file.write(chunk)
110
110
  # end
@@ -460,7 +460,7 @@ module AWS
460
460
  # obj.write(Pathname.new('path/to/file.txt'))
461
461
  #
462
462
  # # file objects
463
- # obj.write(File.open('path/to/file.txt', 'r'))
463
+ # obj.write(File.open('path/to/file.txt', 'rb'))
464
464
  #
465
465
  # # IO objects (must respond to #read and #eof?)
466
466
  # obj.write(io)
@@ -838,6 +838,9 @@ module AWS
838
838
  # when the object being copied was client-side encrypted. This
839
839
  # is important so the encryption metadata will be copied.
840
840
  #
841
+ # @option options [Boolean] :use_multipart_copy (false) Set this to
842
+ # `true` if you need to copy an object that is larger than 5GB.
843
+ #
841
844
  # @option options :cache_control [String] Can be used to specify
842
845
  # caching behavior. See
843
846
  # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
@@ -889,7 +892,11 @@ module AWS
889
892
  options[:bucket_name] = bucket.name
890
893
  options[:key] = key
891
894
 
892
- client.copy_object(options)
895
+ if use_multipart_copy?(options)
896
+ multipart_copy(options)
897
+ else
898
+ resp = client.copy_object(options)
899
+ end
893
900
 
894
901
  nil
895
902
 
@@ -990,7 +997,7 @@ module AWS
990
997
  # the HTTP response.
991
998
  #
992
999
  # # read an object from S3 to a file
993
- # File.open('output.txt', 'w') do |file|
1000
+ # File.open('output.txt', 'wb') do |file|
994
1001
  # bucket.objects['key'].read do |chunk|
995
1002
  # file.write(chunk)
996
1003
  # end
@@ -1173,6 +1180,8 @@ module AWS
1173
1180
  # @option options [Boolean] :secure (true) Whether to generate a
1174
1181
  # secure (HTTPS) URL or a plain HTTP url.
1175
1182
  #
1183
+ # @option options [String] :content_type
1184
+ # @option options [String] :content_md5
1176
1185
  # @option options [String] :endpoint Sets the hostname of the
1177
1186
  # endpoint.
1178
1187
  #
@@ -1208,23 +1217,23 @@ module AWS
1208
1217
  # HTTP GET on the returned URL.
1209
1218
  # @return [URI::HTTP, URI::HTTPS]
1210
1219
  def url_for(method, options = {})
1211
-
1220
+ options = options.dup
1212
1221
  options[:secure] = config.use_ssl? unless options.key?(:secure)
1222
+ options[:expires] = expiration_timestamp(options[:expires])
1213
1223
 
1214
1224
  req = request_for_signing(options)
1215
-
1216
- method = http_method(method)
1217
- expires = expiration_timestamp(options[:expires])
1218
- req.add_param("AWSAccessKeyId",
1219
- config.credential_provider.access_key_id)
1225
+ req.http_method = http_method(method)
1226
+ req.add_param("AWSAccessKeyId", config.credential_provider.access_key_id)
1220
1227
  req.add_param("versionId", options[:version_id]) if options[:version_id]
1221
- req.add_param("Signature", signature(method, expires, req))
1222
- req.add_param("Expires", expires)
1223
- req.add_param("x-amz-security-token",
1224
- config.credential_provider.session_token) if
1225
- config.credential_provider.session_token
1228
+ req.add_param("Signature", signature(req, options))
1229
+ req.add_param("Expires", options[:expires])
1230
+ if config.credential_provider.session_token
1231
+ req.add_param(
1232
+ "x-amz-security-token",
1233
+ config.credential_provider.session_token
1234
+ )
1235
+ end
1226
1236
 
1227
- secure = options.fetch(:secure, config.use_ssl?)
1228
1237
  build_uri(req, options)
1229
1238
  end
1230
1239
 
@@ -1272,6 +1281,34 @@ module AWS
1272
1281
 
1273
1282
  private
1274
1283
 
1284
+ # Used to determine if the data needs to be copied in parts
1285
+ def use_multipart_copy? options
1286
+ options[:use_multipart_copy]
1287
+ end
1288
+
1289
+ def multipart_copy options
1290
+
1291
+ unless options[:content_length]
1292
+ msg = "unknown content length, must set :content_length " +
1293
+ "to use multi-part copy"
1294
+ raise ArgumentError, msg
1295
+ end
1296
+
1297
+ part_size = compute_part_size(options)
1298
+ clean_up_options(options)
1299
+ source_length = options.delete(:content_length)
1300
+
1301
+ multipart_upload(options) do |upload|
1302
+ pos = 0
1303
+ # We copy in part_size chunks until we read the
1304
+ until pos >= source_length
1305
+ last_byte = (pos + part_size >= source_length) ? source_length - 1 : pos + part_size - 1
1306
+ upload.copy_part(options[:copy_source], options.merge({:copy_source_range => "bytes=#{pos}-#{last_byte}"}))
1307
+ pos += part_size
1308
+ end
1309
+ end
1310
+ end
1311
+
1275
1312
  # @return [Boolean]
1276
1313
  def should_decrypt? options
1277
1314
  options[:encryption_key] or config.s3_encryption_key
@@ -1347,13 +1384,12 @@ module AWS
1347
1384
  :query => request.querystring)
1348
1385
  end
1349
1386
 
1350
- def signature(method, expires, request)
1351
-
1387
+ def signature request, options
1352
1388
  parts = []
1353
- parts << method
1354
- parts << ""
1355
- parts << ""
1356
- parts << expires
1389
+ parts << request.http_method
1390
+ parts << options[:content_md5].to_s
1391
+ parts << options[:content_type].to_s
1392
+ parts << options[:expires]
1357
1393
  if token = config.credential_provider.session_token
1358
1394
  parts << "x-amz-security-token:#{token}"
1359
1395
  end
@@ -1363,7 +1399,6 @@ module AWS
1363
1399
 
1364
1400
  secret = config.credential_provider.secret_access_key
1365
1401
  Core::Signer.sign(secret, string_to_sign, 'sha1')
1366
-
1367
1402
  end
1368
1403
 
1369
1404
  def expiration_timestamp(input)
@@ -33,6 +33,7 @@ module AWS
33
33
  def initialize(upload, part_number, opts = {})
34
34
  @upload = upload
35
35
  @part_number = part_number
36
+ @etag = opts[:etag]
36
37
  super
37
38
  end
38
39
 
@@ -57,7 +58,8 @@ module AWS
57
58
 
58
59
  # @return [String] The ETag of the part.
59
60
  def etag
60
- get_attribute(:etag)
61
+ @etag ||= get_attribute(:etag)
62
+ @etag
61
63
  end
62
64
 
63
65
  # @api private