diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index a8a9326a5e41..cae6cefdc986 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -58,6 +58,9 @@ require_relative "../storage_get_autoclass" require_relative "../storage_set_autoclass" require_relative "../storage_move_object" +require_relative "../storage_disable_soft_delete" +require_relative "../storage_get_soft_delete_policy" +require_relative "../storage_set_soft_delete_policy" describe "Buckets Snippets" do let(:storage_client) { Google::Cloud::Storage.new } @@ -676,4 +679,27 @@ assert_nil result end end + + describe "soft_delete_policy" do + it "get_soft_delete_policy, set_soft_delete_policy, disable_soft_delete" do + bucket_name = random_bucket_name + refute storage_client.bucket bucket_name + + storage_client.create_bucket bucket_name + + assert_output(/Soft delete policy for #{bucket_name}:/) do + get_soft_delete_policy bucket_name: bucket_name + end + + assert_output(/Soft delete retention duration for #{bucket_name} is now 604800 seconds\./) do + set_soft_delete_policy bucket_name: bucket_name, retention_duration_seconds: 604800 + end + + assert_output(/Soft delete retention duration for #{bucket_name} is now 0 seconds\./) do + disable_soft_delete bucket_name: bucket_name + end + + delete_bucket_helper bucket_name + end + end end diff --git a/google-cloud-storage/samples/acceptance/files_test.rb b/google-cloud-storage/samples/acceptance/files_test.rb index d1c6c53c74cf..3af79db2f99d 100644 --- a/google-cloud-storage/samples/acceptance/files_test.rb +++ b/google-cloud-storage/samples/acceptance/files_test.rb @@ -52,6 +52,9 @@ require_relative "../storage_upload_file" require_relative "../storage_upload_from_memory" require_relative "../storage_upload_with_kms_key" +require_relative "../storage_list_soft_deleted_objects" +require_relative "../storage_list_soft_deleted_object_versions" +require_relative "../storage_restore_object" describe "Files Snippets" do let(:storage_client) { Google::Cloud::Storage.new } @@ -719,4 +722,25 @@ def mock_cipher.random_key local_file_obj: StringIO.new end end + + describe "soft_deleted objects" do + it "list_soft_deleted_objects, list_soft_deleted_object_versions, restore_object" do + file = bucket.create_file StringIO.new(file_content), remote_file_name + generation = file.generation + file.delete + + out, _err = capture_io do + list_soft_deleted_objects bucket_name: bucket.name + end + assert_match remote_file_name, out + out, _err = capture_io do + list_soft_deleted_object_versions bucket_name: bucket.name + end + assert_match remote_file_name, out + + assert_output(/Restored file #{Regexp.escape remote_file_name} with generation \d+ in bucket #{Regexp.escape bucket.name}\./) do + restore_object bucket_name: bucket.name, file_name: remote_file_name, generation: generation + end + end + end end diff --git a/google-cloud-storage/samples/storage_disable_soft_delete.rb b/google-cloud-storage/samples/storage_disable_soft_delete.rb new file mode 100644 index 000000000000..19cf7db78b54 --- /dev/null +++ b/google-cloud-storage/samples/storage_disable_soft_delete.rb @@ -0,0 +1,31 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START storage_disable_soft_delete] +def disable_soft_delete bucket_name: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.soft_delete_policy = { retention_duration_seconds: 0 } + + puts "Soft delete retention duration for #{bucket_name} is now 0 seconds." +end +# [END storage_disable_soft_delete] + +disable_soft_delete bucket_name: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage/samples/storage_get_soft_delete_policy.rb b/google-cloud-storage/samples/storage_get_soft_delete_policy.rb new file mode 100644 index 000000000000..2606944f63ed --- /dev/null +++ b/google-cloud-storage/samples/storage_get_soft_delete_policy.rb @@ -0,0 +1,31 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START storage_get_soft_delete_policy] +def get_soft_delete_policy bucket_name: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + puts "Soft delete policy for #{bucket_name}:" + puts "Retention duration: #{bucket.soft_delete_policy.retention_duration_seconds} seconds" + puts "Effective time: #{bucket.soft_delete_policy.effective_time}" +end +# [END storage_get_soft_delete_policy] + +get_soft_delete_policy bucket_name: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage/samples/storage_list_soft_deleted_object_versions.rb b/google-cloud-storage/samples/storage_list_soft_deleted_object_versions.rb new file mode 100644 index 000000000000..b5307dadfa26 --- /dev/null +++ b/google-cloud-storage/samples/storage_list_soft_deleted_object_versions.rb @@ -0,0 +1,30 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START storage_list_soft_deleted_object_versions] +def list_soft_deleted_object_versions bucket_name: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + bucket.files(soft_deleted: true).each do |file| + puts "#{file.name}, generation: #{file.generation}, soft_delete_time: #{file.soft_delete_time}" + end +end +# [END storage_list_soft_deleted_object_versions] + +list_soft_deleted_object_versions bucket_name: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage/samples/storage_list_soft_deleted_objects.rb b/google-cloud-storage/samples/storage_list_soft_deleted_objects.rb new file mode 100644 index 000000000000..c91ae14530db --- /dev/null +++ b/google-cloud-storage/samples/storage_list_soft_deleted_objects.rb @@ -0,0 +1,31 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START storage_list_soft_deleted_objects] +def list_soft_deleted_objects bucket_name: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.files(soft_deleted: true).each do |file| + puts "#{file.name}, soft_delete_time: #{file.soft_delete_time}" + end +end +# [END storage_list_soft_deleted_objects] + +list_soft_deleted_objects bucket_name: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage/samples/storage_restore_object.rb b/google-cloud-storage/samples/storage_restore_object.rb new file mode 100644 index 000000000000..5be25faeb50a --- /dev/null +++ b/google-cloud-storage/samples/storage_restore_object.rb @@ -0,0 +1,39 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START storage_restore_object] +def restore_object bucket_name:, file_name:, generation: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # The name of the soft-deleted file to restore + # file_name = "your-file-name" + + # The generation of the soft-deleted file to restore + # generation = 1600000000000000 + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + file = bucket.restore_file file_name, generation + + puts "Restored file #{file.name} with generation #{file.generation} in bucket #{bucket_name}." +end +# [END storage_restore_object] + +if $PROGRAM_NAME == __FILE__ + restore_object bucket_name: ARGV.shift, file_name: ARGV.shift, generation: ARGV.shift +end diff --git a/google-cloud-storage/samples/storage_set_soft_delete_policy.rb b/google-cloud-storage/samples/storage_set_soft_delete_policy.rb new file mode 100644 index 000000000000..e237b98940b4 --- /dev/null +++ b/google-cloud-storage/samples/storage_set_soft_delete_policy.rb @@ -0,0 +1,36 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START storage_set_soft_delete_policy] +def set_soft_delete_policy bucket_name:, retention_duration_seconds: + # The ID of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # The retention duration for soft-deleted objects in seconds + # retention_duration_seconds = 604800 # 7 days in seconds + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + + bucket.soft_delete_policy = { retention_duration_seconds: retention_duration_seconds.to_i } + + puts "Soft delete retention duration for #{bucket_name} is now #{bucket.soft_delete_policy.retention_duration_seconds} seconds." +end +# [END storage_set_soft_delete_policy] + +if $PROGRAM_NAME == __FILE__ + set_soft_delete_policy bucket_name: ARGV.shift, retention_duration_seconds: ARGV.shift +end