google-cloud-storage 1.35.0 → 1.54.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/AUTHENTICATION.md +8 -26
- data/CHANGELOG.md +144 -0
- data/OVERVIEW.md +32 -0
- data/lib/google/cloud/storage/bucket/acl.rb +28 -26
- data/lib/google/cloud/storage/bucket/cors.rb +2 -2
- data/lib/google/cloud/storage/bucket/lifecycle.rb +88 -10
- data/lib/google/cloud/storage/bucket.rb +396 -11
- data/lib/google/cloud/storage/file/list.rb +10 -3
- data/lib/google/cloud/storage/file/signer_v2.rb +6 -5
- data/lib/google/cloud/storage/file/signer_v4.rb +6 -6
- data/lib/google/cloud/storage/file.rb +141 -10
- data/lib/google/cloud/storage/project.rb +88 -13
- data/lib/google/cloud/storage/service.rb +291 -227
- data/lib/google/cloud/storage/version.rb +1 -1
- data/lib/google/cloud/storage.rb +58 -14
- data/lib/google-cloud-storage.rb +47 -13
- metadata +44 -22
@@ -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
|
#
|
@@ -94,6 +103,41 @@ module Google
|
|
94
103
|
service.project_service_account.email_address
|
95
104
|
end
|
96
105
|
|
106
|
+
##
|
107
|
+
# Add custom Google extension headers to the requests that use the signed URLs.
|
108
|
+
#
|
109
|
+
# @param [Hash] headers Google extension headers (custom HTTP headers that
|
110
|
+
# begin with `x-goog-`) to be included in requests that use the signed URLs.
|
111
|
+
# Provide headers as a key/value array, where the key is
|
112
|
+
# the header name, and the value is an array of header values.
|
113
|
+
# For headers with multiple values, provide values as a simple
|
114
|
+
# array, or a comma-separated string. For a reference of allowed
|
115
|
+
# headers, see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers).
|
116
|
+
#
|
117
|
+
# @return [Google::Cloud::Storage::Project] Returns the Project for method chaining
|
118
|
+
#
|
119
|
+
def add_custom_headers headers
|
120
|
+
@service.add_custom_headers headers
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Add custom Google extension header to the requests that use the signed URLs.
|
126
|
+
#
|
127
|
+
# @param [String] header_name Name of Google extension header (custom HTTP header that
|
128
|
+
# begin with `x-goog-`) to be included in requests that use the signed URLs.
|
129
|
+
# For a reference of allowed headers, see
|
130
|
+
# [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers).
|
131
|
+
# @param [Object] header_value Valid value of the Google extension header being added.
|
132
|
+
# For headers with multiple values, provide values as a simple array, or a comma-separated string.
|
133
|
+
#
|
134
|
+
# @return [Google::Cloud::Storage::Project] Returns the Project for method chaining
|
135
|
+
#
|
136
|
+
def add_custom_header header_name, header_value
|
137
|
+
@service.add_custom_header header_name, header_value
|
138
|
+
self
|
139
|
+
end
|
140
|
+
|
97
141
|
##
|
98
142
|
# Retrieves a list of buckets for the given project.
|
99
143
|
#
|
@@ -288,12 +332,11 @@ module Google
|
|
288
332
|
# roles.
|
289
333
|
# * `public`, `public_read`, `publicRead` - File owner gets OWNER
|
290
334
|
# access, and allUsers get READER access.
|
291
|
-
# @param [String] location The location of the bucket.
|
292
|
-
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
#
|
296
|
-
# the authoritative list. The default value is `US`.
|
335
|
+
# @param [String] location The location of the bucket. Optional.
|
336
|
+
# If not passed, the default location, 'US', will be used.
|
337
|
+
# If specifying a dual-region location, the `customPlacementConfig`
|
338
|
+
# property should be set in conjunction. See:
|
339
|
+
# [Storage Locations](https://cloud.google.com/storage/docs/locations).
|
297
340
|
# @param [String] logging_bucket The destination bucket for the bucket's
|
298
341
|
# logs. For more information, see [Access
|
299
342
|
# Logs](https://cloud.google.com/storage/docs/access-logs).
|
@@ -328,11 +371,18 @@ module Google
|
|
328
371
|
# other than the current project, and that project is authorized for
|
329
372
|
# the currently authenticated service account, transit costs will be
|
330
373
|
# billed to the given project. The default is `nil`.
|
374
|
+
# @param [Boolean] autoclass_enabled The bucket's autoclass configuration.
|
375
|
+
# Buckets can have either StorageClass OLM rules or Autoclass, but
|
376
|
+
# not both. When Autoclass is enabled on a bucket, adding StorageClass
|
377
|
+
# OLM rules will result in failure. For more information, see
|
378
|
+
# [Autoclass](https://cloud.google.com/storage/docs/autoclass).
|
331
379
|
#
|
332
380
|
# The value provided will be applied to all operations on the returned
|
333
381
|
# bucket instance and its files.
|
334
382
|
#
|
335
383
|
# See also {Bucket#requester_pays=} and {Bucket#requester_pays}.
|
384
|
+
# @param [Boolean] enable_object_retention
|
385
|
+
# When set to true, object retention is enabled for this bucket.
|
336
386
|
#
|
337
387
|
# @yield [bucket] a block for configuring the bucket before it is
|
338
388
|
# created
|
@@ -347,6 +397,13 @@ module Google
|
|
347
397
|
#
|
348
398
|
# bucket = storage.create_bucket "my-bucket"
|
349
399
|
#
|
400
|
+
# @example
|
401
|
+
# require "google/cloud/storage"
|
402
|
+
#
|
403
|
+
# storage = Google::Cloud::Storage.new
|
404
|
+
#
|
405
|
+
# bucket = storage.create_bucket "my-bucket", enable_object_retention: true
|
406
|
+
#
|
350
407
|
# @example Configure the bucket in a block:
|
351
408
|
# require "google/cloud/storage"
|
352
409
|
#
|
@@ -364,25 +421,41 @@ module Google
|
|
364
421
|
# b.lifecycle.add_set_storage_class_rule "COLDLINE", age: 10
|
365
422
|
# end
|
366
423
|
#
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
424
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
425
|
+
def create_bucket bucket_name,
|
426
|
+
acl: nil,
|
427
|
+
default_acl: nil,
|
428
|
+
location: nil,
|
429
|
+
custom_placement_config: nil,
|
430
|
+
storage_class: nil,
|
431
|
+
logging_bucket: nil,
|
432
|
+
logging_prefix: nil,
|
433
|
+
website_main: nil,
|
434
|
+
website_404: nil,
|
435
|
+
versioning: nil,
|
436
|
+
requester_pays: nil,
|
437
|
+
user_project: nil,
|
438
|
+
autoclass_enabled: false,
|
439
|
+
enable_object_retention: nil,
|
440
|
+
hierarchical_namespace: nil
|
372
441
|
params = {
|
373
442
|
name: bucket_name,
|
374
|
-
location: location
|
443
|
+
location: location,
|
444
|
+
custom_placement_config: custom_placement_config,
|
445
|
+
hierarchical_namespace: hierarchical_namespace
|
375
446
|
}.delete_if { |_, v| v.nil? }
|
376
447
|
new_bucket = Google::Apis::StorageV1::Bucket.new(**params)
|
377
448
|
storage_class = storage_class_for storage_class
|
378
449
|
updater = Bucket::Updater.new(new_bucket).tap do |b|
|
379
450
|
b.logging_bucket = logging_bucket unless logging_bucket.nil?
|
380
451
|
b.logging_prefix = logging_prefix unless logging_prefix.nil?
|
452
|
+
b.autoclass_enabled = autoclass_enabled
|
381
453
|
b.storage_class = storage_class unless storage_class.nil?
|
382
454
|
b.website_main = website_main unless website_main.nil?
|
383
455
|
b.website_404 = website_404 unless website_404.nil?
|
384
456
|
b.versioning = versioning unless versioning.nil?
|
385
457
|
b.requester_pays = requester_pays unless requester_pays.nil?
|
458
|
+
b.hierarchical_namespace = hierarchical_namespace unless hierarchical_namespace.nil?
|
386
459
|
end
|
387
460
|
yield updater if block_given?
|
388
461
|
updater.check_for_changed_labels!
|
@@ -390,9 +463,11 @@ module Google
|
|
390
463
|
updater.check_for_mutable_lifecycle!
|
391
464
|
gapi = service.insert_bucket \
|
392
465
|
new_bucket, acl: acl_rule(acl), default_acl: acl_rule(default_acl),
|
393
|
-
user_project: user_project
|
466
|
+
user_project: user_project,
|
467
|
+
enable_object_retention: enable_object_retention
|
394
468
|
Bucket.from_gapi gapi, service, user_project: user_project
|
395
469
|
end
|
470
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
396
471
|
|
397
472
|
##
|
398
473
|
# Creates a new HMAC key.
|