google-cloud-storage 0.23.1 → 0.23.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d25ea51c3061bfb14179befa5250f8665e7f9691
4
- data.tar.gz: b431f5182d343bb654b7d57cc75db83d6d5470f7
3
+ metadata.gz: eacda730dbe4335f179257e4ca952498675b931c
4
+ data.tar.gz: bb21912a5d50d23f83e92e496954cd78eb6155cf
5
5
  SHA512:
6
- metadata.gz: f257e340fb77698aaa60a23ac31d86d42352ad6c70450e59a0a30166f96b3c9b111244033131041c1c567d5a34a0c981d1a74b662af844e1c6276a69b2ad35be
7
- data.tar.gz: 419052576260453c9595b6c1a6236e8f325d0104fdd0ffc81f71bde1d17e00d28871eff0f8951ef9e56bba825289c7e00cbabff7bec861459fc32a6c23988a56
6
+ metadata.gz: 0977c4f43a27b33c5de1cbefbcfb648269e0f181430dd186e97d511758797162821c7f8e2999262c1c0c32ef1f7f6555893f29596bffb8b1ddd815aff2b07f08
7
+ data.tar.gz: 8e56264bf22deac8a2440cde15e8e9a4507ae717a4fbdcf10250ab155fd08cd6c35c66106b6bad3036a899e6af8120bf8da2402bee8ab6c2dc9e9e3312406127
@@ -210,7 +210,6 @@ module Google
210
210
  #
211
211
  # ```ruby
212
212
  # require "google/cloud/storage"
213
- # require "digest/sha2"
214
213
  #
215
214
  # storage = Google::Cloud::Storage.new
216
215
  # bucket = storage.bucket "my-todo-app"
@@ -229,6 +228,28 @@ module Google
229
228
  # encryption_key: key
230
229
  # ```
231
230
  #
231
+ # Use {Google::Cloud::Storage::File#rotate} to rotate customer-supplied
232
+ # encryption keys.
233
+ #
234
+ # ```ruby
235
+ # require "google/cloud/storage"
236
+ #
237
+ # storage = Google::Cloud::Storage.new
238
+ # bucket = storage.bucket "my-todo-app"
239
+ #
240
+ # # Old key was stored securely for later use.
241
+ # old_key = "y\x03\"\x0E\xB6\xD3\x9B\x0E\xAB*\x19\xFAv\xDEY\xBEI..."
242
+ #
243
+ # file = bucket.file "path/to/my-file.ext", encryption_key: old_key
244
+ #
245
+ # # Key generation shown for example purposes only. Write your own.
246
+ # cipher = OpenSSL::Cipher.new "aes-256-cfb"
247
+ # cipher.encrypt
248
+ # new_key = cipher.random_key
249
+ #
250
+ # file.rotate encryption_key: old_key, new_encryption_key: new_key
251
+ # ```
252
+ #
232
253
  # ## Downloading a File
233
254
  #
234
255
  # Files can be downloaded to the local file system. (See
@@ -16,6 +16,7 @@
16
16
  require "google/cloud/storage/bucket/acl"
17
17
  require "google/cloud/storage/bucket/list"
18
18
  require "google/cloud/storage/bucket/cors"
19
+ require "google/cloud/storage/post_object"
19
20
  require "google/cloud/storage/file"
20
21
  require "pathname"
21
22
 
@@ -514,6 +515,16 @@ module Google
514
515
  # @param [Hash] metadata A hash of custom, user-provided web-safe keys
515
516
  # and arbitrary string values that will returned with requests for the
516
517
  # file as "x-goog-meta-" response headers.
518
+ # @param [Symbol, String] storage_class Storage class of the file.
519
+ # Determines how the file is stored and determines the SLA and the
520
+ # cost of storage. Values include `:multi_regional`, `:regional`,
521
+ # `:nearline`, `:coldline`, `:standard`, and `:dra` (Durable Reduced
522
+ # Availability), as well as the strings returned by
523
+ # {Bucket#storage_class}. For more information, see [Storage
524
+ # Classes](https://cloud.google.com/storage/docs/storage-classes) and
525
+ # [Per-Object Storage
526
+ # Class](https://cloud.google.com/storage/docs/per-object-storage-class).
527
+ # The default value is the default storage class for the bucket.
517
528
  # @param [String] encryption_key Optional. A customer-supplied, AES-256
