diff --git a/google-cloud-storage/google-cloud-storage.gemspec b/google-cloud-storage/google-cloud-storage.gemspec index 31256edff256..58e510bdaf63 100644 --- a/google-cloud-storage/google-cloud-storage.gemspec +++ b/google-cloud-storage/google-cloud-storage.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |gem| gem.add_dependency "google-cloud-core", "~> 1.6" gem.add_dependency "google-apis-core", "~> 0.13" gem.add_dependency "google-apis-iamcredentials_v1", "~> 0.18" - gem.add_dependency "google-apis-storage_v1", "~> 0.38" + gem.add_dependency "google-apis-storage_v1", ">= 0.42" gem.add_dependency "googleauth", "~> 1.9" gem.add_dependency "digest-crc", "~> 0.4" gem.add_dependency "addressable", "~> 2.8" diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 56270c01d5e5..f5ab081698a7 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -2280,6 +2280,31 @@ def signed_url path = nil, end end + # Fetches generation of the bucket + # @example + # require "google/cloud/storage" + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # generation= bucket.generation + def generation + @gapi.generation + end + + # Fetches soft_delete_time of a soft deleted bucket + # @example + # bucket.delete + # bucket.soft_delete_time + def soft_delete_time + @gapi.soft_delete_time + end + + # Fetches hard_delete_time of a soft deleted bucket + # @example + # bucket.hard_delete_time + def hard_delete_time + @gapi.hard_delete_time + end + ## # Generate a PostObject that includes the fields and URL to # upload objects via HTML forms. diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket/list.rb b/google-cloud-storage/lib/google/cloud/storage/bucket/list.rb index e596fb4fda8a..5ed6cf39271b 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket/list.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket/list.rb @@ -72,7 +72,8 @@ def next return nil unless next? ensure_service! gapi = @service.list_buckets prefix: @prefix, token: @token, - max: @max, user_project: @user_project + max: @max, user_project: @user_project, + soft_deleted: @soft_deleted Bucket::List.from_gapi gapi, @service, @prefix, @max, user_project: @user_project end @@ -146,7 +147,7 @@ def all request_limit: nil, &block # @private New Bucket::List from a Google API Client # Google::Apis::StorageV1::Buckets object. def self.from_gapi gapi_list, service, prefix = nil, max = nil, - user_project: nil + user_project: nil, soft_deleted: nil buckets = new(Array(gapi_list.items).map do |gapi_object| Bucket.from_gapi gapi_object, service, user_project: user_project end) @@ -155,6 +156,7 @@ def self.from_gapi gapi_list, service, prefix = nil, max = nil, buckets.instance_variable_set :@prefix, prefix buckets.instance_variable_set :@max, max buckets.instance_variable_set :@user_project, user_project + buckets.instance_variable_set :@soft_deleted, soft_deleted buckets end diff --git a/google-cloud-storage/lib/google/cloud/storage/project.rb b/google-cloud-storage/lib/google/cloud/storage/project.rb index 3bdd554a764c..74c915acf5a8 100644 --- a/google-cloud-storage/lib/google/cloud/storage/project.rb +++ b/google-cloud-storage/lib/google/cloud/storage/project.rb @@ -192,11 +192,20 @@ def add_custom_header header_name, header_value # puts bucket.name # end # - def buckets prefix: nil, token: nil, max: nil, user_project: nil + # @example Retrieve soft deleted buckets + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # soft_deleted_buckets = storage.buckets soft_deleted: true + # soft_deleted_buckets.each do |bucket| + # puts bucket.name + # end + def buckets prefix: nil, token: nil, max: nil, user_project: nil, soft_deleted: nil gapi = service.list_buckets \ - prefix: prefix, token: token, max: max, user_project: user_project + prefix: prefix, token: token, max: max, user_project: user_project, soft_deleted: soft_deleted Bucket::List.from_gapi \ - gapi, service, prefix, max, user_project: user_project + gapi, service, prefix, max, user_project: user_project, soft_deleted: soft_deleted end alias find_buckets buckets @@ -222,6 +231,10 @@ def buckets prefix: nil, token: nil, max: nil, user_project: nil # account, transit costs will be billed to the given project. This # parameter is required with requester pays-enabled buckets. The # default is `nil`. + # @param [Integer] generation generation no of bucket + # on whether the bucket's current metageneration matches the given value. + # @param [Boolean] soft_deleted If true, returns the soft-deleted bucket. + # This parameter is required if generation is specified. # # The value provided will be applied to all operations on the returned # bucket instance and its files. @@ -255,9 +268,20 @@ def buckets prefix: nil, token: nil, max: nil, user_project: nil # bucket = storage.bucket "other-project-bucket", # user_project: "my-other-project" # files = bucket.files # Billed to "my-other-project" + # @example With `soft_deleted` set to true and generation specified: + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # + # bucket = storage.bucket "my-bucket", + # soft_deleted: true, + # generation: 1234567889 + # puts bucket.name # def bucket bucket_name, skip_lookup: false, + generation: nil, + soft_deleted: nil, if_metageneration_match: nil, if_metageneration_not_match: nil, user_project: nil @@ -268,7 +292,10 @@ def bucket bucket_name, gapi = service.get_bucket bucket_name, if_metageneration_match: if_metageneration_match, if_metageneration_not_match: if_metageneration_not_match, - user_project: user_project + user_project: user_project, + soft_deleted: soft_deleted, + generation: generation + Bucket.from_gapi gapi, service, user_project: user_project rescue Google::Cloud::NotFoundError nil @@ -553,6 +580,32 @@ def hmac_keys service_account_email: nil, project_id: nil, max: max, user_project: user_project end + ## + # Restores a soft deleted bucket with bucket name and generation. + # + # @param [String] bucket_name Name of the bucket. + # @param [Fixnum] generation Generation of the bucket. + # + # @return [Google::Cloud::Storage::Bucket, nil] Returns nil if bucket + # does not exist + # + # @example + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # generation= 123 + # + # bucket = storage.restore_bucket "my-bucket", generation + # puts bucket.name + # + def restore_bucket bucket_name, + generation, + options: {} + gapi = service.restore_bucket bucket_name, generation, + options: options + Bucket.from_gapi gapi, service + end + ## # Generates a signed URL. See [Signed # URLs](https://cloud.google.com/storage/docs/access-control/signed-urls) diff --git a/google-cloud-storage/lib/google/cloud/storage/service.rb b/google-cloud-storage/lib/google/cloud/storage/service.rb index 4b6c64816629..5175b08928c9 100644 --- a/google-cloud-storage/lib/google/cloud/storage/service.rb +++ b/google-cloud-storage/lib/google/cloud/storage/service.rb @@ -96,11 +96,12 @@ def project_service_account ## # Retrieves a list of buckets for the given project. - def list_buckets prefix: nil, token: nil, max: nil, user_project: nil, options: {} + def list_buckets prefix: nil, token: nil, max: nil, user_project: nil, soft_deleted: nil, options: {} execute do service.list_buckets \ @project, prefix: prefix, page_token: token, max_results: max, - user_project: user_project(user_project), options: options + user_project: user_project(user_project), + soft_deleted: soft_deleted, options: options end end @@ -111,12 +112,16 @@ def get_bucket bucket_name, if_metageneration_match: nil, if_metageneration_not_match: nil, user_project: nil, + soft_deleted: nil, + generation: nil, options: {} execute do service.get_bucket bucket_name, if_metageneration_match: if_metageneration_match, if_metageneration_not_match: if_metageneration_not_match, user_project: user_project(user_project), + soft_deleted: soft_deleted, + generation: generation, options: options end end @@ -653,6 +658,17 @@ def delete_file bucket_name, end end + ## + # Restore soft deleted bucket + def restore_bucket bucket_name, + generation, + options: {} + execute do + service.restore_bucket bucket_name, generation, + options: options + end + end + ## # Restores a soft-deleted object. def restore_file bucket_name, diff --git a/google-cloud-storage/test/google/cloud/storage/project_test.rb b/google-cloud-storage/test/google/cloud/storage/project_test.rb index 5e1b88ad99da..b7e2fd7c0269 100644 --- a/google-cloud-storage/test/google/cloud/storage/project_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/project_test.rb @@ -615,7 +615,7 @@ def stub.insert_bucket *args num_buckets = 3 mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(num_buckets), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(num_buckets), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -633,7 +633,7 @@ def stub.insert_bucket *args num_buckets = 3 mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(num_buckets), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(num_buckets), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -644,10 +644,31 @@ def stub.insert_bucket *args _(buckets.size).must_equal num_buckets end + it "lists deleted buckets" do + num_buckets = 3 + soft_deleted= true + + mock = Minitest::Mock.new + mock.expect :list_buckets, list_buckets_gapi(num_buckets,"next_page_token",soft_deleted), [project], prefix: nil, page_token: nil, +max_results: nil, user_project: nil, soft_deleted: true, options: {} + + storage.service.mocked_service = mock + buckets = storage.buckets soft_deleted: true + + mock.verify + + _(buckets.size).must_equal num_buckets + bucket = buckets.first + _(bucket).must_be_kind_of Google::Cloud::Storage::Bucket + _(bucket.generation).wont_be_nil + _(bucket.hard_delete_time).wont_be_nil + _(bucket.soft_delete_time).wont_be_nil + end + it "paginates buckets" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -666,8 +687,8 @@ def stub.insert_bucket *args it "paginates buckets with max set" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: 3, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: 3, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: 3, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: 3, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -688,7 +709,7 @@ def stub.insert_bucket *args num_buckets = 3 mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -705,8 +726,8 @@ def stub.insert_bucket *args it "paginates buckets with next? and next" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -724,8 +745,8 @@ def stub.insert_bucket *args it "paginates buckets with next? and next and max set" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: 3, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: 3, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: 3, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: 3, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -743,8 +764,8 @@ def stub.insert_bucket *args it "paginates buckets with all" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -757,8 +778,8 @@ def stub.insert_bucket *args it "paginates buckets with all and max set" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: 3, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: 3, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: 3, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(2), [project], prefix: nil, page_token: "next_page_token", max_results: 3, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -771,8 +792,8 @@ def stub.insert_bucket *args it "iterates buckets with all using Enumerator" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -785,8 +806,8 @@ def stub.insert_bucket *args it "iterates buckets with all and request_limit set" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, options: {} - mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: nil, soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: nil,soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -799,8 +820,8 @@ def stub.insert_bucket *args it "iterates buckets with all and user_project set to true" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: "test", options: {} - mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: "test", options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: "test", soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: "test", soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -814,8 +835,8 @@ def stub.insert_bucket *args it "iterates buckets with all and user_project set to another project ID" do mock = Minitest::Mock.new - mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: "my-other-project", options: {} - mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: "my-other-project", options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "next_page_token"), [project], prefix: nil, page_token: nil, max_results: nil, user_project: "my-other-project", soft_deleted: nil, options: {} + mock.expect :list_buckets, list_buckets_gapi(3, "second_page_token"), [project], prefix: nil, page_token: "next_page_token", max_results: nil, user_project: "my-other-project", soft_deleted: nil, options: {} storage.service.mocked_service = mock @@ -843,6 +864,43 @@ def stub.insert_bucket *args _(bucket).wont_be :lazy? end + it "finds a deleted bucket" do + bucket_name = "found-bucket" + generation = 1_733_393_981_548_601_746 + soft_deleted= true + + mock = Minitest::Mock.new + mock.expect :get_bucket, find_bucket_gapi(bucket_name, soft_deleted), + [bucket_name], **get_bucket_args(soft_deleted: soft_deleted, generation: generation) + + storage.service.mocked_service = mock + bucket = storage.bucket bucket_name, soft_deleted: soft_deleted, generation: generation + + mock.verify + + _(bucket.name).must_equal bucket_name + _(bucket.generation).must_equal generation + _(bucket.soft_delete_time).wont_be_nil + _(bucket.hard_delete_time).wont_be_nil + + _(bucket).wont_be :lazy? + end + + it "restores a deleted bucket" do + bucket_name = "found-bucket" + generation = 1_733_393_981_548_601_746 + + mock = Minitest::Mock.new + mock.expect :restore_bucket, restored_bucket_gapi(bucket_name), + [bucket_name, generation], options: {} + + storage.service.mocked_service = mock + bucket = storage.restore_bucket bucket_name, generation + mock.verify + _(bucket.name).must_equal bucket_name + _(bucket.generation).must_equal generation + end + it "finds a bucket with find_bucket alias" do bucket_name = "found-bucket" @@ -1011,17 +1069,23 @@ def create_bucket_gapi name = nil, Google::Apis::StorageV1::Bucket.new **options end - def find_bucket_gapi name = nil - Google::Apis::StorageV1::Bucket.from_json random_bucket_hash(name: name).to_json + + def find_bucket_gapi name = nil, soft_deleted= nil + Google::Apis::StorageV1::Bucket.from_json random_bucket_hash(name: name, soft_deleted: soft_deleted).to_json end - def list_buckets_gapi count = 2, token = nil - buckets = count.times.map { Google::Apis::StorageV1::Bucket.from_json random_bucket_hash.to_json } + def list_buckets_gapi count = 2, token = nil, soft_deleted = nil + buckets = count.times.map { Google::Apis::StorageV1::Bucket.from_json random_bucket_hash(soft_deleted: soft_deleted).to_json } Google::Apis::StorageV1::Buckets.new( kind: "storage#buckets", items: buckets, next_page_token: token ) end + def restored_bucket_gapi name + Google::Apis::StorageV1::Bucket.from_json random_bucket_hash(name: name).to_json + end + + def object_retention_param enable_object_retention enable_object_retention ? Google::Apis::StorageV1::Bucket::ObjectRetention.new(mode: "Enabled") : nil end diff --git a/google-cloud-storage/test/helper.rb b/google-cloud-storage/test/helper.rb index 50455d7c7e16..239104d6171b 100644 --- a/google-cloud-storage/test/helper.rb +++ b/google-cloud-storage/test/helper.rb @@ -70,15 +70,20 @@ def random_bucket_hash name: random_bucket_name, autoclass_terminal_storage_class: nil, enable_object_retention: nil, effective_time: DateTime.now, - retention_duration_seconds: 604800, # 7 days - hierarchical_namespace: nil + retention_duration_seconds: 604_800, # 7 days + soft_deleted: nil, + hierarchical_namespace: nil, + generation: "1733393981548601746" versioning_config = { "enabled" => versioning } if versioning - { "kind" => "storage#bucket", + + data = { + "kind" => "storage#bucket", "id" => name, "selfLink" => "#{url_root}/b/#{name}", "projectNumber" => "1234567890", "name" => name, "timeCreated" => Time.now, + "generation" => generation, "metageneration" => "1", "owner" => { "entity" => "project-owners-1234567890" }, "location" => location, @@ -96,16 +101,35 @@ def random_bucket_hash name: random_bucket_name, "enableObjectRetention" => enable_object_retention, "softDeletePolicy" => soft_delete_policy_object(retention_duration_seconds: retention_duration_seconds), "hierarchicalNamespace" => hierarchical_namespace - }.delete_if { |_, v| v.nil? } + } + if soft_deleted + data.merge! soft_delete_bucket_hash + end + data.delete_if { |_, v| v.nil? } end - def soft_delete_policy_object retention_duration_seconds: 604800 # 7 days + def soft_delete_policy_object retention_duration_seconds: 604_800 Google::Apis::StorageV1::Bucket::SoftDeletePolicy.new( effective_time: DateTime.now, retention_duration_seconds: retention_duration_seconds ) end + def soft_delete_policy_bucket retention_duration_seconds: 604_800 + Google::Apis::StorageV1::Bucket::SoftDeletePolicy.new( + effective_time: DateTime.now, + retention_duration_seconds: retention_duration_seconds + ) + end + + def soft_delete_bucket_hash + soft_delete_policy = soft_delete_policy_bucket + { + "softDeleteTime" => soft_delete_policy.effective_time, + "hardDeleteTime" => soft_delete_policy.effective_time.to_time + soft_delete_policy.retention_duration_seconds + } + end + def hierarchical_namespace_object enabled: true Google::Apis::StorageV1::Bucket::HierarchicalNamespace.new( enabled: enabled @@ -282,11 +306,15 @@ def policy_gapi etag: "CAE=", version: 1, bindings: [] def get_bucket_args if_metageneration_match: nil, if_metageneration_not_match: nil, user_project: nil, + generation: nil, + soft_deleted: nil, options: {} { if_metageneration_match: if_metageneration_match, if_metageneration_not_match: if_metageneration_not_match, user_project: user_project, + generation: generation, + soft_deleted: soft_deleted, options: options } end