google-cloud-storage 1.30.0 → 1.34.0

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
  SHA256:
3
- metadata.gz: d3b78945de5adc36366ded346357d71f954327a48b11d9d909ad5b8443f51c95
4
- data.tar.gz: adcc876f70b87130ca732a591a9f1d6aa278e03a0356ea012620f30650c3b25e
3
+ metadata.gz: b25b270d900a20eeef47726ae61ddbaf11457d3cdab25c1d8b2169d4537f0047
4
+ data.tar.gz: 4cdc04bbe927ada1e58ee895889c210d1a3afebfadb7917e8dfd8db7218bcd4b
5
5
  SHA512:
6
- metadata.gz: e46be5fe50420e4a674add04d12a06243dba3438aafedc9356246ac8e5fa66aa0db547d9264a70b940cd46133aed1b7256cdad02397c93b0eeb73d312fffdd48
7
- data.tar.gz: 0a89f487726406d8865b1c675d43f1153e3cf78d0e5b8df1ebc4eb1f09a051f9dd45c328503d500dda6aee4bcd60c3693104d0371755154263eb52ccceaf3b1b
6
+ metadata.gz: 3afb0f705f9592631928e5f4645513b273d729067578f333052e0dc51da38d8aa4951ba2778aaeb3e6799680fa783a2ce6426d6abaf5e9c796029977ce3ecaea
7
+ data.tar.gz: 750da06b028394f5018431945ba86a44733414b334cc9677f81031fd6f0271df47ae74612047487f077ec27c06f645b27b0ab4e6bb875134610c197ac3fd446a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Release History
2
2
 
3
+ ### 1.34.0 / 2021-06-30
4
+
5
+ #### Features
6
+
7
+ * Add support for automatic crc32c and md5 upload verification
8
+ * Add checksum to Bucket#create_file
9
+
10
+ ### 1.33.0 / 2021-06-29
11
+
12
+ #### Features
13
+
14
+ * Add support for PublicAccessPrevention
15
+ * Add Bucket#public_access_prevention
16
+ * Add Bucket#public_access_prevention=
17
+ * Add Bucket#public_access_prevention_enforced?
18
+ * Add Bucket#public_access_prevention_unspecified?
19
+ * Add samples for PublicAccessPrevention
20
+
21
+ ### 1.32.0 / 2021-06-22
22
+
23
+ #### Features
24
+
25
+ * Add sources_if_generation_match to Bucket#compose
26
+ * Add support for (meta)generation preconditions to File operations
27
+ * Add if_(meta)generation_match options to Bucket#compose
28
+ * Add if_(meta)generation_(not_)match options to Bucket#create_file
29
+ * Add if_(meta)generation_(not_)match options to Bucket#file
30
+ * Add if_(meta)generation_(not_)match options to File#delete.
31
+ * Add if_(meta)generation_(not_)match options to File#rewrite
32
+ * Add generation and if_(meta)generation_(not_)match options to File#update
33
+ * Add generation and if_(meta)generation_(not_)match options to File::Acl predefined_acl methods
34
+
35
+ #### Bug Fixes
36
+
37
+ * Expand googleauth dependency to support future 1.x versions
38
+ * Update File::Verifier to test for File#to_path
39
+
40
+ ### 1.31.1 / 2021-05-19
41
+
42
+ #### Documentation
43
+
44
+ * Update IAMCredentialsService#sign_service_account_blob examples
45
+
46
+ ### 1.31.0 / 2021-03-10
47
+
48
+ #### Features
49
+
50
+ * Drop support for Ruby 2.4 and add support for Ruby 3.0
51
+
3
52
  ### 1.30.0 / 2021-01-13
4
53
 
5
54
  #### Features
data/CONTRIBUTING.md CHANGED
@@ -24,7 +24,7 @@ be able to accept your pull requests.
24
24
  In order to use the google-cloud-storage console and run the project's tests,
25
25
  there is a small amount of setup:
26
26
 