518
529
  # encryption key that will be used to encrypt the file.
519
530
  #
@@ -540,7 +551,6 @@ module Google
540
551
  #
541
552
  # @example Providing a customer-supplied encryption key:
542
553
  # require "google/cloud/storage"
543
- # require "digest/sha2"
544
554
  #
545
555
  # storage = Google::Cloud::Storage.new
546
556
  # bucket = storage.bucket "my-bucket"
@@ -562,14 +572,14 @@ module Google
562
572
  content_disposition: nil, content_encoding: nil,
563
573
  content_language: nil, content_type: nil,
564
574
  crc32c: nil, md5: nil, metadata: nil,
565
- encryption_key: nil
575
+ storage_class: nil, encryption_key: nil
566
576
  ensure_service!
567
577
  options = { acl: File::Acl.predefined_rule_for(acl), md5: md5,
568
578
  cache_control: cache_control, content_type: content_type,
569
579
  content_disposition: content_disposition, crc32c: crc32c,
570
- content_encoding: content_encoding,
571
- content_language: content_language, metadata: metadata,
572
- key: encryption_key }
580
+ content_encoding: content_encoding, metadata: metadata,
581
+ content_language: content_language, key: encryption_key,
582
+ storage_class: storage_class_for(storage_class) }
573
583
  ensure_file_exists! file
574
584
  # TODO: Handle file as an IO and path is missing more gracefully
575
585
  path ||= Pathname(file).to_path
@@ -676,6 +686,114 @@ module Google
676
686
  signer.signed_url options
677
687
  end
678
688
 
689
+ ##
690
+ # Generate a PostObject that includes the fields and url to
691
+ # upload objects via html forms.
692
+ #
693
+ # Generating a PostObject requires service account credentials,
694
+ # either by connecting with a service account when calling
695
+ # {Google::Cloud.storage}, or by passing in the service account
696
+ # `issuer` and `signing_key` values. Although the private key can
697
+ # be passed as a string for convenience, creating and storing
698
+ # an instance of # `OpenSSL::PKey::RSA` is more efficient
699
+ # when making multiple calls to `post_object`.
700
+ #
701
+ # A {SignedUrlUnavailable} is raised if the service account credentials
702
+ # are missing. Service account credentials are acquired by following the
703
+ # steps in [Service Account Authentication](
704
+ # https://cloud.google.com/storage/docs/authentication#service_accounts).
705
+ #
706
+ # @see https://cloud.google.com/storage/docs/xml-api/post-object
707
+ #
708
+ # @param [String] path Path to of the file in Google Cloud Storage.
709
+ # @param [Hash] policy The security policy that describes what
710
+ # can and cannot be uploaded in the form. When provided,
711
+ # the PostObject fields will include a Signature based on the JSON
712
+ # representation of this Hash and the same policy in Base64 format.
713
+ # If you do not provide a security policy, requests are considered
714
+ # to be anonymous and will only work with buckets that have granted
715
+ # WRITE or FULL_CONTROL permission to anonymous users.
716
+ # See [Policy Document](https://cloud.google.com/storage/docs/xml-api/post-object#policydocument)
717
+ # for more information.
718
+ # @param [String] issuer Service Account's Client Email.
719
+ # @param [String] client_email Service Account's Client Email.
720
+ # @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
721
+ # Private Key.
722
+ # @param [OpenSSL::PKey::RSA, String] private_key Service Account's
723
+ # Private Key.
724
+ #
725
+ # @return [PostObject]
726
+ #
727
+ # @example
728
+ # require "google/cloud/storage"
729
+ #
730
+ # storage = Google::Cloud::Storage.new
731
+ #
732
+ # bucket = storage.bucket "my-todo-app"
733
+ # post = bucket.post_object "avatars/heidi/400x400.png"
734
+ #
735
+ # post.url #=> "https://storage.googleapis.com"
736
+ # post.fields[:key] #=> "my-todo-app/avatars/heidi/400x400.png"
737
+ # post.fields[:GoogleAccessId] #=> "0123456789@gserviceaccount.com"
738
+ # post.fields[:signature] #=> "ABC...XYZ="
739
+ # post.fields[:policy] #=> "ABC...XYZ="
740
+ #
741
+ # @example Using a policy to define the upload authorization:
742
+ # require "google/cloud/storage"
743
+ #
744
+ # storage = Google::Cloud::Storage.new
745
+ #
746
+ # policy = {
747
+ # expiration: (Time.now + 3600).iso8601,
748
+ # conditions: [
749
+ # ["starts-with", "$key", ""],
750
+ # {acl: "bucket-owner-read"},
751
+ # {bucket: "travel-maps"},
752
+ # {success_action_redirect: "http://example.com/success.html"},
753
+ # ["eq", "$Content-Type", "image/jpeg"],
754
+ # ["content-length-range", 0, 1000000]
755
+ # ]
756
+ # }
757
+ #
758
+ # bucket = storage.bucket "my-todo-app"
759
+ # post = bucket.post_object "avatars/heidi/400x400.png",
760
+ # policy: policy
761
+ #
762
+ # post.url #=> "https://storage.googleapis.com"
763
+ # post.fields[:key] #=> "my-todo-app/avatars/heidi/400x400.png"
764
+ # post.fields[:GoogleAccessId] #=> "0123456789@gserviceaccount.com"
765
+ # post.fields[:signature] #=> "ABC...XYZ="
766
+ # post.fields[:policy] #=> "ABC...XYZ="
767
+ #
768
+ # @example Using the issuer and signing_key options:
769
+ # require "google/cloud/storage"
770
+ #
771
+ # storage = Google::Cloud::Storage.new
772
+ #
773
+ # bucket = storage.bucket "my-todo-app"
774
+ # key = OpenSSL::PKey::RSA.new
775
+ # post = bucket.post_object "avatars/heidi/400x400.png",
776
+ # issuer: "service-account@gcloud.com",
777
+ # signing_key: key
778
+ #
779
+ # post.url #=> "https://storage.googleapis.com"
780
+ # post.fields[:key] #=> "my-todo-app/avatars/heidi/400x400.png"
781
+ # post.fields[:GoogleAccessId] #=> "0123456789@gserviceaccount.com"
782
+ # post.fields[:signature] #=> "ABC...XYZ="
783
+ # post.fields[:policy] #=> "ABC...XYZ="
784
+ #
785
+ def post_object path, policy: nil, issuer: nil,
786
+ client_email: nil, signing_key: nil,
787
+ private_key: nil
788
+ ensure_service!
789
+ options = { issuer: issuer, client_email: client_email,
790
+ signing_key: signing_key, private_key: private_key,
791
+ policy: policy }
792
+
793
+ signer = File::Signer.from_bucket self, path
794
+ signer.post_object options
795
+ end
796
+
679
797
  ##
