google-cloud-storage 1.45.0 → 1.56.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +79 -0
- data/lib/google/cloud/storage/bucket/cors.rb +2 -2
- data/lib/google/cloud/storage/bucket/list.rb +4 -2
- data/lib/google/cloud/storage/bucket.rb +295 -10
- data/lib/google/cloud/storage/file/list.rb +10 -3
- data/lib/google/cloud/storage/file/signer_v2.rb +5 -4
- data/lib/google/cloud/storage/file/signer_v4.rb +5 -5
- data/lib/google/cloud/storage/file.rb +141 -10
- data/lib/google/cloud/storage/project.rb +86 -9
- data/lib/google/cloud/storage/service.rb +120 -14
- data/lib/google/cloud/storage/version.rb +1 -1
- data/lib/google/cloud/storage.rb +15 -8
- data/lib/google-cloud-storage.rb +10 -12
- metadata +28 -23
@@ -763,6 +763,30 @@ module Google
|
|
763
763
|
@gapi.retention_expiration_time
|
764
764
|
end
|
765
765
|
|
766
|
+
##
|
767
|
+
# This soft delete time is the time when the object became
|
768
|
+
# soft-deleted.
|
769
|
+
#
|
770
|
+
# @return [DateTime, nil] A DateTime representing the time at
|
771
|
+
# which the object became soft-deleted, or `nil` if the file was
|
772
|
+
# not deleted.
|
773
|
+
#
|
774
|
+
def soft_delete_time
|
775
|
+
@gapi.soft_delete_time
|
776
|
+
end
|
777
|
+
|
778
|
+
##
|
779
|
+
# This hard delete time is The time when the file will be permanently
|
780
|
+
# deleted.
|
781
|
+
#
|
782
|
+
# @return [DateTime, nil] A DateTime representing the time at
|
783
|
+
# which the file will be permanently deleted, or `nil` if the file is
|
784
|
+
# not soft deleted.
|
785
|
+
#
|
786
|
+
def hard_delete_time
|
787
|
+
@gapi.hard_delete_time
|
788
|
+
end
|
789
|
+
|
766
790
|
##
|
767
791
|
# Retrieves a list of versioned files for the current object.
|
768
792
|
#
|
@@ -825,6 +849,9 @@ module Google
|
|
825
849
|
# @param [Integer] if_metageneration_not_match Makes the operation
|
826
850
|
# conditional on whether the file's current metageneration does not
|
827
851
|
# match the given value.
|
852
|
+
# @param [Boolean] override_unlocked_retention
|
853
|
+
# Must be true to remove the retention configuration, reduce its unlocked
|
854
|
+
# retention period, or change its mode from unlocked to locked.
|
828
855
|
#
|
829
856
|
# @yield [file] a block yielding a delegate object for updating the file
|
830
857
|
#
|
@@ -865,7 +892,8 @@ module Google
|
|
865
892
|
if_generation_match: nil,
|
866
893
|
if_generation_not_match: nil,
|
867
894
|
if_metageneration_match: nil,
|
868
|
-
if_metageneration_not_match: nil
|
895
|
+
if_metageneration_not_match: nil,
|
896
|
+
override_unlocked_retention: nil
|
869
897
|
updater = Updater.new gapi
|
870
898
|
yield updater
|
871
899
|
updater.check_for_changed_metadata!
|
@@ -875,7 +903,8 @@ module Google
|
|
875
903
|
if_generation_match: if_generation_match,
|
876
904
|
if_generation_not_match: if_generation_not_match,
|
877
905
|
if_metageneration_match: if_metageneration_match,
|
878
|
-
if_metageneration_not_match: if_metageneration_not_match
|
906
|
+
if_metageneration_not_match: if_metageneration_not_match,
|
907
|
+
override_unlocked_retention: override_unlocked_retention
|
879
908
|
end
|
880
909
|
|
881
910
|
##
|
@@ -1560,6 +1589,64 @@ module Google
|
|
1560
1589
|
true
|
1561
1590
|
end
|
1562
1591
|
|
1592
|
+
# Mode of object level retention configuration.
|
1593
|
+
# Valid values are 'Locked' or 'Unlocked'
|
1594
|
+
#
|
1595
|
+
# @return [String]
|
1596
|
+
def retention_mode
|
1597
|
+
@gapi.retention&.mode
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
# The earliest time in RFC 3339 UTC "Zulu" format that the object can
|
1601
|
+
# be deleted or replaced.
|
1602
|
+
#
|
1603
|
+
# @return [DateTime]
|
1604
|
+
def retention_retain_until_time
|
1605
|
+
@gapi.retention&.retain_until_time
|
1606
|
+
end
|
1607
|
+
|
1608
|
+
# A collection of object level retention parameters.
|
1609
|
+
# The full list of available options are outlined at the [JSON API docs]
|
1610
|
+
# (https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body).
|
1611
|
+
#
|
1612
|
+
# @return [Google::Apis::StorageV1::Object::Retention]
|
1613
|
+
def retention
|
1614
|
+
@gapi.retention
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
##
|
1618
|
+
# Update method to update retention parameter of an object / file
|
1619
|
+
# It accepts params as a Hash of attributes in the following format:
|
1620
|
+
#
|
1621
|
+
# { mode: 'Locked|Unlocked', retain_until_time: '2023-12-19T03:22:23+00:00' }
|
1622
|
+
#
|
1623
|
+
# @param [Hash(String => String)] new_retention_attributes
|
1624
|
+
#
|
1625
|
+
# @example Update retention parameters for the File / Object
|
1626
|
+
# require "google/cloud/storage"
|
1627
|
+
# storage = Google::Cloud::Storage.new
|
1628
|
+
# bucket = storage.bucket "my-bucket"
|
1629
|
+
# file = bucket.file "avatars/heidi/400x400.png"
|
1630
|
+
# retention_params = { mode: 'Unlocked', retain_until_time: '2023-12-19T03:22:23+00:00'.to_datetime }
|
1631
|
+
# file.retention = retention_params
|
1632
|
+
#
|
1633
|
+
# @example Update retention parameters for the File / Object with override enabled
|
1634
|
+
# require "google/cloud/storage"
|
1635
|
+
# storage = Google::Cloud::Storage.new
|
1636
|
+
# bucket = storage.bucket "my-bucket"
|
1637
|
+
# file = bucket.file "avatars/heidi/400x400.png"
|
1638
|
+
# retention_params = { mode: 'Unlocked',
|
1639
|
+
# retain_until_time: '2023-12-19T03:22:23+00:00'.to_datetime,
|
1640
|
+
# override_unlocked_retention: true }
|
1641
|
+
# file.retention = retention_params
|
1642
|
+
#
|
1643
|
+
def retention= new_retention_attributes
|
1644
|
+
@gapi.retention ||= Google::Apis::StorageV1::Object::Retention.new
|
1645
|
+
@gapi.retention.mode = new_retention_attributes[:mode]
|
1646
|
+
@gapi.retention.retain_until_time = new_retention_attributes[:retain_until_time]
|
1647
|
+
update_gapi! :retention, override_unlocked_retention: new_retention_attributes[:override_unlocked_retention]
|
1648
|
+
end
|
1649
|
+
|
1563
1650
|
##
|
1564
1651
|
# Public URL to access the file. If the file is not public, requests to
|
1565
1652
|
# the URL will return an error. (See {File::Acl#public!} and
|
@@ -1985,15 +2072,59 @@ module Google
|
|
1985
2072
|
def self.gapi_from_attrs gapi, attributes
|
1986
2073
|
attributes.flatten!
|
1987
2074
|
return nil if attributes.empty?
|
1988
|
-
attr_params =
|
1989
|
-
|
1990
|
-
|
2075
|
+
attr_params = attributes.to_h do |attr|
|
2076
|
+
[attr, gapi.send(attr)]
|
2077
|
+
end
|
1991
2078
|
# Sending nil metadata results in an Apiary runtime error:
|
1992
2079
|
# NoMethodError: undefined method `each' for nil:NilClass
|
1993
2080
|
attr_params.reject! { |k, v| k == :metadata && v.nil? }
|
1994
2081
|
Google::Apis::StorageV1::Object.new(**attr_params)
|
1995
2082
|
end
|
1996
2083
|
|
2084
|
+
##
|
2085
|
+
# from_gs_url is a method to fetch bucket details and file details from a gs url
|
2086
|
+
#
|
2087
|
+
# @return [Hash(String => String)]
|
2088
|
+
#
|
2089
|
+
# @example Fetch bucket_name and file_Path from gs url:
|
2090
|
+
# require "google/cloud/storage"
|
2091
|
+
# gs_url= "gs://my-todo-app/avatars/heidi.jpeg"
|
2092
|
+
# file=Google::Cloud::Storage::File
|
2093
|
+
# file.from_gs_url(gs_url)
|
2094
|
+
# =>
|
2095
|
+
# {"bucket_name"=>"my-todo-app", "file_path"=>"avatars/heidi.jpeg"}
|
2096
|
+
#
|
2097
|
+
# @example Fetch bucket_name , file_Path and other query params from gs url:
|
2098
|
+
# require "google/cloud/storage"
|
2099
|
+
# gs_url= "gs://my-todo-app/test_sub_folder/heidi.jpeg?params1=test1¶ms2=test2"
|
2100
|
+
# file=Google::Cloud::Storage::File
|
2101
|
+
# file.from_gs_url(gs_url)
|
2102
|
+
# =>{
|
2103
|
+
# "bucket_name"=>"my-todo-app",
|
2104
|
+
# "file_path"=>"test_sub_folder/heidi.jpeg",
|
2105
|
+
# "options" => {
|
2106
|
+
# "params1"=>"test1",
|
2107
|
+
# "params2"=>"test2"
|
2108
|
+
# }
|
2109
|
+
# }
|
2110
|
+
|
2111
|
+
def self.from_gs_url gs_url
|
2112
|
+
prefix = "gs://".freeze
|
2113
|
+
raise ArgumentError, "Invalid GCS URL" unless gs_url.start_with? prefix
|
2114
|
+
# seprating params from input url
|
2115
|
+
path, query = gs_url.sub(prefix, "").split("?", 2)
|
2116
|
+
# parsing the url
|
2117
|
+
bucket_name, file_path = path.split "/", 2
|
2118
|
+
query_params = URI.decode_www_form(query).to_h if query
|
2119
|
+
url_items = {
|
2120
|
+
"bucket_name" => bucket_name,
|
2121
|
+
"file_path" => file_path
|
2122
|
+
}
|
2123
|
+
# adding url params to output hash
|
2124
|
+
url_items.merge! "options" => query_params if query
|
2125
|
+
url_items
|
2126
|
+
end
|
2127
|
+
|
1997
2128
|
protected
|
1998
2129
|
|
1999
2130
|
##
|
@@ -2015,7 +2146,8 @@ module Google
|
|
2015
2146
|
if_generation_match: nil,
|
2016
2147
|
if_generation_not_match: nil,
|
2017
2148
|
if_metageneration_match: nil,
|
2018
|
-
if_metageneration_not_match: nil
|
2149
|
+
if_metageneration_not_match: nil,
|
2150
|
+
override_unlocked_retention: nil
|
2019
2151
|
attributes = Array(attributes)
|
2020
2152
|
attributes.flatten!
|
2021
2153
|
return if attributes.empty?
|
@@ -2044,7 +2176,8 @@ module Google
|
|
2044
2176
|
if_generation_not_match: if_generation_not_match,
|
2045
2177
|
if_metageneration_match: if_metageneration_match,
|
2046
2178
|
if_metageneration_not_match: if_metageneration_not_match,
|
2047
|
-
user_project: user_project
|
2179
|
+
user_project: user_project,
|
2180
|
+
override_unlocked_retention: override_unlocked_retention
|
2048
2181
|
end
|
2049
2182
|
end
|
2050
2183
|
|
@@ -2107,10 +2240,8 @@ module Google
|
|
2107
2240
|
[dest_bucket, dest_path]
|
2108
2241
|
end
|
2109
2242
|
|
2110
|
-
# rubocop:disable Style/MultipleComparison
|
2111
|
-
|
2112
2243
|
def verify_file! file, verify = :md5
|
2113
|
-
verify_md5 = verify == :md5
|
2244
|
+
verify_md5 = verify == :md5 || verify == :all
|
2114
2245
|
verify_crc32c = verify == :crc32c || verify == :all
|
2115
2246
|
Verifier.verify_md5! self, file if verify_md5 && md5
|
2116
2247
|
Verifier.verify_crc32c! self, file if verify_crc32c && crc32c
|
@@ -62,6 +62,15 @@ module Google
|
|
62
62
|
@service = service
|
63
63
|
end
|
64
64
|
|
65
|
+
##
|
66
|
+
# The universe domain the client is connected to
|
67
|
+
#
|
68
|
+
# @return [String]
|
69
|
+
#
|
70
|
+
def universe_domain
|
71
|
+
service.universe_domain
|
72
|
+
end
|
73
|
+
|
65
74
|
##
|
66
75
|
# The Storage project connected to.
|
67
76
|
#
|
@@ -90,8 +99,7 @@ module Google
|
|
90
99
|
# @return [String] The service account email address.
|
91
100
|
#
|
92
101
|
def service_account_email
|
93
|
-
@service_account_email ||=
|
94
|
-
service.project_service_account.email_address
|
102
|
+
@service_account_email ||= service.project_service_account.email_address
|
95
103
|
end
|
96
104
|
|
97
105
|
##
|
@@ -184,11 +192,20 @@ module Google
|
|
184
192
|
# puts bucket.name
|
185
193
|
# end
|
186
194
|
#
|
187
|
-
|
195
|
+
# @example Retrieve soft deleted buckets
|
196
|
+
# require "google/cloud/storage"
|
197
|
+
#
|
198
|
+
# storage = Google::Cloud::Storage.new
|
199
|
+
#
|
200
|
+
# soft_deleted_buckets = storage.buckets soft_deleted: true
|
201
|
+
# soft_deleted_buckets.each do |bucket|
|
202
|
+
# puts bucket.name
|
203
|
+
# end
|
204
|
+
def buckets prefix: nil, token: nil, max: nil, user_project: nil, soft_deleted: nil
|
188
205
|
gapi = service.list_buckets \
|
189
|
-
prefix: prefix, token: token, max: max, user_project: user_project
|
206
|
+
prefix: prefix, token: token, max: max, user_project: user_project, soft_deleted: soft_deleted
|
190
207
|
Bucket::List.from_gapi \
|
191
|
-
gapi, service, prefix, max, user_project: user_project
|
208
|
+
gapi, service, prefix, max, user_project: user_project, soft_deleted: soft_deleted
|
192
209
|
end
|
193
210
|
alias find_buckets buckets
|
194
211
|
|
@@ -214,6 +231,10 @@ module Google
|
|
214
231
|
# account, transit costs will be billed to the given project. This
|
215
232
|
# parameter is required with requester pays-enabled buckets. The
|
216
233
|
# default is `nil`.
|
234
|
+
# @param [Integer] generation generation no of bucket
|
235
|
+
# on whether the bucket's current metageneration matches the given value.
|
236
|
+
# @param [Boolean] soft_deleted If true, returns the soft-deleted bucket.
|
237
|
+
# This parameter is required if generation is specified.
|
217
238
|
#
|
218
239
|
# The value provided will be applied to all operations on the returned
|
219
240
|
# bucket instance and its files.
|
@@ -247,9 +268,20 @@ module Google
|
|
247
268
|
# bucket = storage.bucket "other-project-bucket",
|
248
269
|
# user_project: "my-other-project"
|
249
270
|
# files = bucket.files # Billed to "my-other-project"
|
271
|
+
# @example With `soft_deleted` set to true and generation specified:
|
272
|
+
# require "google/cloud/storage"
|
273
|
+
#
|
274
|
+
# storage = Google::Cloud::Storage.new
|
275
|
+
#
|
276
|
+
# bucket = storage.bucket "my-bucket",
|
277
|
+
# soft_deleted: true,
|
278
|
+
# generation: 1234567889
|
279
|
+
# puts bucket.name
|
250
280
|
#
|
251
281
|
def bucket bucket_name,
|
252
282
|
skip_lookup: false,
|
283
|
+
generation: nil,
|
284
|
+
soft_deleted: nil,
|
253
285
|
if_metageneration_match: nil,
|
254
286
|
if_metageneration_not_match: nil,
|
255
287
|
user_project: nil
|
@@ -260,7 +292,10 @@ module Google
|
|
260
292
|
gapi = service.get_bucket bucket_name,
|
261
293
|
if_metageneration_match: if_metageneration_match,
|
262
294
|
if_metageneration_not_match: if_metageneration_not_match,
|
263
|
-
user_project: user_project
|
295
|
+
user_project: user_project,
|
296
|
+
soft_deleted: soft_deleted,
|
297
|
+
generation: generation
|
298
|
+
|
264
299
|
Bucket.from_gapi gapi, service, user_project: user_project
|
265
300
|
rescue Google::Cloud::NotFoundError
|
266
301
|
nil
|
@@ -372,6 +407,8 @@ module Google
|
|
372
407
|
# bucket instance and its files.
|
373
408
|
#
|
374
409
|
# See also {Bucket#requester_pays=} and {Bucket#requester_pays}.
|
410
|
+
# @param [Boolean] enable_object_retention
|
411
|
+
# When set to true, object retention is enabled for this bucket.
|
375
412
|
#
|
376
413
|
# @yield [bucket] a block for configuring the bucket before it is
|
377
414
|
# created
|
@@ -386,6 +423,13 @@ module Google
|
|
386
423
|
#
|
387
424
|
# bucket = storage.create_bucket "my-bucket"
|
388
425
|
#
|
426
|
+
# @example
|
427
|
+
# require "google/cloud/storage"
|
428
|
+
#
|
429
|
+
# storage = Google::Cloud::Storage.new
|
430
|
+
#
|
431
|
+
# bucket = storage.create_bucket "my-bucket", enable_object_retention: true
|
432
|
+
#
|
389
433
|
# @example Configure the bucket in a block:
|
390
434
|
# require "google/cloud/storage"
|
391
435
|
#
|
@@ -403,6 +447,7 @@ module Google
|
|
403
447
|
# b.lifecycle.add_set_storage_class_rule "COLDLINE", age: 10
|
404
448
|
# end
|
405
449
|
#
|
450
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
406
451
|
def create_bucket bucket_name,
|
407
452
|
acl: nil,
|
408
453
|
default_acl: nil,
|
@@ -416,11 +461,14 @@ module Google
|
|
416
461
|
versioning: nil,
|
417
462
|
requester_pays: nil,
|
418
463
|
user_project: nil,
|
419
|
-
autoclass_enabled: false
|
464
|
+
autoclass_enabled: false,
|
465
|
+
enable_object_retention: nil,
|
466
|
+
hierarchical_namespace: nil
|
420
467
|
params = {
|
421
468
|
name: bucket_name,
|
422
469
|
location: location,
|
423
|
-
custom_placement_config: custom_placement_config
|
470
|
+
custom_placement_config: custom_placement_config,
|
471
|
+
hierarchical_namespace: hierarchical_namespace
|
424
472
|
}.delete_if { |_, v| v.nil? }
|
425
473
|
new_bucket = Google::Apis::StorageV1::Bucket.new(**params)
|
426
474
|
storage_class = storage_class_for storage_class
|
@@ -433,6 +481,7 @@ module Google
|
|
433
481
|
b.website_404 = website_404 unless website_404.nil?
|
434
482
|
b.versioning = versioning unless versioning.nil?
|
435
483
|
b.requester_pays = requester_pays unless requester_pays.nil?
|
484
|
+
b.hierarchical_namespace = hierarchical_namespace unless hierarchical_namespace.nil?
|
436
485
|
end
|
437
486
|
yield updater if block_given?
|
438
487
|
updater.check_for_changed_labels!
|
@@ -440,9 +489,11 @@ module Google
|
|
440
489
|
updater.check_for_mutable_lifecycle!
|
441
490
|
gapi = service.insert_bucket \
|
442
491
|
new_bucket, acl: acl_rule(acl), default_acl: acl_rule(default_acl),
|
443
|
-
user_project: user_project
|
492
|
+
user_project: user_project,
|
493
|
+
enable_object_retention: enable_object_retention
|
444
494
|
Bucket.from_gapi gapi, service, user_project: user_project
|
445
495
|
end
|
496
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
446
497
|
|
447
498
|
##
|
448
499
|
# Creates a new HMAC key.
|
@@ -529,6 +580,32 @@ module Google
|
|
529
580
|
max: max, user_project: user_project
|
530
581
|
end
|
531
582
|
|
583
|
+
##
|
584
|
+
# Restores a soft deleted bucket with bucket name and generation.
|
585
|
+
#
|
586
|
+
# @param [String] bucket_name Name of the bucket.
|
587
|
+
# @param [Fixnum] generation Generation of the bucket.
|
588
|
+
#
|
589
|
+
# @return [Google::Cloud::Storage::Bucket, nil] Returns nil if bucket
|
590
|
+
# does not exist
|
591
|
+
#
|
592
|
+
# @example
|
593
|
+
# require "google/cloud/storage"
|
594
|
+
#
|
595
|
+
# storage = Google::Cloud::Storage.new
|
596
|
+
# generation= 123
|
597
|
+
#
|
598
|
+
# bucket = storage.restore_bucket "my-bucket", generation
|
599
|
+
# puts bucket.name
|
600
|
+
#
|
601
|
+
def restore_bucket bucket_name,
|
602
|
+
generation,
|
603
|
+
options: {}
|
604
|
+
gapi = service.restore_bucket bucket_name, generation,
|
605
|
+
options: options
|
606
|
+
Bucket.from_gapi gapi, service
|
607
|
+
end
|
608
|
+
|
532
609
|
##
|
533
610
|
# Generates a signed URL. See [Signed
|
534
611
|
# URLs](https://cloud.google.com/storage/docs/access-control/signed-urls)
|