27
- 1. Install Ruby. google-cloud-storage requires Ruby 2.4+. You may choose to
27
+ 1. Install Ruby. google-cloud-storage requires Ruby 2.5+. You may choose to
28
28
  manage your Ruby and gem installations with [RVM](https://rvm.io/),
29
29
  [rbenv](https://github.com/rbenv/rbenv), or
30
30
  [chruby](https://github.com/postmodern/chruby).
@@ -119,15 +119,14 @@ If you alter an example's title, you may encounter breaking tests.
119
119
  ### Storage Acceptance Tests
120
120
 
121
121
  The Storage acceptance tests interact with the live service API. Follow the
122
- instructions in the {file:AUTHENTICATION.md Authentication guide} for enabling
122
+ instructions in the {file:AUTHENTICATION.md Authentication Guide} for enabling
123
123
  the Storage API. Occasionally, some API features may not yet be generally
124
124
  available, making it difficult for some contributors to successfully run the
125
125
  entire acceptance test suite. However, please ensure that you do successfully
126
126
  run acceptance tests for any code areas covered by your pull request.
127
127
 
128
128
  To run the acceptance tests, first create and configure a project in the Google
129
- Developers Console, as described in the {file:AUTHENTICATION.md Authentication
130
- guide}. Be sure to download the JSON KEY file. Make note of the PROJECT_ID and
129
+ Developers Console, as described in the {file:AUTHENTICATION.md Authentication Guide}. Be sure to download the JSON KEY file. Make note of the PROJECT_ID and
131
130
  the KEYFILE location on your system.
132
131
 
133
132
  Before you can run the Storage acceptance tests, you must first create indexes
@@ -309,12 +309,15 @@ module Google
309
309
  # @see https://cloud.google.com/storage/docs/access-logs Access Logs
310
310
  #
311
311
  def logging_bucket
312
- @gapi.logging.log_bucket if @gapi.logging
312
+ @gapi.logging&.log_bucket
313
313
  end
314
314
 
315
315
  ##
316
316
  # Updates the destination bucket for the bucket's logs.
317
317
  #
318
+ # To pass metageneration preconditions, call this method within a
319
+ # block passed to {#update}.
320
+ #
318
321
  # @see https://cloud.google.com/storage/docs/access-logs Access Logs
319
322
  #
320
323
  # @param [String] logging_bucket The bucket to hold the logging output
@@ -333,7 +336,7 @@ module Google
333
336
  # @return [String]
334
337
  #
335
338
  def logging_prefix
336
- @gapi.logging.log_object_prefix if @gapi.logging
339
+ @gapi.logging&.log_object_prefix
337
340
  end
338
341
 
339
342
  ##
@@ -344,6 +347,9 @@ module Google
344
347
  # By default, the object prefix is the name of the bucket for which the
345
348
  # logs are enabled.
346
349
  #
350
+ # To pass metageneration preconditions, call this method within a
351
+ # block passed to {#update}.
352
+ #
347
353
  # @see https://cloud.google.com/storage/docs/access-logs Access Logs
348
354
  #
349
355
  # @param [String] logging_prefix The logging object prefix.
@@ -377,6 +383,9 @@ module Google
377
383
  # For more information, see [Storage
378
384
  # Classes](https://cloud.google.com/storage/docs/storage-classes).
379
385
  #
386
+ # To pass metageneration preconditions, call this method within a
387
+ # block passed to {#update}.
388
+ #
380
389
  # @param [Symbol, String] new_storage_class Storage class of the bucket.
381
390
  #
382
391
  def storage_class= new_storage_class
@@ -392,7 +401,7 @@ module Google
392
401
  # @return [Boolean]
393
402
  #
394
403
  def versioning?
395
- @gapi.versioning.enabled? unless @gapi.versioning.nil?
404
+ @gapi.versioning&.enabled?
396
405
  end
397
406
 
398
407
  ##
@@ -400,6 +409,9 @@ module Google
400
409
  # Versioning](https://cloud.google.com/storage/docs/object-versioning)
401
410
  # is enabled for the bucket.
402
411
  #
412
+ # To pass metageneration preconditions, call this method within a
413
+ # block passed to {#update}.
414
+ #
403
415
  # @param [Boolean] new_versioning true if versioning is to be enabled
404
416
  # for the bucket.
405
417
  #
@@ -422,12 +434,15 @@ module Google
422
434
  # @return [String] The main page suffix.
423
435
  #
424
436
  def website_main
425
- @gapi.website.main_page_suffix if @gapi.website
437
+ @gapi.website&.main_page_suffix
426
438
  end
427
439
 
428
440
  ##
429
441
  # Updates the main page suffix for a static website.
430
442
  #
443
+ # To pass metageneration preconditions, call this method within a
444
+ # block passed to {#update}.
445
+ #
431
446
  # @see https://cloud.google.com/storage/docs/website-configuration#step4
432
447
  # How to Host a Static Website
433
448
  #
@@ -449,7 +464,7 @@ module Google
449
464
  # @return [String]
450
465
  #
451
466
  def website_404
452
- @gapi.website.not_found_page if @gapi.website
467
+ @gapi.website&.not_found_page
453
468
  end
454
469
 
455
470
  ##
@@ -467,6 +482,9 @@ module Google
467
482
  ##
468
483
  # Updates the hash of user-provided labels.
469
484
  #
485
+ # To pass metageneration preconditions, call this method within a
486
+ # block passed to {#update}.
487
+ #
470
488
  # @param [Hash(String => String)] labels The user-provided labels.
471
489
  #
472
490
  def labels= labels
@@ -478,6 +496,9 @@ module Google
478
496
  # Updates the page returned from a static website served from the bucket
479
497
  # when a site visitor requests a resource that does not exist.
480
498
  #
499
+ # To pass metageneration preconditions, call this method within a
500
+ # block passed to {#update}.
501
+ #
481
502
  # @see https://cloud.google.com/storage/docs/website-configuration#step4
482
503
  # How to Host a Static Website
483
504
  #
@@ -498,7 +519,7 @@ module Google
498
519
  # the bucket.
499
520
  #
500
521
  def requester_pays
501
- @gapi.billing.requester_pays if @gapi.billing
522
+ @gapi.billing&.requester_pays
502
523
  end
503
524
  alias requester_pays? requester_pays
504
525
 
@@ -509,6 +530,9 @@ module Google
509
530
  # {Project#bucket} and {Project#buckets} to indicate the project to
510
531
  # which the access costs should be billed.
511
532
  #
533
+ # To pass metageneration preconditions, call this method within a
534
+ # block passed to {#update}.
535
+ #
512
536
  # @param [Boolean] new_requester_pays When set to `true`, requester pays
513
537
  # is enabled for the bucket.
514
538
  #
@@ -550,13 +574,16 @@ module Google
550
574
  # bucket.default_kms_key #=> kms_key_name
551
575
  #
552
576
  def default_kms_key
553
- @gapi.encryption && @gapi.encryption.default_kms_key_name
577
+ @gapi.encryption&.default_kms_key_name
554
578
  end
555
579
 
556
580
  ##
557
581
  # Set the Cloud KMS encryption key that will be used to protect files.
558
582
  # For example: `projects/a/locations/b/keyRings/c/cryptoKeys/d`
559
583
  #
584
+ # To pass metageneration preconditions, call this method within a
585
+ # block passed to {#update}.
586
+ #
560
587
  # @param [String, nil] new_default_kms_key New Cloud KMS key name, or
561
588
  # `nil` to delete the Cloud KMS encryption key.
562
589
  #
@@ -599,7 +626,7 @@ module Google
599
626
  # retention policy exists for the bucket.
600
627
  #
601
628
  def retention_period
602
- @gapi.retention_policy && @gapi.retention_policy.retention_period
629
+ @gapi.retention_policy&.retention_period
603
630
  end
604
631
 
605
632
  ##
@@ -617,6 +644,9 @@ module Google
617
644
  # See also: {#lock_retention_policy!}, {#retention_period},
618
645
  # {#retention_effective_at}, and {#retention_policy_locked?}.
619
646
  #
647
+ # To pass metageneration preconditions, call this method within a
648
+ # block passed to {#update}.
649
+ #
620
650
  # @param [Integer, nil] new_retention_period The retention period
621
651
  # defined in seconds. The value must be between 0 and 100 years (in
622
652
  # seconds), or `nil`.
@@ -658,7 +688,7 @@ module Google
658
688
  # policy, if a policy exists.
659
689
  #
660
690
  def retention_effective_at
661
- @gapi.retention_policy && @gapi.retention_policy.effective_time
691
+ @gapi.retention_policy&.effective_time
662
692
  end
663
693
 
664
694
  ##
@@ -715,6 +745,9 @@ module Google
715
745
  #
716
746
  # See {File#event_based_hold?} and {File#set_event_based_hold!}.
717
747
  #
748
+ # To pass metageneration preconditions, call this method within a
749
+ # block passed to {#update}.
750
+ #
718
751
  # @param [Boolean] new_default_event_based_hold The default event-based
719
752
  # hold field for the bucket.
720
753
  #
@@ -808,7 +841,7 @@ module Google
808
841
  # bucket.uniform_bucket_level_access? # true
809
842
  #
810
843
  def uniform_bucket_level_access?
811
- return false unless @gapi.iam_configuration && @gapi.iam_configuration.uniform_bucket_level_access
844
+ return false unless @gapi.iam_configuration&.uniform_bucket_level_access
812
845
  !@gapi.iam_configuration.uniform_bucket_level_access.enabled.nil? &&
813
846
  @gapi.iam_configuration.uniform_bucket_level_access.enabled
814
847
  end
@@ -823,6 +856,9 @@ module Google
823
856
  # Before enabling uniform bucket-level access please review [uniform bucket-level
824
857
  # access](https://cloud.google.com/storage/docs/uniform-bucket-level-access).
825
858
  #
859
+ # To pass metageneration preconditions, call this method within a
860
+ # block passed to {#update}.
861
+ #
826
862
  # @param [Boolean] new_uniform_bucket_level_access When set to `true`, uniform bucket-level access is enabled in
827
863
  # the bucket's IAM configuration.
828
864
  #
@@ -870,7 +906,7 @@ module Google
870
906
  # puts bucket.uniform_bucket_level_access_locked_at
871
907
  #
872
908
  def uniform_bucket_level_access_locked_at
873
- return nil unless @gapi.iam_configuration && @gapi.iam_configuration.uniform_bucket_level_access
909
+ return nil unless @gapi.iam_configuration&.uniform_bucket_level_access
874
910
  @gapi.iam_configuration.uniform_bucket_level_access.locked_time
875
911
  end
876
912
 
@@ -895,6 +931,108 @@ module Google
895
931
  uniform_bucket_level_access_locked_at
896
932
  end
897
933
 
934
+ ##
935
+ # The value for Public Access Prevention in the bucket's IAM configuration. Currently, `unspecified` and
936
+ # `enforced` are supported. When set to `enforced`, Public Access Prevention is enforced in the bucket's IAM
937
+ # configuration. This value can be modified by calling {#public_access_prevention=}.
938
+ #
939
+ # @return [String, nil] Currently, `unspecified` and `enforced` are supported. Returns `nil` if the bucket has
940
+ # no IAM configuration.
941
+ #
942
+ # @example
943
+ # require "google/cloud/storage"
944
+ #
945
+ # storage = Google::Cloud::Storage.new
946
+ #
947
+ # bucket = storage.bucket "my-bucket"
948
+ #
949
+ # bucket.public_access_prevention = :enforced
950
+ # bucket.public_access_prevention #=> "enforced"
951
+ #
952
+ def public_access_prevention
953
+ @gapi.iam_configuration&.public_access_prevention
954
+ end
955
+
956
+ ##
957
+ # Sets the value for Public Access Prevention in the bucket's IAM configuration. This value can be queried by
958
+ # calling {#public_access_prevention}.
959
+ #
960
+ # @param [Symbol, String] new_public_access_prevention The bucket's new Public Access Prevention configuration.
961
+ # Currently, `unspecified` and `enforced` are supported. When set to `enforced`, Public Access
962
+ # Prevention is enforced in the bucket's IAM configuration.
963
+ #
964
+ # @example Set Public Access Prevention to enforced:
965
+ # require "google/cloud/storage"
966
+ #
967
+ # storage = Google::Cloud::Storage.new
968
+ #
969
+ # bucket = storage.bucket "my-bucket"
970
+ #
971
+ # bucket.public_access_prevention = :enforced
972
+ # bucket.public_access_prevention #=> "enforced"
973
+ #
974
+ # @example Set Public Access Prevention to unspecified:
975
+ # require "google/cloud/storage"
976
+ #
977
+ # storage = Google::Cloud::Storage.new
978
+ #
979
+ # bucket = storage.bucket "my-bucket"
980
+ #
981
+ # bucket.public_access_prevention = :unspecified
982
+ # bucket.public_access_prevention #=> "unspecified"
983
+ #
984
+ def public_access_prevention= new_public_access_prevention
985
+ @gapi.iam_configuration ||= API::Bucket::IamConfiguration.new
986
+ @gapi.iam_configuration.public_access_prevention = new_public_access_prevention.to_s
987
+ patch_gapi! :iam_configuration
988
+ end
989
+
990
+ ##
991
+ # Whether the bucket's file IAM configuration enforces Public Access Prevention. The default is `false`. This
992
+ # value can be modified by calling {Bucket#public_access_prevention=}.
993
+ #
994
+ # @return [Boolean] Returns `false` if the bucket has no IAM configuration or if Public Access Prevention is
995
+ # not `enforced` in the IAM configuration. Returns `true` if Public Access Prevention is `enforced` in the IAM
996
+ # configuration.
997
+ #
998
+ # @example
999
+ # require "google/cloud/storage"
1000
+ #
1001
+ # storage = Google::Cloud::Storage.new
1002
+ #
1003
+ # bucket = storage.bucket "my-bucket"
1004
+ #
1005
+ # bucket.public_access_prevention = :enforced
1006
+ # bucket.public_access_prevention_enforced? # true
1007
+ #
1008
+ def public_access_prevention_enforced?
1009
+ return false unless @gapi.iam_configuration&.public_access_prevention
1010
+ @gapi.iam_configuration.public_access_prevention.to_s == "enforced"
1011
+ end
1012
+
1013
+ ##
1014
+ # Whether the value for Public Access Prevention in the bucket's IAM configuration is `unspecified`. The default
1015
+ # is `false`. This value can be modified by calling {Bucket#public_access_prevention=}.
1016
+ #
1017
+ # @return [Boolean] Returns `false` if the bucket has no IAM configuration or if Public Access Prevention is
1018
+ # not `unspecified` in the IAM configuration. Returns `true` if Public Access Prevention is `unspecified` in
1019
+ # the IAM configuration.
1020
+ #
1021
+ # @example
1022
+ # require "google/cloud/storage"
1023
+ #
1024
+ # storage = Google::Cloud::Storage.new
1025
+ #
1026
+ # bucket = storage.bucket "my-bucket"
1027
+ #
1028
+ # bucket.public_access_prevention = :unspecified
1029
+ # bucket.public_access_prevention_unspecified? # true
1030
+ #
1031
+ def public_access_prevention_unspecified?
1032
+ return false unless @gapi.iam_configuration&.public_access_prevention
1033
+ @gapi.iam_configuration.public_access_prevention.to_s == "unspecified"
1034
+ end
1035
+
898
1036
  ##
899
1037
  # Updates the bucket with changes made in the given block in a single
900
1038
  # PATCH request. The following attributes may be set: {#cors},
@@ -905,6 +1043,12 @@ module Google
905
1043
  # completely mutable and will be included in the request. (See
906
1044
  # {Bucket::Cors})
907
1045
  #
1046
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1047
+ # on whether the bucket's current metageneration matches the given value.
1048
+ # @param [Integer] if_metageneration_not_match Makes the operation
1049
+ # conditional on whether the bucket's current metageneration does not
1050
+ # match the given value.
1051
+ #
908
1052
  # @yield [bucket] a block yielding a delegate object for updating the
909
1053
  # file
910
1054
  #
@@ -936,14 +1080,27 @@ module Google
936
1080
  # end
937
1081
  # end
938
1082
  #
939
- def update
1083
+ # @example With a `if_metageneration_match` precondition:
1084
+ # require "google/cloud/storage"
1085
+ #
1086
+ # storage = Google::Cloud::Storage.new
1087
+ #
1088
+ # bucket = storage.bucket "my-todo-app"
1089
+ # bucket.update if_metageneration_match: 6 do |b|
1090
+ # b.website_main = "index.html"
1091
+ # end
1092
+ #
1093
+ def update if_metageneration_match: nil, if_metageneration_not_match: nil
940
1094
  updater = Updater.new @gapi
941
1095
  yield updater
942
1096
  # Add check for mutable cors
943
1097
  updater.check_for_changed_labels!
944
1098
  updater.check_for_mutable_cors!
945
1099
  updater.check_for_mutable_lifecycle!
946
- patch_gapi! updater.updates unless updater.updates.empty?
1100
+ return if updater.updates.empty?
1101
+ patch_gapi! updater.updates,
1102
+ if_metageneration_match: if_metageneration_match,
1103
+ if_metageneration_not_match: if_metageneration_not_match
947
1104
  end
948
1105
 
949
1106
  ##
@@ -953,6 +1110,12 @@ module Google
953
1110
  # The API call to delete the bucket may be retried under certain
954
1111
  # conditions. See {Google::Cloud#storage} to control this behavior.
955
1112
  #
1113
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1114
+ # on whether the bucket's current metageneration matches the given value.
1115
+ # @param [Integer] if_metageneration_not_match Makes the operation
1116
+ # conditional on whether the bucket's current metageneration does not
1117
+ # match the given value.
1118
+ #
956
1119
  # @return [Boolean] Returns `true` if the bucket was deleted.
957
1120
  #
958
1121
  # @example
@@ -963,10 +1126,12 @@ module Google
963
1126
  # bucket = storage.bucket "my-bucket"
964
1127
  # bucket.delete
965
1128
  #
966
- def delete
1129
+ def delete if_metageneration_match: nil, if_metageneration_not_match: nil
967
1130
  ensure_service!
968
- service.delete_bucket name, user_project: user_project
969
- true
1131
+ service.delete_bucket name,
1132
+ if_metageneration_match: if_metageneration_match,
1133
+ if_metageneration_not_match: if_metageneration_not_match,
1134
+ user_project: user_project
970
1135
  end
971
1136
 
972
1137
  ##
@@ -1040,6 +1205,19 @@ module Google
1040
1205
  # @param [String] path Name (path) of the file.
1041
1206
  # @param [Integer] generation When present, selects a specific revision
1042
1207
  # of this object. Default is the latest version.
1208
+ # @param [Integer] if_generation_match Makes the operation conditional
1209
+ # on whether the file's current generation matches the given value.
1210
+ # Setting to 0 makes the operation succeed only if there are no live
1211
+ # versions of the file.
1212
+ # @param [Integer] if_generation_not_match Makes the operation conditional
1213
+ # on whether the file's current generation does not match the given
1214
+ # value. If no live file exists, the precondition fails. Setting to 0
1215
+ # makes the operation succeed only if there is a live version of the file.
1216
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1217
+ # on whether the file's current metageneration matches the given value.
1218
+ # @param [Integer] if_metageneration_not_match Makes the operation
1219
+ # conditional on whether the file's current metageneration does not
1220
+ # match the given value.
1043
1221
  # @param [Boolean] skip_lookup Optionally create a Bucket object
1044
1222
  # without verifying the bucket resource exists on the Storage service.
1045
1223
  # Calls made on this object will raise errors if the bucket resource
@@ -1061,7 +1239,14 @@ module Google
1061
1239
  # file = bucket.file "path/to/my-file.ext"
1062
1240
  # puts file.name
1063
1241
  #
1064
- def file path, generation: nil, skip_lookup: nil, encryption_key: nil
1242
+ def file path,
1243
+ generation: nil,
1244
+ if_generation_match: nil,
1245
+ if_generation_not_match: nil,
1246
+ if_metageneration_match: nil,
1247
+ if_metageneration_not_match: nil,
1248
+ skip_lookup: nil,
1249
+ encryption_key: nil
1065
1250
  ensure_service!
1066
1251
  if skip_lookup
1067
1252
  return File.new_lazy name, path, service,
@@ -1069,6 +1254,10 @@ module Google
1069
1254
  user_project: user_project
1070
1255
  end
1071
1256
  gapi = service.get_file name, path, generation: generation,
1257
+ if_generation_match: if_generation_match,
1258
+ if_generation_not_match: if_generation_not_match,
1259
+ if_metageneration_match: if_metageneration_match,
1260
+ if_metageneration_not_match: if_metageneration_not_match,
1072
1261
  key: encryption_key,
1073
1262
  user_project: user_project
1074
1263
  File.from_gapi gapi, service, user_project: user_project
@@ -1143,16 +1332,34 @@ module Google
1143
1332
  # changed to a time in the future. If custom_time must be unset, you
1144
1333
  # must either perform a rewrite operation, or upload the data again
1145
1334
  # and create a new file.
1335
+ # @param [Symbol, nil] checksum The type of checksum for the client to
1336
+ # automatically calculate and send with the create request to verify
1337
+ # the integrity of the object. If provided, Cloud Storage will only
1338
+ # create the file if the value calculated by the client matches the
1339
+ # value calculated by the service.
1340
+ #
1341
+ # Acceptable values are:
1342
+ #
1343
+ # * `md5` - Calculate and provide a checksum using the MD5 hash.
1344
+ # * `crc32c` - Calculate and provide a checksum using the CRC32c hash.
1345
+ # * `all` - Calculate and provide checksums for all available verifications.
1346
+ #
1347
+ # Optional. The default is `nil`. Do not provide if also providing a
1348
+ # corresponding `crc32c` or `md5` argument. See
1349
+ # [Validation](https://cloud.google.com/storage/docs/hashes-etags)
1350
+ # for more information.
1146
1351
  # @param [String] crc32c The CRC32c checksum of the file data, as
1147
1352
  # described in [RFC 4960, Appendix
1148
1353
  # B](http://tools.ietf.org/html/rfc4960#appendix-B).
1149
1354
  # If provided, Cloud Storage will only create the file if the value
1150
- # matches the value calculated by the service. See
1355
+ # matches the value calculated by the service. Do not provide if also
1356
+ # providing a `checksum: :crc32c` or `checksum: :all` argument. See
1151
1357
  # [Validation](https://cloud.google.com/storage/docs/hashes-etags)
1152
1358
  # for more information.
1153
1359
  # @param [String] md5 The MD5 hash of the file data. If provided, Cloud
1154
1360
  # Storage will only create the file if the value matches the value
1155
- # calculated by the service. See
1361
+ # calculated by the service. Do not provide if also providing a
1362
+ # `checksum: :md5` or `checksum: :all` argument. See
1156
1363
  # [Validation](https://cloud.google.com/storage/docs/hashes-etags) for
1157
1364
  # more information.
1158
1365
  # @param [Hash] metadata A hash of custom, user-provided web-safe keys
@@ -1179,6 +1386,19 @@ module Google
1179
1386
  # the same location as the bucket.The Service Account associated with
1180
1387
  # your project requires access to this encryption key. Do not provide
1181
1388
  # if `encryption_key` is used.
1389
+ # @param [Integer] if_generation_match Makes the operation conditional
1390
+ # on whether the file's current generation matches the given value.
1391
+ # Setting to 0 makes the operation succeed only if there are no live
1392
+ # versions of the file.
1393
+ # @param [Integer] if_generation_not_match Makes the operation conditional
1394
+ # on whether the file's current generation does not match the given
1395
+ # value. If no live file exists, the precondition fails. Setting to 0
1396
+ # makes the operation succeed only if there is a live version of the file.
1397
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1398
+ # on whether the file's current metageneration matches the given value.
1399
+ # @param [Integer] if_metageneration_not_match Makes the operation
1400
+ # conditional on whether the file's current metageneration does not
1401
+ # match the given value.
1182
1402
  #
1183
1403
  # @return [Google::Cloud::Storage::File]
1184
1404
  #
@@ -1262,35 +1482,59 @@ module Google
1262
1482
  # file.download "path/to/downloaded/gzipped.txt",
1263
1483
  # skip_decompress: true
1264
1484
  #
1265
- def create_file file, path = nil, acl: nil, cache_control: nil,
1266
- content_disposition: nil, content_encoding: nil,
1267
- content_language: nil, content_type: nil, custom_time: nil,
1268
- crc32c: nil, md5: nil, metadata: nil,
1269
- storage_class: nil, encryption_key: nil, kms_key: nil,
1270
- temporary_hold: nil, event_based_hold: nil
1485
+ def create_file file,
1486
+ path = nil,
1487
+ acl: nil,
1488
+ cache_control: nil,
1489
+ content_disposition: nil,
1490
+ content_encoding: nil,
1491
+ content_language: nil,
1492
+ content_type: nil,
1493
+ custom_time: nil,
1494
+ checksum: nil,
1495
+ crc32c: nil,
1496
+ md5: nil,
1497
+ metadata: nil,
1498
+ storage_class: nil,
1499
+ encryption_key: nil,
1500
+ kms_key: nil,
1501
+ temporary_hold: nil,
1502
+ event_based_hold: nil,
1503
+ if_generation_match: nil,
1504
+ if_generation_not_match: nil,
1505
+ if_metageneration_match: nil,
1506
+ if_metageneration_not_match: nil
1271
1507
  ensure_service!
1272
1508
  ensure_io_or_file_exists! file
1273
1509
  path ||= file.path if file.respond_to? :path
1274
1510
  path ||= file if file.is_a? String
1275
1511
  raise ArgumentError, "must provide path" if path.nil?
1276
-
1277
-
1278
- gapi = service.insert_file name, file, path, acl: File::Acl.predefined_rule_for(acl),
1279
- md5: md5,
1280
- cache_control: cache_control,
1281
- content_type: content_type,
1282
- custom_time: custom_time,
1283
- content_disposition: content_disposition,
1284
- crc32c: crc32c,
1285
- content_encoding: content_encoding,
1286
- metadata: metadata,
1287
- content_language: content_language,
1288
- key: encryption_key,
1289
- kms_key: kms_key,
1290
- storage_class: storage_class_for(storage_class),
1291
- temporary_hold: temporary_hold,
1292
- event_based_hold: event_based_hold,
1293
- user_project: user_project
1512
+ crc32c = crc32c_for file, checksum, crc32c
1513
+ md5 = md5_for file, checksum, md5
1514
+
1515
+ gapi = service.insert_file name,
1516
+ file,
1517
+ path,
1518
+ acl: File::Acl.predefined_rule_for(acl),
1519
+ md5: md5,
1520
+ cache_control: cache_control,
1521
+ content_type: content_type,
1522
+ custom_time: custom_time,
1523
+ content_disposition: content_disposition,
1524
+ crc32c: crc32c,
1525
+ content_encoding: content_encoding,
1526
+ metadata: metadata,
1527
+ content_language: content_language,
1528
+ key: encryption_key,
1529
+ kms_key: kms_key,
1530
+ storage_class: storage_class_for(storage_class),
1531
+ temporary_hold: temporary_hold,
1532
+ event_based_hold: event_based_hold,
1533
+ if_generation_match: if_generation_match,
1534
+ if_generation_not_match: if_generation_not_match,
1535
+ if_metageneration_match: if_metageneration_match,
1536
+ if_metageneration_not_match: if_metageneration_not_match,
1537
+ user_project: user_project
1294
1538
  File.from_gapi gapi, service, user_project: user_project
1295
1539
  end
1296
1540
  alias upload_file create_file
@@ -1334,6 +1578,16 @@ module Google
1334
1578
  # used. All source files must have been encrypted with the same key,
1335
1579
  # and the resulting destination file will also be encrypted with the
1336
1580
  # key.
1581
+ # @param [Array<Integer>] if_source_generation_match Makes the operation
1582
+ # conditional on whether the source files' current generations match the
1583
+ # given values. The list must match `sources` item-to-item.
1584
+ # @param [Integer] if_generation_match Makes the operation conditional
1585
+ # on whether the destination file's current generation matches the
1586
+ # given value. Setting to 0 makes the operation succeed only if there
1587
+ # are no live versions of the file.
1588
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1589
+ # on whether the destination file's current metageneration matches the
1590
+ # given value.
1337
1591
  #
1338
1592
  # @yield [file] A block yielding a delegate file object for setting the
1339
1593
  # properties of the destination file.
@@ -1382,7 +1636,13 @@ module Google
1382
1636
  #
1383
1637
  # new_file = bucket.compose [file_1, file_2], "path/to/new-file.ext"
1384
1638
  #
1385
- def compose sources, destination, acl: nil, encryption_key: nil
1639
+ def compose sources,
1640
+ destination,
1641
+ acl: nil,
1642
+ encryption_key: nil,
1643
+ if_source_generation_match: nil,
1644
+ if_generation_match: nil,
1645
+ if_metageneration_match: nil
1386
1646
  ensure_service!
1387
1647
  sources = Array sources
1388
1648
  if sources.size < 2
@@ -1398,9 +1658,16 @@ module Google
1398
1658
  end
1399
1659
 
1400
1660
  acl_rule = File::Acl.predefined_rule_for acl
1401
- gapi = service.compose_file name, sources, destination, destination_gapi, acl: acl_rule,
1402
- key: encryption_key,
1403
- user_project: user_project
1661
+ gapi = service.compose_file name,
1662
+ sources,
1663
+ destination,
1664
+ destination_gapi,
1665
+ acl: acl_rule,
1666
+ key: encryption_key,
1667
+ if_source_generation_match: if_source_generation_match,
1668
+ if_generation_match: if_generation_match,
1669
+ if_metageneration_match: if_metageneration_match,
1670
+ user_project: user_project
1404
1671
  File.from_gapi gapi, service, user_project: user_project
1405
1672
  end
1406
1673
  alias compose_file compose
@@ -1545,11 +1812,11 @@ module Google
1545
1812
  # scopes = ["https://www.googleapis.com/auth/iam"]
1546
1813
  # iam_client.authorization = Google::Auth.get_application_default scopes
1547
1814
  #
1548
- # request = {
1549
- # "payload": string_to_sign,
1550
- # }
1815
+ # request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
1816
+ # payload: string_to_sign
1817
+ # )
1551
1818
  # resource = "projects/-/serviceAccounts/#{issuer}"
1552
- # response = iam_client.sign_service_account_blob resource, request, {}
1819
+ # response = iam_client.sign_service_account_blob resource, request
1553
1820
  # response.signed_blob
1554
1821
  # end
1555
1822
  #
@@ -1778,11 +2045,11 @@ module Google
1778
2045
  # scopes = ["https://www.googleapis.com/auth/iam"]
1779
2046
  # iam_client.authorization = Google::Auth.get_application_default scopes
1780
2047
  #
1781
- # request = {
1782
- # "payload": string_to_sign,
1783
- # }
2048
+ # request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
2049
+ # payload: string_to_sign
2050
+ # )
1784
2051
  # resource = "projects/-/serviceAccounts/#{issuer}"
1785
- # response = iam_client.sign_service_account_blob resource, request, {}
2052
+ # response = iam_client.sign_service_account_blob resource, request
1786
2053
  # response.signed_blob
1787
2054
  # end
1788
2055
  #
@@ -1928,11 +2195,11 @@ module Google
1928
2195
  # scopes = ["https://www.googleapis.com/auth/iam"]
1929
2196
  # iam_client.authorization = Google::Auth.get_application_default scopes
1930
2197
  #
1931
- # request = {
1932
- # "payload": string_to_sign,
1933
- # }
2198
+ # request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
2199
+ # payload: string_to_sign
2200
+ # )
1934
2201
  # resource = "projects/-/serviceAccounts/#{issuer}"
1935
- # response = iam_client.sign_service_account_blob resource, request, {}
2202
+ # response = iam_client.sign_service_account_blob resource, request
1936
2203
  # response.signed_blob
1937
2204
  # end
1938
2205
  #
@@ -2546,7 +2813,10 @@ module Google
2546
2813
  reload!
2547
2814
  end
2548
2815
 
2549
- def patch_gapi! *attributes
2816
+ def patch_gapi! attributes,
2817
+ if_metageneration_match: nil,
2818
+ if_metageneration_not_match: nil
2819
+ attributes = Array(attributes)
2550
2820
  attributes.flatten!
2551
2821
  return if attributes.empty?
2552
2822
  ensure_service!
@@ -2554,7 +2824,10 @@ module Google
2554
2824
  [attr, @gapi.send(attr)]
2555
2825
  end]
2556
2826
  patch_gapi = API::Bucket.new(**patch_args)
2557
- @gapi = service.patch_bucket name, patch_gapi,
2827
+ @gapi = service.patch_bucket name,
2828
+ patch_gapi,
2829
+ if_metageneration_match: if_metageneration_match,
2830
+ if_metageneration_not_match: if_metageneration_not_match,
2558
2831
  user_project: user_project
2559
2832
  @lazy = nil
2560
2833
  self
@@ -2568,13 +2841,27 @@ module Google
2568
2841
  raise ArgumentError, "cannot find file #{file}"
2569
2842
  end
2570
2843
 
2844
+ def crc32c_for source, checksum, crc32c
2845
+ return crc32c unless [:crc32c, :all].include? checksum
2846
+ raise ArgumentError, "'checksum: :crc32c' or 'checksum: :all' is present with 'crc32c' arg" if crc32c
2847
+ File::Verifier.crc32c_for source
2848
+ end
2849
+
2850
+ def md5_for source, checksum, md5
2851
+ return md5 unless [:md5, :all].include? checksum
2852
+ raise ArgumentError, "'checksum: :md5' or 'checksum: :all' is present with 'md5' arg" if md5
2853
+ File::Verifier.md5_for source
2854
+ end
2855
+
2571
2856
  ##
2572
2857
  # Yielded to a block to accumulate changes for a patch request.
2573
2858
  class Updater < Bucket
2574
2859
  attr_reader :updates
2860
+
2575
2861
  ##
2576
2862
  # Create an Updater object.
2577
2863
  def initialize gapi
2864
+ super()
2578
2865
  @updates = []
2579
2866
  @gapi = gapi
2580
2867
  @labels = @gapi.labels.to_h.dup