680
798
  # The Bucket::Acl instance used to control access to the bucket.
681
799
  #
@@ -806,6 +924,18 @@ module Google
806
924
  fail ArgumentError, "cannot find file #{file}"
807
925
  end
808
926
 
927
+ def storage_class_for str
928
+ return nil if str.nil?
929
+ { "durable_reduced_availability" => "DURABLE_REDUCED_AVAILABILITY",
930
+ "dra" => "DURABLE_REDUCED_AVAILABILITY",
931
+ "durable" => "DURABLE_REDUCED_AVAILABILITY",
932
+ "nearline" => "NEARLINE",
933
+ "coldline" => "COLDLINE",
934
+ "multi_regional" => "MULTI_REGIONAL",
935
+ "regional" => "REGIONAL",
936
+ "standard" => "STANDARD" }[str.to_s.downcase] || str.to_s
937
+ end
938
+
809
939
  ##
810
940
  # Yielded to a block to accumulate changes for a patch request.
811
941
  class Updater < Bucket
@@ -21,6 +21,8 @@ require "google/cloud/storage/file/verifier"
21
21
  module Google
22
22
  module Cloud
23
23
  module Storage
24
+ GOOGLEAPIS_URL = "https://storage.googleapis.com".freeze
25
+
24
26
  ##
25
27
  # # File
26
28
  #
@@ -265,6 +267,35 @@ module Google
265
267
  Base64.decode64 @gapi.customer_encryption.key_sha256
266
268
  end
267
269
 
