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.
@@ -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 = Hash[attributes.map do |attr|
1989
- [attr, gapi.send(attr)]
1990
- end]
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&params2=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 || verify == :all
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. Object data for
292
- # objects in the bucket resides in physical storage within this
293
- # region. Possible values include `ASIA`, `EU`, and `US`. (See the
294
- # [developer's
295
- # guide](https://cloud.google.com/storage/docs/bucket-locations) for
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
- def create_bucket bucket_name, acl: nil, default_acl: nil,
368
- location: nil, storage_class: nil,
369
- logging_bucket: nil, logging_prefix: nil,
370
- website_main: nil, website_404: nil, versioning: nil,
371
- requester_pays: nil, user_project: nil
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.