aws-sdk 1.9.5 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
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