270
+ ##
271
+ # The file's storage class. This defines how the file is stored and
272
+ # determines the SLA and the cost of storage. For more information, see
273
+ # [Storage
274
+ # Classes](https://cloud.google.com/storage/docs/storage-classes) and
275
+ # [Per-Object Storage
276
+ # Class](https://cloud.google.com/storage/docs/per-object-storage-class).
277
+ def storage_class
278
+ @gapi.storage_class
279
+ end
280
+
281
+ ##
282
+ # Updates how the file is stored and determines the SLA and the cost of
283
+ # storage. Values include `:multi_regional`, `:regional`, `:nearline`,
284
+ # `:coldline`, `:standard`, and `:dra` (Durable Reduced Availability),
285
+ # as well as the strings returned by {File#storage_class} or
286
+ # {Bucket#storage_class}. For more information, see [Storage
287
+ # Classes](https://cloud.google.com/storage/docs/storage-classes) and
288
+ # [Per-Object Storage
289
+ # Class](https://cloud.google.com/storage/docs/per-object-storage-class).
290
+ # The default value is the default storage class for the bucket. See
291
+ # {Bucket#storage_class}.
292
+ # @param [Symbol, String] storage_class Storage class of the file.
293
+ def storage_class= storage_class
294
+ resp = service.update_file_storage_class \
295
+ bucket, name, storage_class_for(storage_class)
296
+ @gapi = resp.resource
297
+ end
298
+
268
299
  ##
269
300
  # Updates the file with changes made in the given block in a single
270
301
  # PATCH request. The following attributes may be set: {#cache_control=},
@@ -460,6 +491,63 @@ module Google
460
491
  File.from_gapi gapi, service
461
492
  end
462
493
 
494
+ ##
495
+ # [Rewrites](https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite)
496
+ # the file to the same {#bucket} and {#name} with a new
497
+ # [customer-supplied encryption
498
+ # key](https://cloud.google.com/storage/docs/encryption#customer-supplied).
499
+ #
500
+ # If a new key is provided to this method, the new key must be used to
501
+ # subsequently download or copy the file. You must securely manage your
502
+ # keys and ensure that they are not lost. Also, please note that file
503
+ # metadata is not encrypted, with the exception of the CRC32C checksum
504
+ # and MD5 hash. The names of files and buckets are also not encrypted,
505
+ # and you can read or update the metadata of an encrypted file without
506
+ # providing the encryption key.
507
+ #
508
+ # @see https://cloud.google.com/storage/docs/encryption
509
+ #
510
+ # @param [String, nil] encryption_key Optional. The last
511
+ # customer-supplied, AES-256 encryption key used to encrypt the file,
512
+ # if one was used.
513
+ # @param [String, nil] new_encryption_key Optional. The new
514
+ # customer-supplied, AES-256 encryption key with which to encrypt the
515
+ # file. If `nil`, the rewritten file will be encrypted using the
516
+ # default server-side encryption, not customer-supplied encryption
517
+ # keys.
518
+ #
519
+ # @return [Google::Cloud::Storage::File]
520
+ #
521
+ # @example The file will be rewritten with a new encryption key:
522
+ # require "google/cloud/storage"
523
+ #
524
+ # storage = Google::Cloud::Storage.new
525
+ # bucket = storage.bucket "my-bucket"
526
+ #
527
+ # # Old key was stored securely for later use.
528
+ # old_key = "y\x03\"\x0E\xB6\xD3\x9B\x0E\xAB*\x19\xFAv\xDEY\xBEI..."
529
+ #
530
+ # file = bucket.file "path/to/my-file.ext", encryption_key: old_key
531
+ #
532
+ # # Key generation shown for example purposes only. Write your own.
533
+ # cipher = OpenSSL::Cipher.new "aes-256-cfb"
534
+ # cipher.encrypt
535
+ # new_key = cipher.random_key
536
+ #
537
+ # file.rotate encryption_key: old_key, new_encryption_key: new_key
538
+ #
539
+ def rotate encryption_key: nil, new_encryption_key: nil
540
+ ensure_service!
541
+ options = { source_key: encryption_key,
542
+ destination_key: new_encryption_key }
543
+ gapi = service.rewrite_file bucket, name, bucket, name, options
544
+ until gapi.done
545
+ options[:token] = gapi.rewrite_token
546
+ gapi = service.rewrite_file bucket, name, bucket, name, options
547
+ end
548
+ File.from_gapi gapi.resource, service
549
+ end
550
+
463
551
  ##
464
552
  # Permanently deletes the file.
465
553
  #
@@ -723,6 +811,18 @@ module Google
723
811
  file
724
812
  end
725
813
 
814
+ def storage_class_for str
815
+ return nil if str.nil?
816
+ { "durable_reduced_availability" => "DURABLE_REDUCED_AVAILABILITY",
817
+ "dra" => "DURABLE_REDUCED_AVAILABILITY",
818
+ "durable" => "DURABLE_REDUCED_AVAILABILITY",
819
+ "nearline" => "NEARLINE",
820
+ "coldline" => "COLDLINE",
821
+ "multi_regional" => "MULTI_REGIONAL",
822
+ "regional" => "REGIONAL",
823
+ "standard" => "STANDARD" }[str.to_s.downcase] || str.to_s
824
+ end
825
+
726
826
  ##
727
827
  # @private Create a signed_url for a file.
728
828
  class Signer
@@ -749,7 +849,7 @@ module Google
749
849
  ##
750
850
  # The external url to the file.
751
851
  def ext_url
752
- "https://storage.googleapis.com#{ext_path}"
852
+ "#{GOOGLEAPIS_URL}#{ext_path}"
753
853
  end
754
854
 
755
855
  def apply_option_defaults options
@@ -775,6 +875,33 @@ module Google
775
875
  @service.credentials.issuer
776
876
  end
777
877
 
878
+ def post_object options
879
+ options = apply_option_defaults options
880
+
881
+ fields = {
882
+ key: ext_path.sub("/", "")
883
+ }
884
+
885
+ p = options[:policy] || {}
886
+ fail "Policy must be given in a Hash" unless p.is_a? Hash
887
+
888
+ i = determine_issuer options
889
+ s = determine_signing_key options
890
+
891
+ fail SignedUrlUnavailable unless i && s
892
+
893
+ policy_str = p.to_json
894
+ policy = Base64.strict_encode64(policy_str).delete("\n")
895
+
896
+ signature = generate_signature s, policy
897
+
898
+ fields[:GoogleAccessId] = i
899
+ fields[:signature] = signature
900
+ fields[:policy] = policy
901
+
902
+ Google::Cloud::Storage::PostObject.new GOOGLEAPIS_URL, fields
903
+ end
904
+
778
905
  def signed_url options
779
906
  options = apply_option_defaults options
780
907
 
@@ -783,22 +910,22 @@ module Google
783
910
 
784
911
  fail SignedUrlUnavailable unless i && s
785
912
 
786
- sig = generate_signature s, options
913
+ sig = generate_signature s, signature_str(options)
787
914
  generate_signed_url i, sig, options[:expires]
788
915
  end
789
916
 
790
- def generate_signature signing_key, options = {}
917
+ def generate_signature signing_key, secret
791
918
  unless signing_key.respond_to? :sign
792
919
  signing_key = OpenSSL::PKey::RSA.new signing_key
793
920
  end
794
- signing_key.sign OpenSSL::Digest::SHA256.new, signature_str(options)
921
+ signature = signing_key.sign OpenSSL::Digest::SHA256.new, secret
922
+ Base64.strict_encode64(signature).delete("\n")
795
923
  end
796
924
 
797
925
  def generate_signed_url issuer, signed_string, expires
798
- signature = Base64.strict_encode64(signed_string).delete("\n")
799
926
  "#{ext_url}?GoogleAccessId=#{CGI.escape issuer}" \
800
927
  "&Expires=#{expires}" \
801
- "&Signature=#{CGI.escape signature}"
928
+ "&Signature=#{CGI.escape signed_string}"
802
929
  end
803
930
 
804
931
  def format_extension_headers headers
@@ -815,9 +942,15 @@ module Google
815
942
  ##
816
943
  # Yielded to a block to accumulate changes for a patch request.
817
944
  class Updater < File
945
+ # @private Do not allow storage_class to be set in an update call.
946
+ # It cannot be set with PATCH.
947
+ undef :storage_class=
948
+
949
+ # @private
818
950
  attr_reader :updates
951
+
819
952
  ##
820
- # Create an Updater object.
953
+ # @private Create an Updater object.
821
954
  def initialize gapi
822
955
  @updates = []
823
956
  @gapi = gapi
@@ -0,0 +1,55 @@
1
+ # Copyright 2014 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ module Storage
19
+ ##
20
+ # PostObject represents the URL, fields, and values needed to upload
21
+ # objects via html forms.
22
+ #
23
+ # @see https://cloud.google.com/storage/docs/xml-api/post-object
24
+ #
25
+ # @attr_reader [String] url The URL the form must post to.
26
+ # @attr_reader [Hash] fields The input fields that must be included in the
27
+ # form. Each key/value pair should be set as an input tag's name and
28
+ # value.
29
+ #
30
+ # @example
31
+ # require "google/cloud/storage"
32
+ #
33
+ # storage = Google::Cloud::Storage.new
34
+ #
35
+ # bucket = storage.bucket "my-todo-app"
36
+ # post = bucket.post_object "avatars/heidi/400x400.png"
37
+ #
38
+ # post.url #=> "https://storage.googleapis.com"
39
+ # post.fields[:key] #=> "my-todo-app/avatars/heidi/400x400.png"
40
+ # post.fields[:GoogleAccessId] #=> "0123456789@gserviceaccount.com"
41
+ # post.fields[:signature] #=> "ABC...XYZ="
42
+ # post.fields[:policy] #=> "ABC...XYZ="
43
+ #
44
+ class PostObject
45
+ attr_reader :url, :fields
46
+
47
+ # @private
48
+ def initialize url, fields
49
+ @url = url
50
+ @fields = fields
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -231,7 +231,7 @@ module Google
231
231
  # Values include `:multi_regional`, `:regional`, `:nearline`,
232
232
  # `:coldline`, `:standard`, and `:dra` (Durable Reduced
233
233
  # Availability), as well as the strings returned by
234
- # Bucket#storage_class. For more information, see [Storage
234
+ # {Bucket#storage_class}. For more information, see [Storage
235
235
  # Classes](https://cloud.google.com/storage/docs/storage-classes). The
236
236
  # default value is `:standard`, which is equivalent to
237
237
  # `:multi_regional` or `:regional` depending on the bucket's location
@@ -306,6 +306,7 @@ module Google
306
306
  end
307
307
 
308
308
  def storage_class_for str
309
+ return nil if str.nil?
309
310
  { "durable_reduced_availability" => "DURABLE_REDUCED_AVAILABILITY",
310
311
  "dra" => "DURABLE_REDUCED_AVAILABILITY",
311
312
  "durable" => "DURABLE_REDUCED_AVAILABILITY",
@@ -313,7 +314,7 @@ module Google
313
314
  "coldline" => "COLDLINE",
314
315
  "multi_regional" => "MULTI_REGIONAL",
315
316
  "regional" => "REGIONAL",
316
- "standard" => "STANDARD" }[str.to_s.downcase]
317
+ "standard" => "STANDARD" }[str.to_s.downcase] || str.to_s
317
318
  end
318
319
  end
319
320
  end
@@ -171,12 +171,13 @@ module Google
171
171
  cache_control: nil, content_disposition: nil,
172
172
  content_encoding: nil, content_language: nil,
173
173
  content_type: nil, crc32c: nil, md5: nil, metadata: nil,
174
- key: nil
174
+ storage_class: nil, key: nil
175
175
  file_obj = Google::Apis::StorageV1::Object.new \
176
176
  cache_control: cache_control, content_type: content_type,
177
177
  content_disposition: content_disposition, md5_hash: md5,
178
178
  content_encoding: content_encoding, crc32c: crc32c,
179
- content_language: content_language, metadata: metadata
179
+ content_language: content_language, metadata: metadata,
180
+ storage_class: storage_class
180
181
  content_type ||= mime_type_for(Pathname(source).to_path)
181
182
  execute do
182
183
  service.insert_object \
@@ -213,6 +214,35 @@ module Google
213
214
  end
214
215
  end
215
216
 
217
+ ## Rewrite a file from source bucket/object to a
218
+ # destination bucket/object.
219
+ def rewrite_file source_bucket_name, source_file_path,
220
+ destination_bucket_name, destination_file_path,
221
+ options = {}
222
+ options = rewrite_key_options options[:source_key],
223
+ options[:destination_key]
224
+ execute do
225
+ service.rewrite_object \
226
+ source_bucket_name, source_file_path,
227
+ destination_bucket_name, destination_file_path,
228
+ destination_predefined_acl: options[:acl],
229
+ source_generation: options[:generation],
230
+ rewrite_token: options[:token],
231
+ options: options
232
+ end
233
+ end
234
+
235
+ ## Rewrite a file from source bucket/object to a
236
+ # destination bucket/object.
237
+ def update_file_storage_class bucket_name, file_path, storage_class
238
+ execute do
239
+ service.rewrite_object \
240
+ bucket_name, file_path,
241
+ bucket_name, file_path,
242
+ Google::Apis::StorageV1::Object.new(storage_class: storage_class)
243
+ end
244
+ end
245
+
216
246
  ##
217
247
  # Download contents of a file.
218
248
  def download_file bucket_name, file_path, target_path, generation: nil,
@@ -285,15 +315,32 @@ module Google
285
315
 
286
316
  def key_options key
287
317
  options = {}
288
- if key
289
- key_sha256 = Digest::SHA256.digest key
290
- headers = {}
291
- headers["x-goog-encryption-algorithm"] = "AES256"
292
- headers["x-goog-encryption-key"] = Base64.strict_encode64 key
293
- headers["x-goog-encryption-key-sha256"] = \
294
- Base64.strict_encode64 key_sha256
295
- options[:header] = headers
318
+ encryption_key_headers options, key if key
319
+ options
320
+ end
321
+
322
+ def rewrite_key_options source_key, destination_key
323
+ options = {}
324
+ if source_key
325
+ encryption_key_headers options, source_key, copy_source: true
296
326
  end
327
+ encryption_key_headers options, destination_key if destination_key
328
+ options
329
+ end
330
+
331
+ # @private
332
+ # @param copy_source If true, header names are those for source object
333
+ # in rewrite request. If false, the header names are for use with any
334
+ # method supporting customer-supplied encryption keys.
335
+ # See https://cloud.google.com/storage/docs/encryption#request
336
+ def encryption_key_headers options, key, copy_source: false
337
+ source = copy_source ? "copy-source-" : ""
338
+ key_sha256 = Digest::SHA256.digest key
339
+ headers = (options[:header] ||= {})
340
+ headers["x-goog-#{source}encryption-algorithm"] = "AES256"
341
+ headers["x-goog-#{source}encryption-key"] = Base64.strict_encode64 key
342
+ headers["x-goog-#{source}encryption-key-sha256"] = \
343
+ Base64.strict_encode64 key_sha256
297
344
  options
298
345
  end
299
346
 
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Storage
19
- VERSION = "0.23.1"
19
+ VERSION = "0.23.2"
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.1
4
+ version: 0.23.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-14 00:00:00.000000000 Z
12
+ date: 2017-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '5.9'
62
+ version: '5.10'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '5.9'
69
+ version: '5.10'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: minitest-autotest
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -169,14 +169,14 @@ dependencies:
169
169
  name: yard-doctest
170
170
  requirement: !ruby/object:Gem::Requirement
171
171
  requirements:
172
- - - "~>"
172
+ - - "<="
173
173
  - !ruby/object:Gem::Version
174
174
  version: 0.1.8
175
175
  type: :development
176
176
  prerelease: false
177
177
  version_requirements: !ruby/object:Gem::Requirement
178
178
  requirements:
179
- - - "~>"
179
+ - - "<="
180
180
  - !ruby/object:Gem::Version
181
181
  version: 0.1.8
182
182
  description: google-cloud-storage is the official library for Google Cloud Storage.
@@ -202,6 +202,7 @@ files:
202
202
  - lib/google/cloud/storage/file/acl.rb
203
203
  - lib/google/cloud/storage/file/list.rb
204
204
  - lib/google/cloud/storage/file/verifier.rb
205
+ - lib/google/cloud/storage/post_object.rb
205
206
  - lib/google/cloud/storage/project.rb
206
207
  - lib/google/cloud/storage/service.rb
207
208
  - lib/google/cloud/storage/version.rb
@@ -225,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
226
  version: '0'
226
227
  requirements: []
227
228
  rubyforge_project:
228
- rubygems_version: 2.4.5.1
229
+ rubygems_version: 2.6.10
229
230
  signing_key:
230
231
  specification_version: 4
231
232
  summary: API Client library for Google Cloud Storage