From 598851ab54eea2455a1c0c4cdb84a318e53ac7d0 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Wed, 25 Mar 2026 08:48:29 +0000 Subject: [PATCH 01/28] adding ostruct gem in samples --- google-cloud-storage/samples/Gemfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/google-cloud-storage/samples/Gemfile b/google-cloud-storage/samples/Gemfile index 3b36d79c3373..67a916a8415c 100644 --- a/google-cloud-storage/samples/Gemfile +++ b/google-cloud-storage/samples/Gemfile @@ -36,3 +36,7 @@ group :test do gem "minitest-hooks", "~> 1.5" gem "rake" end +# The following gems have been removed from ruby core and are required for testing. +gem "ostruct" +gem "cgi" +gem "irb" From 53ee419f6cf8db16612e54eb6fcfc3a2905d8acf Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 3 Mar 2026 05:39:02 +0000 Subject: [PATCH 02/28] adding functionality --- .../storage/bucket_encryption_test.rb | 2 +- .../lib/google/cloud/storage/bucket.rb | 115 ++++++++++++++++++ .../samples/acceptance/buckets_test.rb | 41 +++++++ ...orage_get_encryption_enforcement_config.rb | 36 ++++++ ...emove_all_encryption_enforcement_config.rb | 34 ++++++ ...orage_set_encryption_enforcement_config.rb | 48 ++++++++ .../cloud/storage/bucket_encryption_test.rb | 14 +-- .../test/google/cloud/storage/project_test.rb | 78 +++++++++++- google-cloud-storage/test/helper.rb | 31 ++++- 9 files changed, 388 insertions(+), 11 deletions(-) create mode 100644 google-cloud-storage/samples/storage_get_encryption_enforcement_config.rb create mode 100644 google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb create mode 100644 google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 7760e2107ed8..6065874f6893 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -71,4 +71,4 @@ _(bucket.default_kms_key).must_be :nil? end end -end +end \ No newline at end of file diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index ca8461354bb7..17e6bae808f7 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -717,6 +717,121 @@ def default_kms_key= new_default_kms_key patch_gapi! :encryption end + # The bucket's encryption configuration for customer-managed encryption keys. + # This configuration defines the + # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements for the bucket. + # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/). + # @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] The bucket's encryption configuration, or `nil` if no encryption configuration has been set. + # @example + # require "google/cloud/storage" + # # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # bucket.customer_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new + # restriction_mode: "NotRestricted" + # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" + + def customer_managed_encryption_enforcement_config + @gapi.encryption&.customer_managed_encryption_enforcement_config + end + + # Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files. + # @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] new_customer_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. + # @example + # require "google/cloud/storage" + # # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # bucket.customer_managed_encryption_enforcement_config = new_config + # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" + + def customer_managed_encryption_enforcement_config= new_customer_managed_encryption_enforcement_config + @gapi.encryption ||= API::Bucket::Encryption.new + @gapi.encryption.customer_managed_encryption_enforcement_config = + new_customer_managed_encryption_enforcement_config + patch_gapi! :encryption + end + + ## + # The bucket's encryption configuration for customer-supplied encryption keys. This configuration defines the + # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements + # for the bucket. + # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/). + # @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] + # The bucket's encryption configuration, or `nil` if no encryption configuration has been set. + # @example + # require "google/cloud/storage" + # # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # bucket.customer_supplied_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new + # restriction_mode: "NotRestricted" + # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted". + + def customer_supplied_encryption_enforcement_config + @gapi.encryption&.customer_supplied_encryption_enforcement_config + end + + ## + # Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files. + # @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] new_customer_supplied_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. + # @example + # require "google/cloud/storage" + # # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # bucket.customer_supplied_encryption_enforcement_config = new_config + # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" + + def customer_supplied_encryption_enforcement_config= new_customer_supplied_encryption_enforcement_config + @gapi.encryption ||= API::Bucket::Encryption.new + @gapi.encryption.customer_supplied_encryption_enforcement_config = + new_customer_supplied_encryption_enforcement_config + patch_gapi! :encryption + end + + ## + # The bucket's encryption configuration for google-managed encryption keys. + # This configuration defines the + # default encryption behavior for the bucket and its files, and it can be used to enforce encryption + # requirements for the bucket. + # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/). + # @return [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, nil] + # The bucket's encryption configuration, or `nil` if no encryption configuration has been set. + # @example + # require "google/cloud/storage" + # # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # bucket.google_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new + # restriction_mode: "NotRestricted" + # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted". + + def google_managed_encryption_enforcement_config + @gapi.encryption&.google_managed_encryption_enforcement_config + end + + ## + # Sets the bucket's encryption configuration for google-managed encryption that will be used to protect files. + # @param [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, nil] new_google_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. + # @example + # require "google/cloud/storage" + # # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # bucket.google_managed_encryption_enforcement_config = new_config + # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" + + def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config + @gapi.encryption ||= API::Bucket::Encryption.new + @gapi.encryption.google_managed_encryption_enforcement_config = + new_google_managed_encryption_enforcement_config + patch_gapi! :encryption + end + ## # The period of time (in seconds) that files in the bucket must be # retained, and cannot be deleted, overwritten, or archived. diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index bb78ba9bbe44..e30b0cfb79d3 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -37,6 +37,7 @@ require_relative "../storage_get_bucket_class_and_location" require_relative "../storage_get_bucket_metadata" require_relative "../storage_get_default_event_based_hold" +require_relative "../storage_get_encryption_enforcement_config" require_relative "../storage_get_public_access_prevention" require_relative "../storage_get_requester_pays_status" require_relative "../storage_get_retention_policy" @@ -48,6 +49,8 @@ require_relative "../storage_remove_cors_configuration" require_relative "../storage_remove_retention_policy" require_relative "../storage_set_bucket_default_kms_key" +require_relative "../storage_set_encryption_enforcement_config" +require_relative "../storage_remove_all_encryption_enforcement_config" require_relative "../storage_set_object_retention_policy" require_relative "../storage_set_public_access_prevention_enforced" require_relative "../storage_set_public_access_prevention_inherited" @@ -169,6 +172,44 @@ end end + describe "storage_encryption_enforcement_config" do + bucket_name = random_bucket_name + + it "gets, sets and clears bucket encryption enforcement config" do + # creates bucket with encryption enforcement config + expected = "Created bucket #{bucket_name} with Encryption Enforcement Config.\n" + + retry_resource_exhaustion do + assert_output expected do + set_encryption_enforcement_config bucket_name: bucket_name + end + end + + # get encryption enforcement config + expected = "Encryption Enforcement Config for bucket #{bucket_name}:\n" \ + "Customer-managed encryption enforcement config restriction mode: NotRestricted\n" \ + "Customer-supplied encryption enforcement config restriction mode: FullyRestricted\n" \ + "Google-managed encryption enforcement config restriction mode: FullyRestricted\n" + retry_resource_exhaustion do + assert_output expected do + get_encryption_enforcement_config bucket_name: bucket_name + end + end + + # clears encryption enforcement config + expected = "Removed Encryption Enforcement Config from bucket #{bucket_name}.\n" + + retry_resource_exhaustion do + assert_output expected do + remove_all_encryption_enforcement_config bucket_name: bucket_name + end + end + + refute_nil storage_client.bucket bucket_name + end + delete_bucket_helper bucket_name + end + describe "storage_create_bucket_with_object_retention" do it "creates a bucket with object retention enabled." do bucket_name = random_bucket_name diff --git a/google-cloud-storage/samples/storage_get_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_get_encryption_enforcement_config.rb new file mode 100644 index 000000000000..652610cc4553 --- /dev/null +++ b/google-cloud-storage/samples/storage_get_encryption_enforcement_config.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_get_encryption_enforcement_config] +def get_encryption_enforcement_config bucket_name: + # The ID to give your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + puts "Encryption Enforcement Config for bucket #{bucket.name}:" + puts "Customer-managed encryption enforcement config restriction mode: " \ + "#{bucket.customer_managed_encryption_enforcement_config&.restriction_mode}" + puts "Customer-supplied encryption enforcement config restriction mode: " \ + "#{bucket.customer_supplied_encryption_enforcement_config&.restriction_mode}" + puts "Google-managed encryption enforcement config restriction mode: " \ + "#{bucket.google_managed_encryption_enforcement_config&.restriction_mode}" +end +# [END storage_get_encryption_enforcement_config] + +if $PROGRAM_NAME == __FILE__ + get_encryption_enforcement_config bucket_name: ARGV.shift +end diff --git a/google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb new file mode 100644 index 000000000000..781e86c48451 --- /dev/null +++ b/google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb @@ -0,0 +1,34 @@ +# 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_remove_all_encryption_enforcement_config] +def remove_all_encryption_enforcement_config bucket_name: + # The ID to give your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name do |b| + b.customer_managed_encryption_enforcement_config = nil + b.customer_supplied_encryption_enforcement_config = nil + b.google_managed_encryption_enforcement_config = nil + end + puts "Removed Encryption Enforcement Config from bucket #{bucket.name}." +end +# [END storage_remove_all_encryption_enforcement_config] + +if $PROGRAM_NAME == __FILE__ + remove_all_encryption_enforcement_config bucket_name: ARGV.shift +end diff --git a/google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb new file mode 100644 index 000000000000..391f67e7af4b --- /dev/null +++ b/google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb @@ -0,0 +1,48 @@ +# 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_encryption_enforcement_config] +def set_encryption_enforcement_config bucket_name: + # The ID to give your GCS bucket + # bucket_name = "your-unique-bucket-name" + + require "google/cloud/storage" + + storage = Google::Cloud::Storage.new + + customer_managed_config = + Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( + restriction_mode: "NotRestricted" + ) + customer_supplied_config = + Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + google_managed_config = + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + + bucket = storage.create_bucket bucket_name do |b| + b.customer_managed_encryption_enforcement_config = customer_managed_config + b.customer_supplied_encryption_enforcement_config = customer_supplied_config + b.google_managed_encryption_enforcement_config = google_managed_config + end + puts "Created bucket #{bucket.name} with Encryption Enforcement Config." +end +# [END storage_set_encryption_enforcement_config] + +if $PROGRAM_NAME == __FILE__ + set_encryption_enforcement_config bucket_name: ARGV.shift +end diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index ce617da110e6..9e84cd78e4f8 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -20,6 +20,8 @@ let(:bucket_json) { bucket_hash.to_json } let(:bucket_gapi) { Google::Apis::StorageV1::Bucket.from_json bucket_json } let(:bucket) { Google::Cloud::Storage::Bucket.from_gapi bucket_gapi, storage.service } + let(:kms_key) { "path/to/encryption_key_name" } + describe "customer-supplied encryption key (CSEK)" do let(:encryption_key) { "y\x03\"\x0E\xB6\xD3\x9B\x0E\xAB*\x19\xFAv\xDEY\xBEI\xF8ftA|[z\x1A\xFBE\xDE\x97&\xBC\xC7" } @@ -70,11 +72,9 @@ end describe "KMS customer-managed encryption key (CMEK)" do - let(:kms_key) { "path/to/encryption_key_name" } - it "gets and sets its encryption config" do mock = Minitest::Mock.new - patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(kms_key) + patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(key_name: kms_key) mock.expect :patch_bucket, patch_bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: {retries: 0}) bucket.service.mocked_service = mock @@ -88,11 +88,12 @@ it "sets its encryption config to nil" do bucket_gapi_with_key = bucket_gapi.dup - bucket_gapi_with_key.encryption = encryption_gapi(kms_key) + bucket_gapi_with_key.encryption = encryption_gapi(key_name: kms_key) bucket_with_key = Google::Cloud::Storage::Bucket.from_gapi bucket_gapi_with_key, storage.service - patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(nil) mock = Minitest::Mock.new - mock.expect :patch_bucket, bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: {retries: 0}) + mock.expect :patch_bucket, bucket_gapi do |name, patch_obj, **args| + name == bucket_name && patch_obj.encryption&.default_kms_key_name.nil? + end bucket_with_key.service.mocked_service = mock @@ -122,7 +123,6 @@ end end - def create_file_gapi bucket=nil, name = nil Google::Apis::StorageV1::Object.from_json random_file_hash(bucket, name).to_json end 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 05724226ca34..052c3a77f184 100644 --- a/google-cloud-storage/test/google/cloud/storage/project_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/project_test.rb @@ -389,7 +389,7 @@ def creds.is_a? target it "creates a bucket with block encryption" do mock = Minitest::Mock.new created_bucket = create_bucket_gapi bucket_name - created_bucket.encryption = encryption_gapi(kms_key) + created_bucket.encryption = encryption_gapi(key_name: kms_key) resp_bucket = bucket_with_location created_bucket mock.expect :insert_bucket, resp_bucket, [project, created_bucket], predefined_acl: nil, predefined_default_object_acl: nil, user_project: nil, enable_object_retention: nil, options: {} @@ -1090,6 +1090,82 @@ def stub.insert_bucket *args _(buckets.unreachable).must_be :nil? end + describe "storage encryption enforcement config" do + # set and get customer managed encryption enforcement config and verify + it "sets and gets customer managed bucket encryption enforcement config" do + mock = Minitest::Mock.new + created_bucket = create_bucket_gapi bucket_name + created_bucket.encryption = encryption_gapi(customer_managed_config_restriction_mode: "NotRestricted") + resp_bucket = bucket_with_location created_bucket + mock.expect :insert_bucket, resp_bucket, [project, created_bucket], predefined_acl: nil, predefined_default_object_acl: nil, user_project: nil, enable_object_retention: nil, options: {} + storage.service.mocked_service = mock + bucket = storage.create_bucket bucket_name do |b| + # set customer managed encryption enforcement config + b.customer_managed_encryption_enforcement_config = customer_managed_config(restriction_mode: "NotRestricted") + end + mock.verify + # get customer managed encryption enforcement config and verify + _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + end + + # set customer supplied and google managed encryption enforcement config and verify + it "sets customer supplied and google managed bucket encryption enforcement config" do + mock = Minitest::Mock.new + created_bucket = create_bucket_gapi bucket_name + created_bucket.encryption = encryption_gapi(customer_supplied_config_restriction_mode: "FullyRestricted", google_managed_config_restriction_mode: "NotRestricted" ) + resp_bucket = bucket_with_location created_bucket + mock.expect :insert_bucket, resp_bucket, [project, created_bucket], predefined_acl: nil, predefined_default_object_acl: nil, user_project: nil, enable_object_retention: nil, options: {} + storage.service.mocked_service = mock + + # set customer supplied and google managed encryption enforcement config + bucket = storage.create_bucket bucket_name do |b| + b.customer_supplied_encryption_enforcement_config = customer_supplied_config(restriction_mode: "FullyRestricted") + b.google_managed_encryption_enforcement_config = google_managed_config(restriction_mode: "NotRestricted" ) + end + mock.verify + # get customer supplied and google managed encryption enforcement config and verify + _(bucket.customer_supplied_encryption_enforcement_config).wont_be :nil? + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_managed_encryption_enforcement_config).must_be :nil? + end + + # delete customer supplied encryption enforcement config and verify + it "deletes customer supplied encryption enforcement config" do + mock = Minitest::Mock.new + + created_bucket = create_bucket_gapi bucket_name + # Set initial state: FullyRestricted + created_bucket.encryption = encryption_gapi(customer_supplied_config_restriction_mode: "FullyRestricted") + resp_bucket = bucket_with_location created_bucket + + mock.expect :insert_bucket, resp_bucket do |project_id, b_arg, **kwargs| + project_id == project && + b_arg.encryption.customer_supplied_encryption_enforcement_config.restriction_mode == "FullyRestricted" + end + + # Define what the bucket should look like AFTER the delete (config should be nil) + updated_bucket_gapi = create_bucket_gapi bucket_name + updated_bucket_gapi.encryption = encryption_gapi(customer_supplied_config_restriction_mode: nil) + + # We verify that the patch_bucket call is made with a bucket that has NO config + mock.expect :patch_bucket, updated_bucket_gapi do |name, b_arg, **kwargs| + name == bucket_name && + b_arg.encryption.customer_supplied_encryption_enforcement_config.nil? + end + storage.service.mocked_service = mock + + # Create the bucket + bucket = storage.create_bucket bucket_name do |b| + b.customer_supplied_encryption_enforcement_config = customer_supplied_config(restriction_mode: "FullyRestricted") + end + # Perform the deletion + bucket.customer_supplied_encryption_enforcement_config = nil + mock.verify + _(bucket.customer_supplied_encryption_enforcement_config).must_be :nil? + end + end + def bucket_with_location created_bucket, location_type: bucket_location_type resp_bucket = created_bucket.dup diff --git a/google-cloud-storage/test/helper.rb b/google-cloud-storage/test/helper.rb index 1a4752e77628..52bf1b2e0a88 100644 --- a/google-cloud-storage/test/helper.rb +++ b/google-cloud-storage/test/helper.rb @@ -244,8 +244,35 @@ def download_http_resp gzip: nil OpenStruct.new(header: headers) end - def encryption_gapi key_name - Google::Apis::StorageV1::Bucket::Encryption.new default_kms_key_name: key_name + def encryption_gapi(key_name: nil, + customer_managed_config_restriction_mode: nil, + customer_supplied_config_restriction_mode: nil, + google_managed_config_restriction_mode: nil) + + cm_config = customer_managed_config(restriction_mode: customer_managed_config_restriction_mode) if customer_managed_config_restriction_mode + cs_config = customer_supplied_config(restriction_mode: customer_supplied_config_restriction_mode) if customer_supplied_config_restriction_mode + gm_config = google_managed_config(restriction_mode: google_managed_config_restriction_mode) if google_managed_config_restriction_mode + + params = { + default_kms_key_name: key_name, + customer_managed_encryption_enforcement_config: cm_config, + customer_supplied_encryption_enforcement_config: cs_config, + google_managed_encryption_enforcement_config: gm_config + }.compact # This removes the nil values so the API doesn't get empty configs + + Google::Apis::StorageV1::Bucket::Encryption.new(**params) + end + + def customer_managed_config restriction_mode: nil + Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: restriction_mode + end + + def customer_supplied_config restriction_mode: nil + Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: restriction_mode + end + + def google_managed_config restriction_mode: nil + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: restriction_mode end def lifecycle_gapi *rules From be44e07ff36f26fcc17404d063dc55eb490f81f5 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 3 Mar 2026 11:19:24 +0530 Subject: [PATCH 03/28] Add newline at end of bucket_encryption_test.rb Fix missing newline at end of file in bucket_encryption_test.rb --- .../acceptance/storage/bucket_encryption_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 6065874f6893..7760e2107ed8 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -71,4 +71,4 @@ _(bucket.default_kms_key).must_be :nil? end end -end \ No newline at end of file +end From 96e3fa20b8f1be4ccd86914f517bc9dbaa88cc27 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 16 Mar 2026 09:18:16 +0000 Subject: [PATCH 04/28] renaming tags --- .../samples/acceptance/buckets_test.rb | 14 +++++++------- ...ge_get_bucket_encryption_enforcement_config.rb} | 8 ++++---- ...ve_all_bucket_encryption_enforcement_config.rb} | 8 ++++---- ...ge_set_bucket_encryption_enforcement_config.rb} | 8 ++++---- 4 files changed, 19 insertions(+), 19 deletions(-) rename google-cloud-storage/samples/{storage_get_encryption_enforcement_config.rb => storage_get_bucket_encryption_enforcement_config.rb} (84%) rename google-cloud-storage/samples/{storage_remove_all_encryption_enforcement_config.rb => storage_remove_all_bucket_encryption_enforcement_config.rb} (79%) rename google-cloud-storage/samples/{storage_set_encryption_enforcement_config.rb => storage_set_bucket_encryption_enforcement_config.rb} (87%) diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index e30b0cfb79d3..ba9ff0c56781 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -37,7 +37,7 @@ require_relative "../storage_get_bucket_class_and_location" require_relative "../storage_get_bucket_metadata" require_relative "../storage_get_default_event_based_hold" -require_relative "../storage_get_encryption_enforcement_config" +require_relative "../storage_get_bucket_encryption_enforcement_config" require_relative "../storage_get_public_access_prevention" require_relative "../storage_get_requester_pays_status" require_relative "../storage_get_retention_policy" @@ -45,12 +45,12 @@ require_relative "../storage_list_buckets" require_relative "../storage_list_buckets_with_partial_success" require_relative "../storage_lock_retention_policy" +require_relative "../storage_remove_all_bucket_encryption_enforcement_config" require_relative "../storage_remove_bucket_label" require_relative "../storage_remove_cors_configuration" require_relative "../storage_remove_retention_policy" require_relative "../storage_set_bucket_default_kms_key" -require_relative "../storage_set_encryption_enforcement_config" -require_relative "../storage_remove_all_encryption_enforcement_config" +require_relative "../storage_set_bucket_encryption_enforcement_config" require_relative "../storage_set_object_retention_policy" require_relative "../storage_set_public_access_prevention_enforced" require_relative "../storage_set_public_access_prevention_inherited" @@ -172,7 +172,7 @@ end end - describe "storage_encryption_enforcement_config" do + describe "storage_bucket_encryption_enforcement_config" do bucket_name = random_bucket_name it "gets, sets and clears bucket encryption enforcement config" do @@ -181,7 +181,7 @@ retry_resource_exhaustion do assert_output expected do - set_encryption_enforcement_config bucket_name: bucket_name + set_bucket_encryption_enforcement_config bucket_name: bucket_name end end @@ -192,7 +192,7 @@ "Google-managed encryption enforcement config restriction mode: FullyRestricted\n" retry_resource_exhaustion do assert_output expected do - get_encryption_enforcement_config bucket_name: bucket_name + get_bucket_encryption_enforcement_config bucket_name: bucket_name end end @@ -201,7 +201,7 @@ retry_resource_exhaustion do assert_output expected do - remove_all_encryption_enforcement_config bucket_name: bucket_name + remove_all_bucket_encryption_enforcement_config bucket_name: bucket_name end end diff --git a/google-cloud-storage/samples/storage_get_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_get_bucket_encryption_enforcement_config.rb similarity index 84% rename from google-cloud-storage/samples/storage_get_encryption_enforcement_config.rb rename to google-cloud-storage/samples/storage_get_bucket_encryption_enforcement_config.rb index 652610cc4553..c79911104e2b 100644 --- a/google-cloud-storage/samples/storage_get_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_get_bucket_encryption_enforcement_config.rb @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# [START storage_get_encryption_enforcement_config] -def get_encryption_enforcement_config bucket_name: +# [START storage_get_bucket_encryption_enforcement_config] +def get_bucket_encryption_enforcement_config bucket_name: # The ID to give your GCS bucket # bucket_name = "your-unique-bucket-name" @@ -29,8 +29,8 @@ def get_encryption_enforcement_config bucket_name: puts "Google-managed encryption enforcement config restriction mode: " \ "#{bucket.google_managed_encryption_enforcement_config&.restriction_mode}" end -# [END storage_get_encryption_enforcement_config] +# [END storage_get_bucket_encryption_enforcement_config] if $PROGRAM_NAME == __FILE__ - get_encryption_enforcement_config bucket_name: ARGV.shift + get_bucket_encryption_enforcement_config bucket_name: ARGV.shift end diff --git a/google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_remove_all_bucket_encryption_enforcement_config.rb similarity index 79% rename from google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb rename to google-cloud-storage/samples/storage_remove_all_bucket_encryption_enforcement_config.rb index 781e86c48451..3f577a5b1769 100644 --- a/google-cloud-storage/samples/storage_remove_all_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_remove_all_bucket_encryption_enforcement_config.rb @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# [START storage_remove_all_encryption_enforcement_config] -def remove_all_encryption_enforcement_config bucket_name: +# [START storage_remove_all_bucket_encryption_enforcement_config] +def remove_all_bucket_encryption_enforcement_config bucket_name: # The ID to give your GCS bucket # bucket_name = "your-unique-bucket-name" @@ -27,8 +27,8 @@ def remove_all_encryption_enforcement_config bucket_name: end puts "Removed Encryption Enforcement Config from bucket #{bucket.name}." end -# [END storage_remove_all_encryption_enforcement_config] +# [END storage_remove_all_bucket_encryption_enforcement_config] if $PROGRAM_NAME == __FILE__ - remove_all_encryption_enforcement_config bucket_name: ARGV.shift + remove_all_bucket_encryption_enforcement_config bucket_name: ARGV.shift end diff --git a/google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb similarity index 87% rename from google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb rename to google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb index 391f67e7af4b..65c305a41301 100644 --- a/google-cloud-storage/samples/storage_set_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# [START storage_set_encryption_enforcement_config] -def set_encryption_enforcement_config bucket_name: +# [START storage_set_bucket_encryption_enforcement_config] +def set_bucket_encryption_enforcement_config bucket_name: # The ID to give your GCS bucket # bucket_name = "your-unique-bucket-name" @@ -41,8 +41,8 @@ def set_encryption_enforcement_config bucket_name: end puts "Created bucket #{bucket.name} with Encryption Enforcement Config." end -# [END storage_set_encryption_enforcement_config] +# [END storage_set_bucket_encryption_enforcement_config] if $PROGRAM_NAME == __FILE__ - set_encryption_enforcement_config bucket_name: ARGV.shift + set_bucket_encryption_enforcement_config bucket_name: ARGV.shift end From 36589794835f6f48801e3980e526eb823ede3ac8 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Wed, 25 Mar 2026 19:18:14 +0000 Subject: [PATCH 05/28] adding update functionality --- .../lib/google/cloud/storage/bucket.rb | 32 ++++++++++++++++--- .../samples/acceptance/buckets_test.rb | 11 ++++++- ...e_bucket_encryption_enforcement_config.rb} | 28 +++++++++++++--- 3 files changed, 61 insertions(+), 10 deletions(-) rename google-cloud-storage/samples/{storage_remove_all_bucket_encryption_enforcement_config.rb => storage_update_bucket_encryption_enforcement_config.rb} (53%) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 17e6bae808f7..56120d72d0d6 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -749,10 +749,27 @@ def customer_managed_encryption_enforcement_config def customer_managed_encryption_enforcement_config= new_customer_managed_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new @gapi.encryption.customer_managed_encryption_enforcement_config = - new_customer_managed_encryption_enforcement_config + new_customer_managed_encryption_enforcement_config || {} patch_gapi! :encryption end + def update_bucket_encryption_enforcement_config incoming_config + attr_name = case incoming_config + when Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig + :google_managed_encryption_enforcement_config + when Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig + :customer_managed_encryption_enforcement_config + when Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig + :customer_supplied_encryption_enforcement_config + else + raise ArgumentError, "Unsupported config type: #{incoming_config.class}" + end + encryption_patch = Google::Apis::StorageV1::Bucket::Encryption.new + encryption_patch.public_send "#{attr_name}=", incoming_config + patch_gapi! :encryption, bucket_encryption_config: encryption_patch + end + + ## # The bucket's encryption configuration for customer-supplied encryption keys. This configuration defines the # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements @@ -788,7 +805,7 @@ def customer_supplied_encryption_enforcement_config def customer_supplied_encryption_enforcement_config= new_customer_supplied_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new @gapi.encryption.customer_supplied_encryption_enforcement_config = - new_customer_supplied_encryption_enforcement_config + new_customer_supplied_encryption_enforcement_config || {} patch_gapi! :encryption end @@ -828,7 +845,7 @@ def google_managed_encryption_enforcement_config def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new @gapi.encryption.google_managed_encryption_enforcement_config = - new_google_managed_encryption_enforcement_config + new_google_managed_encryption_enforcement_config || {} patch_gapi! :encryption end @@ -3367,13 +3384,18 @@ def ensure_gapi! def patch_gapi! attributes, if_metageneration_match: nil, - if_metageneration_not_match: nil + if_metageneration_not_match: nil, + bucket_encryption_config: nil attributes = Array(attributes) attributes.flatten! return if attributes.empty? ensure_service! patch_args = attributes.to_h do |attr| - [attr, @gapi.send(attr)] + if bucket_encryption_config + [attr, bucket_encryption_config] + else + [attr, @gapi.send(attr)] + end end patch_gapi = API::Bucket.new(**patch_args) @gapi = service.patch_bucket name, diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index ba9ff0c56781..cd6eb5a6da20 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -45,7 +45,7 @@ require_relative "../storage_list_buckets" require_relative "../storage_list_buckets_with_partial_success" require_relative "../storage_lock_retention_policy" -require_relative "../storage_remove_all_bucket_encryption_enforcement_config" +require_relative "../storage_update_bucket_encryption_enforcement_config" require_relative "../storage_remove_bucket_label" require_relative "../storage_remove_cors_configuration" require_relative "../storage_remove_retention_policy" @@ -196,6 +196,15 @@ end end + # update encryption enforcement config + expected = "Updated google_managed_config to NotRestricted for bucket #{bucket_name}.\n" + + retry_resource_exhaustion do + assert_output expected do + update_bucket_encryption_enforcement_config bucket_name: bucket_name, bucket_encryption_type: "google_managed_config", restriction_mode: "NotRestricted" + end + end + # clears encryption enforcement config expected = "Removed Encryption Enforcement Config from bucket #{bucket_name}.\n" diff --git a/google-cloud-storage/samples/storage_remove_all_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb similarity index 53% rename from google-cloud-storage/samples/storage_remove_all_bucket_encryption_enforcement_config.rb rename to google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index 3f577a5b1769..7976ab7a9943 100644 --- a/google-cloud-storage/samples/storage_remove_all_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -# [START storage_remove_all_bucket_encryption_enforcement_config] +require "google/cloud/storage" + +# [START storage_update_bucket_encryption_enforcement_config] def remove_all_bucket_encryption_enforcement_config bucket_name: # The ID to give your GCS bucket # bucket_name = "your-unique-bucket-name" - require "google/cloud/storage" - storage = Google::Cloud::Storage.new bucket = storage.bucket bucket_name do |b| b.customer_managed_encryption_enforcement_config = nil @@ -27,8 +27,28 @@ def remove_all_bucket_encryption_enforcement_config bucket_name: end puts "Removed Encryption Enforcement Config from bucket #{bucket.name}." end -# [END storage_remove_all_bucket_encryption_enforcement_config] + +def update_bucket_encryption_enforcement_config bucket_name:, bucket_encryption_type:, restriction_mode: + # The ID to give your GCS bucket + # bucket_name = "your-unique-bucket-name" + + google_managed_config = + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: restriction_mode + ) + + storage = Google::Cloud::Storage.new + bucket = storage.bucket bucket_name + # assuming bucket_encryption_type = google_managed_config + bucket.update_bucket_encryption_enforcement_config google_managed_config + + puts "Updated #{bucket_encryption_type} to #{bucket.google_managed_encryption_enforcement_config.restriction_mode} for bucket #{bucket.name}." +end +# [END storage_update_bucket_encryption_enforcement_config] if $PROGRAM_NAME == __FILE__ remove_all_bucket_encryption_enforcement_config bucket_name: ARGV.shift end +if $PROGRAM_NAME == __FILE__ + update_bucket_encryption_enforcement_config bucket_name: ARGV.shift, bucket_encryption_type: ARGV.shift, restriction_mode: ARGV.shift +end From 221d38bf434ca155f67e21157ed9f942ba86ce19 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Sun, 29 Mar 2026 20:06:26 +0000 Subject: [PATCH 06/28] adding tests --- .../storage/bucket_encryption_test.rb | 68 +++++++++++- .../lib/google/cloud/storage/bucket.rb | 16 +++ .../cloud/storage/bucket_encryption_test.rb | 105 ++++++++++++++++++ 3 files changed, 185 insertions(+), 4 deletions(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 7760e2107ed8..49bb905bcec2 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -16,18 +16,32 @@ describe Google::Cloud::Storage::Bucket, :encryption, :storage do let(:bucket_name) { "#{$bucket_names[1]}-encryption" } - let(:bucket_location) { "us-central1" } + let(:bucket_location) { "us-west1" } let(:kms_key) { ENV["GCLOUD_TEST_STORAGE_KMS_KEY_1"] || - "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/ruby-test/cryptoKeys/ruby-test-key-1" + "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/kms-kr/cryptoKeys/key1" } let(:kms_key_2) { ENV["GCLOUD_TEST_STORAGE_KMS_KEY_2"] || - "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/ruby-test/cryptoKeys/ruby-test-key-2" + "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/kms-kr/cryptoKeys/key2" } + let(:customer_managed_config) {Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( + restriction_mode: "NotRestricted" + ) + } + let(:customer_supplied_config) {Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + } + let(:google_managed_config) {Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + } + let :bucket do - b = safe_gcs_execute { storage.create_bucket(bucket_name, location: bucket_location) } + b = safe_gcs_execute { storage.bucket(bucket_name) || storage.create_bucket(bucket_name, location: bucket_location) } b.default_kms_key = kms_key + b.customer_managed_encryption_enforcement_config = customer_managed_config b end @@ -71,4 +85,50 @@ _(bucket.default_kms_key).must_be :nil? end end + + describe "Encryption Enforcement Config" do + it "knows its encryption enforcement config" do + _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + bucket.reload! + _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + end + + it "updates encryption enforcement configs" do + _(bucket.customer_supplied_encryption_enforcement_config).must_be :nil? + + bucket.customer_supplied_encryption_enforcement_config = customer_supplied_config + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + + bucket.update_bucket_encryption_enforcement_config google_managed_config + _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + + bucket.reload! + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + end + + it "deletes all encryption enforcement configs" do + bucket.update do |b| + b.customer_supplied_encryption_enforcement_config = customer_supplied_config + b.google_managed_encryption_enforcement_config = google_managed_config + end + + _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? + _(bucket.customer_supplied_encryption_enforcement_config).wont_be :nil? + _(bucket.google_managed_encryption_enforcement_config).wont_be :nil? + + bucket.update do |b| + b.customer_managed_encryption_enforcement_config = nil + b.customer_supplied_encryption_enforcement_config = nil + b.google_managed_encryption_enforcement_config = nil + end + # Removed all encryption enforcement configs without removing default_kms_key + _(bucket.customer_managed_encryption_enforcement_config).must_be :nil? + _(bucket.customer_supplied_encryption_enforcement_config).must_be :nil? + _(bucket.google_managed_encryption_enforcement_config).must_be :nil? + _(bucket.default_kms_key).must_equal kms_key + end + end end diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 56120d72d0d6..ec37175437a1 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -753,6 +753,22 @@ def customer_managed_encryption_enforcement_config= new_customer_managed_encrypt patch_gapi! :encryption end + ## + # Updates the bucket's encryption enforcement configuration. + # + # @param [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig] incoming_config The new encryption enforcement configuration to apply. + # + # @raise [ArgumentError] If the provided config type is unsupported. + # + # @example + # require "google/cloud/storage" + # + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # + # new_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # bucket.update_bucket_encryption_enforcement_config new_config + # def update_bucket_encryption_enforcement_config incoming_config attr_name = case incoming_config when Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index 9e84cd78e4f8..d93d662b8a48 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -123,6 +123,111 @@ end end + describe "encryption enforcement config" do + let(:customer_managed_encryption) { Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" } + let(:customer_supplied_encryption) { Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" } + let(:google_managed_encryption) { Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" } + let(:bucket_encryption) do + Google::Apis::StorageV1::Bucket::Encryption.new( + customer_managed_encryption_enforcement_config: customer_managed_encryption, + customer_supplied_encryption_enforcement_config: customer_supplied_encryption, + google_managed_encryption_enforcement_config: google_managed_encryption + ) + end + + let(:bucket_gapi) do + b = Google::Apis::StorageV1::Bucket.from_json bucket_json + b.encryption = bucket_encryption + b.encryption.default_kms_key_name = kms_key + b + end + + it "knows its encryption enforcement config" do + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + end + + it "updates encryption_enforcement_config using update_bucket_encryption_enforcement_config" do + mock = Minitest::Mock.new + incoming_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + + patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new( + encryption: Google::Apis::StorageV1::Bucket::Encryption.new( + google_managed_encryption_enforcement_config: incoming_config + ) + ) + + returned_bucket_gapi = bucket_gapi.dup + returned_bucket_gapi.encryption = bucket_gapi.encryption.dup + returned_bucket_gapi.encryption.google_managed_encryption_enforcement_config = incoming_config + mock.expect :patch_bucket, returned_bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: { retries: 0 }) + + bucket.service.mocked_service = mock + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + + bucket.update_bucket_encryption_enforcement_config incoming_config + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + + mock.verify + end + + it "raises error on invalid config using update_bucket_encryption_enforcement_config" do + expect { + bucket.update_bucket_encryption_enforcement_config "invalid config" + }.must_raise ArgumentError + end + + it "deletes all encryption enforcement configs together and preserves default_kms_key" do + mock = Minitest::Mock.new + + initial_bucket_gapi = bucket_gapi.dup + initial_bucket_gapi.encryption = bucket_encryption.dup + initial_bucket_gapi.encryption.default_kms_key_name = kms_key + + bucket_with_configs_and_key = Google::Cloud::Storage::Bucket.from_gapi initial_bucket_gapi, storage.service + + returned_bucket_gapi = bucket_gapi.dup + returned_bucket_gapi.encryption = Google::Apis::StorageV1::Bucket::Encryption.new default_kms_key_name: kms_key + + mock.expect :update_bucket, returned_bucket_gapi do |name, patch_obj, **kwargs| + cm_config = patch_obj.encryption.customer_managed_encryption_enforcement_config + cs_config = patch_obj.encryption.customer_supplied_encryption_enforcement_config + gm_config = patch_obj.encryption.google_managed_encryption_enforcement_config + + name == bucket_name && + (cm_config == {} || cm_config.nil?) && + (cs_config == {} || cs_config.nil?) && + (gm_config == {} || gm_config.nil?) && + patch_obj.encryption.default_kms_key_name == kms_key + end + + bucket_with_configs_and_key.service.mocked_service = mock + + _(bucket_with_configs_and_key.customer_managed_encryption_enforcement_config).wont_be :nil? + _(bucket_with_configs_and_key.customer_supplied_encryption_enforcement_config).wont_be :nil? + _(bucket_with_configs_and_key.google_managed_encryption_enforcement_config).wont_be :nil? + _(bucket_with_configs_and_key.default_kms_key).must_equal kms_key + + bucket_with_configs_and_key.update do |b| + b.customer_managed_encryption_enforcement_config = nil + b.customer_supplied_encryption_enforcement_config = nil + b.google_managed_encryption_enforcement_config = nil + end + + _(bucket_with_configs_and_key.customer_managed_encryption_enforcement_config).must_be :nil? + _(bucket_with_configs_and_key.customer_supplied_encryption_enforcement_config).must_be :nil? + _(bucket_with_configs_and_key.google_managed_encryption_enforcement_config).must_be :nil? + _(bucket_with_configs_and_key.default_kms_key).must_equal kms_key + + mock.verify + end + end + def create_file_gapi bucket=nil, name = nil Google::Apis::StorageV1::Object.from_json random_file_hash(bucket, name).to_json end From a0ddae38b458f705f2222773c67b6407a1556bd6 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Sun, 29 Mar 2026 20:22:30 +0000 Subject: [PATCH 07/28] fixing rubocop issue --- ...ate_bucket_encryption_enforcement_config.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index 7976ab7a9943..dde3b0e20996 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -20,7 +20,8 @@ def remove_all_bucket_encryption_enforcement_config bucket_name: # bucket_name = "your-unique-bucket-name" storage = Google::Cloud::Storage.new - bucket = storage.bucket bucket_name do |b| + bucket = storage.bucket bucket_name + bucket.update do |b| b.customer_managed_encryption_enforcement_config = nil b.customer_supplied_encryption_enforcement_config = nil b.google_managed_encryption_enforcement_config = nil @@ -42,13 +43,18 @@ def update_bucket_encryption_enforcement_config bucket_name:, bucket_encryption_ # assuming bucket_encryption_type = google_managed_config bucket.update_bucket_encryption_enforcement_config google_managed_config - puts "Updated #{bucket_encryption_type} to #{bucket.google_managed_encryption_enforcement_config.restriction_mode} for bucket #{bucket.name}." + puts "Updated #{bucket_encryption_type} to " \ + "#{bucket.google_managed_encryption_enforcement_config.restriction_mode} " \ + "for bucket #{bucket.name}." end # [END storage_update_bucket_encryption_enforcement_config] if $PROGRAM_NAME == __FILE__ - remove_all_bucket_encryption_enforcement_config bucket_name: ARGV.shift -end -if $PROGRAM_NAME == __FILE__ - update_bucket_encryption_enforcement_config bucket_name: ARGV.shift, bucket_encryption_type: ARGV.shift, restriction_mode: ARGV.shift + case ARGV.length + when 1 + remove_all_bucket_encryption_enforcement_config bucket_name: ARGV.shift + when 3 + update_bucket_encryption_enforcement_config bucket_name: ARGV.shift, bucket_encryption_type: ARGV.shift, + restriction_mode: ARGV.shift + end end From 87a5e377216db95d50a87c0b9144de315e40dab2 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 03:11:01 +0000 Subject: [PATCH 08/28] removing unwanted code --- .../storage/bucket_encryption_test.rb | 27 ++++--- .../lib/google/cloud/storage/bucket.rb | 7 +- ...te_bucket_encryption_enforcement_config.rb | 19 +++-- .../test/google/cloud/storage/project_test.rb | 75 ------------------- 4 files changed, 31 insertions(+), 97 deletions(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 49bb905bcec2..0c8733337898 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -25,18 +25,21 @@ ENV["GCLOUD_TEST_STORAGE_KMS_KEY_2"] || "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/kms-kr/cryptoKeys/key2" } - let(:customer_managed_config) {Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( - restriction_mode: "NotRestricted" - ) - } - let(:customer_supplied_config) {Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( - restriction_mode: "FullyRestricted" - ) - } - let(:google_managed_config) {Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( - restriction_mode: "FullyRestricted" - ) - } + let(:customer_managed_config) do + Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( + restriction_mode: "NotRestricted" + ) + end + let(:customer_supplied_config) do + Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + end + let(:google_managed_config) do + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + end let :bucket do b = safe_gcs_execute { storage.bucket(bucket_name) || storage.create_bucket(bucket_name, location: bucket_location) } diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index ec37175437a1..f5797ac4cef2 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -716,7 +716,7 @@ def default_kms_key= new_default_kms_key default_kms_key_name: new_default_kms_key patch_gapi! :encryption end - + ## # The bucket's encryption configuration for customer-managed encryption keys. # This configuration defines the # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements for the bucket. @@ -734,7 +734,7 @@ def default_kms_key= new_default_kms_key def customer_managed_encryption_enforcement_config @gapi.encryption&.customer_managed_encryption_enforcement_config end - + ## # Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files. # @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] new_customer_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. # @example @@ -854,8 +854,7 @@ def google_managed_encryption_enforcement_config # # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" - # bucket.google_managed_encryption_enforcement_config = new_config + # new_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" # bucket.google_managed_encryption_enforcement_config = new_config # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index dde3b0e20996..90b9fa38d0e8 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -33,15 +33,22 @@ def update_bucket_encryption_enforcement_config bucket_name:, bucket_encryption_ # The ID to give your GCS bucket # bucket_name = "your-unique-bucket-name" - google_managed_config = - Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( - restriction_mode: restriction_mode - ) + config_class = case bucket_encryption_type + when "google_managed_config" + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig + when "customer_managed_config" + Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig + when "customer_supplied_config" + Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig + else + puts "Unsupported bucket_encryption_type: #{bucket_encryption_type}" + return + end + new_config = config_class.new restriction_mode: restriction_mode storage = Google::Cloud::Storage.new bucket = storage.bucket bucket_name - # assuming bucket_encryption_type = google_managed_config - bucket.update_bucket_encryption_enforcement_config google_managed_config + bucket.update_bucket_encryption_enforcement_config new_config puts "Updated #{bucket_encryption_type} to " \ "#{bucket.google_managed_encryption_enforcement_config.restriction_mode} " \ 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 052c3a77f184..0e29038eda3d 100644 --- a/google-cloud-storage/test/google/cloud/storage/project_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/project_test.rb @@ -1090,81 +1090,6 @@ def stub.insert_bucket *args _(buckets.unreachable).must_be :nil? end - describe "storage encryption enforcement config" do - # set and get customer managed encryption enforcement config and verify - it "sets and gets customer managed bucket encryption enforcement config" do - mock = Minitest::Mock.new - created_bucket = create_bucket_gapi bucket_name - created_bucket.encryption = encryption_gapi(customer_managed_config_restriction_mode: "NotRestricted") - resp_bucket = bucket_with_location created_bucket - mock.expect :insert_bucket, resp_bucket, [project, created_bucket], predefined_acl: nil, predefined_default_object_acl: nil, user_project: nil, enable_object_retention: nil, options: {} - storage.service.mocked_service = mock - bucket = storage.create_bucket bucket_name do |b| - # set customer managed encryption enforcement config - b.customer_managed_encryption_enforcement_config = customer_managed_config(restriction_mode: "NotRestricted") - end - mock.verify - # get customer managed encryption enforcement config and verify - _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? - _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" - end - - # set customer supplied and google managed encryption enforcement config and verify - it "sets customer supplied and google managed bucket encryption enforcement config" do - mock = Minitest::Mock.new - created_bucket = create_bucket_gapi bucket_name - created_bucket.encryption = encryption_gapi(customer_supplied_config_restriction_mode: "FullyRestricted", google_managed_config_restriction_mode: "NotRestricted" ) - resp_bucket = bucket_with_location created_bucket - mock.expect :insert_bucket, resp_bucket, [project, created_bucket], predefined_acl: nil, predefined_default_object_acl: nil, user_project: nil, enable_object_retention: nil, options: {} - storage.service.mocked_service = mock - - # set customer supplied and google managed encryption enforcement config - bucket = storage.create_bucket bucket_name do |b| - b.customer_supplied_encryption_enforcement_config = customer_supplied_config(restriction_mode: "FullyRestricted") - b.google_managed_encryption_enforcement_config = google_managed_config(restriction_mode: "NotRestricted" ) - end - mock.verify - # get customer supplied and google managed encryption enforcement config and verify - _(bucket.customer_supplied_encryption_enforcement_config).wont_be :nil? - _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" - _(bucket.customer_managed_encryption_enforcement_config).must_be :nil? - end - - # delete customer supplied encryption enforcement config and verify - it "deletes customer supplied encryption enforcement config" do - mock = Minitest::Mock.new - - created_bucket = create_bucket_gapi bucket_name - # Set initial state: FullyRestricted - created_bucket.encryption = encryption_gapi(customer_supplied_config_restriction_mode: "FullyRestricted") - resp_bucket = bucket_with_location created_bucket - - mock.expect :insert_bucket, resp_bucket do |project_id, b_arg, **kwargs| - project_id == project && - b_arg.encryption.customer_supplied_encryption_enforcement_config.restriction_mode == "FullyRestricted" - end - - # Define what the bucket should look like AFTER the delete (config should be nil) - updated_bucket_gapi = create_bucket_gapi bucket_name - updated_bucket_gapi.encryption = encryption_gapi(customer_supplied_config_restriction_mode: nil) - - # We verify that the patch_bucket call is made with a bucket that has NO config - mock.expect :patch_bucket, updated_bucket_gapi do |name, b_arg, **kwargs| - name == bucket_name && - b_arg.encryption.customer_supplied_encryption_enforcement_config.nil? - end - storage.service.mocked_service = mock - - # Create the bucket - bucket = storage.create_bucket bucket_name do |b| - b.customer_supplied_encryption_enforcement_config = customer_supplied_config(restriction_mode: "FullyRestricted") - end - # Perform the deletion - bucket.customer_supplied_encryption_enforcement_config = nil - mock.verify - _(bucket.customer_supplied_encryption_enforcement_config).must_be :nil? - end - end def bucket_with_location created_bucket, location_type: bucket_location_type From d01e6d1dfc11bd1adcea77af7ad6cb3412600e6a Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 05:40:53 +0000 Subject: [PATCH 09/28] updating update sample --- .../storage/bucket_encryption_test.rb | 6 +-- .../samples/acceptance/buckets_test.rb | 13 +---- ...te_bucket_encryption_enforcement_config.rb | 47 +++++-------------- .../test/google/cloud/storage/project_test.rb | 1 - google-cloud-storage/test/helper.rb | 12 ----- 5 files changed, 16 insertions(+), 63 deletions(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 0c8733337898..377a96c33efa 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -16,14 +16,14 @@ describe Google::Cloud::Storage::Bucket, :encryption, :storage do let(:bucket_name) { "#{$bucket_names[1]}-encryption" } - let(:bucket_location) { "us-west1" } + let(:bucket_location) { "us-central1" } let(:kms_key) { ENV["GCLOUD_TEST_STORAGE_KMS_KEY_1"] || - "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/kms-kr/cryptoKeys/key1" + "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/ruby-test/cryptoKeys/ruby-test-key-1" } let(:kms_key_2) { ENV["GCLOUD_TEST_STORAGE_KMS_KEY_2"] || - "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/kms-kr/cryptoKeys/key2" + "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/ruby-test/cryptoKeys/ruby-test-key-2" } let(:customer_managed_config) do Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index cd6eb5a6da20..a8a9326a5e41 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -175,7 +175,7 @@ describe "storage_bucket_encryption_enforcement_config" do bucket_name = random_bucket_name - it "gets, sets and clears bucket encryption enforcement config" do + it "gets, sets and updates bucket encryption enforcement config" do # creates bucket with encryption enforcement config expected = "Created bucket #{bucket_name} with Encryption Enforcement Config.\n" @@ -201,16 +201,7 @@ retry_resource_exhaustion do assert_output expected do - update_bucket_encryption_enforcement_config bucket_name: bucket_name, bucket_encryption_type: "google_managed_config", restriction_mode: "NotRestricted" - end - end - - # clears encryption enforcement config - expected = "Removed Encryption Enforcement Config from bucket #{bucket_name}.\n" - - retry_resource_exhaustion do - assert_output expected do - remove_all_bucket_encryption_enforcement_config bucket_name: bucket_name + update_bucket_encryption_enforcement_config bucket_name: bucket_name end end diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index 90b9fa38d0e8..defb498b57d1 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -15,53 +15,28 @@ require "google/cloud/storage" # [START storage_update_bucket_encryption_enforcement_config] -def remove_all_bucket_encryption_enforcement_config bucket_name: - # The ID to give your GCS bucket - # bucket_name = "your-unique-bucket-name" - - storage = Google::Cloud::Storage.new - bucket = storage.bucket bucket_name - bucket.update do |b| - b.customer_managed_encryption_enforcement_config = nil - b.customer_supplied_encryption_enforcement_config = nil - b.google_managed_encryption_enforcement_config = nil - end - puts "Removed Encryption Enforcement Config from bucket #{bucket.name}." -end -def update_bucket_encryption_enforcement_config bucket_name:, bucket_encryption_type:, restriction_mode: +def update_bucket_encryption_enforcement_config bucket_name: # The ID to give your GCS bucket # bucket_name = "your-unique-bucket-name" - config_class = case bucket_encryption_type - when "google_managed_config" - Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig - when "customer_managed_config" - Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig - when "customer_supplied_config" - Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig - else - puts "Unsupported bucket_encryption_type: #{bucket_encryption_type}" - return - end - new_config = config_class.new restriction_mode: restriction_mode - storage = Google::Cloud::Storage.new bucket = storage.bucket bucket_name - bucket.update_bucket_encryption_enforcement_config new_config + + # Update a specific type (e.g., change GMEK to NotRestricted) + google_managed_config = + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: "NotRestricted" + ) + + bucket.update_bucket_encryption_enforcement_config google_managed_config - puts "Updated #{bucket_encryption_type} to " \ + puts "Updated google_managed_config to " \ "#{bucket.google_managed_encryption_enforcement_config.restriction_mode} " \ "for bucket #{bucket.name}." end # [END storage_update_bucket_encryption_enforcement_config] if $PROGRAM_NAME == __FILE__ - case ARGV.length - when 1 - remove_all_bucket_encryption_enforcement_config bucket_name: ARGV.shift - when 3 - update_bucket_encryption_enforcement_config bucket_name: ARGV.shift, bucket_encryption_type: ARGV.shift, - restriction_mode: ARGV.shift - end + update_bucket_encryption_enforcement_config bucket_name: ARGV.shift end 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 0e29038eda3d..c07bff384157 100644 --- a/google-cloud-storage/test/google/cloud/storage/project_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/project_test.rb @@ -1090,7 +1090,6 @@ def stub.insert_bucket *args _(buckets.unreachable).must_be :nil? end - def bucket_with_location created_bucket, location_type: bucket_location_type resp_bucket = created_bucket.dup diff --git a/google-cloud-storage/test/helper.rb b/google-cloud-storage/test/helper.rb index 52bf1b2e0a88..cb73937a2eda 100644 --- a/google-cloud-storage/test/helper.rb +++ b/google-cloud-storage/test/helper.rb @@ -263,18 +263,6 @@ def encryption_gapi(key_name: nil, Google::Apis::StorageV1::Bucket::Encryption.new(**params) end - def customer_managed_config restriction_mode: nil - Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: restriction_mode - end - - def customer_supplied_config restriction_mode: nil - Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: restriction_mode - end - - def google_managed_config restriction_mode: nil - Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: restriction_mode - end - def lifecycle_gapi *rules Google::Apis::StorageV1::Bucket::Lifecycle.new rule: Array(rules) end From a21d625cd159ab071344cfe8a0b42161551b2cfb Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 06:35:17 +0000 Subject: [PATCH 10/28] update --- .../acceptance/storage/bucket_encryption_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 377a96c33efa..9de2340ff906 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -113,6 +113,7 @@ end it "deletes all encryption enforcement configs" do + # For the update, need to specify all three configs bucket.update do |b| b.customer_supplied_encryption_enforcement_config = customer_supplied_config b.google_managed_encryption_enforcement_config = google_managed_config From 2d5b5e3bb7c2ddedffb7107eb8db66acf874b1fa Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 14:47:28 +0530 Subject: [PATCH 11/28] Remove unnecessary line in bucket encryption test --- .../acceptance/storage/bucket_encryption_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 9de2340ff906..a675e347c479 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -118,7 +118,6 @@ b.customer_supplied_encryption_enforcement_config = customer_supplied_config b.google_managed_encryption_enforcement_config = google_managed_config end - _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? _(bucket.customer_supplied_encryption_enforcement_config).wont_be :nil? _(bucket.google_managed_encryption_enforcement_config).wont_be :nil? From 67e25f90111a7833f6eebcec785bb1dc57c23cd8 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 09:54:59 +0000 Subject: [PATCH 12/28] fix --- google-cloud-storage/acceptance/storage/file_encryption_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-storage/acceptance/storage/file_encryption_test.rb b/google-cloud-storage/acceptance/storage/file_encryption_test.rb index 70665da0de1b..f7dbdb2d2c6a 100644 --- a/google-cloud-storage/acceptance/storage/file_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/file_encryption_test.rb @@ -22,7 +22,7 @@ let(:bucket_location) { "us-central1" } let :bucket do - safe_gcs_execute {storage.create_bucket bucket_name, location: bucket_location } + safe_gcs_execute { storage.bucket(bucket_name) || storage.create_bucket(bucket_name, location: bucket_location) } end let(:file_path) { "acceptance/data/abc.txt" } From 69e6fd980a97c151be8becb3ed321ecc871cdda9 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 17:11:24 +0530 Subject: [PATCH 13/28] Remove blank line in bucket.rb Removed an unnecessary blank line before the encryption configuration documentation. --- google-cloud-storage/lib/google/cloud/storage/bucket.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index f5797ac4cef2..265d1c98019e 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -785,7 +785,6 @@ def update_bucket_encryption_enforcement_config incoming_config patch_gapi! :encryption, bucket_encryption_config: encryption_patch end - ## # The bucket's encryption configuration for customer-supplied encryption keys. This configuration defines the # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements From f88d02e896678c7eb44dd316e5629d3d185de0e5 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 17:45:34 +0530 Subject: [PATCH 14/28] Clean up comments in bucket.rb Removed unnecessary comment line in bucket.rb --- google-cloud-storage/lib/google/cloud/storage/bucket.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 265d1c98019e..bd2f637a00d2 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -794,7 +794,7 @@ def update_bucket_encryption_enforcement_config incoming_config # The bucket's encryption configuration, or `nil` if no encryption configuration has been set. # @example # require "google/cloud/storage" - # # + # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" # bucket.customer_supplied_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new From 27632c6820894922fd5fcd8b0c1a86b390925ce2 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 17:59:53 +0530 Subject: [PATCH 15/28] Clean up comments in bucket.rb Removed unnecessary comment line in bucket.rb. --- google-cloud-storage/lib/google/cloud/storage/bucket.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index bd2f637a00d2..f7cb2bf0cabf 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -810,7 +810,7 @@ def customer_supplied_encryption_enforcement_config # @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] new_customer_supplied_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. # @example # require "google/cloud/storage" - # # + # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" From 794c7cc7a6aa12e14ac42c9f076a26ca5b941b8d Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 30 Mar 2026 18:29:42 +0530 Subject: [PATCH 16/28] Clean up comments in bucket.rb Removed unnecessary comment line in bucket.rb --- google-cloud-storage/lib/google/cloud/storage/bucket.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index f7cb2bf0cabf..193531385bd9 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -834,7 +834,7 @@ def customer_supplied_encryption_enforcement_config= new_customer_supplied_encry # The bucket's encryption configuration, or `nil` if no encryption configuration has been set. # @example # require "google/cloud/storage" - # # + # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" # bucket.google_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new From d7a5cca0cc53a1b8cd5417199c065f9e8f06bcf6 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 31 Mar 2026 12:15:02 +0530 Subject: [PATCH 17/28] Remove unnecessary line in encryption config update --- .../storage_update_bucket_encryption_enforcement_config.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index defb498b57d1..94ccf320d044 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -28,7 +28,6 @@ def update_bucket_encryption_enforcement_config bucket_name: Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( restriction_mode: "NotRestricted" ) - bucket.update_bucket_encryption_enforcement_config google_managed_config puts "Updated google_managed_config to " \ From 36ea00e897819f9dc2941139d2ec45b782b4f6fe Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 31 Mar 2026 16:16:50 +0530 Subject: [PATCH 18/28] blank commit --- .../test/google/cloud/storage/bucket_encryption_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index d93d662b8a48..8082a8a4f191 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -22,7 +22,6 @@ let(:bucket) { Google::Cloud::Storage::Bucket.from_gapi bucket_gapi, storage.service } let(:kms_key) { "path/to/encryption_key_name" } - describe "customer-supplied encryption key (CSEK)" do let(:encryption_key) { "y\x03\"\x0E\xB6\xD3\x9B\x0E\xAB*\x19\xFAv\xDEY\xBEI\xF8ftA|[z\x1A\xFBE\xDE\x97&\xBC\xC7" } let(:encryption_key_sha256) { "5\x04_\xDF\x1D\x8A_d\xFEK\e6p[XZz\x13s]E\xF6\xBB\x10aQH\xF6o\x14f\xF9" } From 88c4b82b47fac6d5e42002584a430119bcac92b4 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Thu, 2 Apr 2026 09:21:57 +0000 Subject: [PATCH 19/28] updating tests --- .../cloud/storage/bucket_encryption_test.rb | 25 ++++++++++--------- google-cloud-storage/test/helper.rb | 20 ++++++++++++++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index 8082a8a4f191..4a1e7767dc24 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -89,10 +89,14 @@ bucket_gapi_with_key = bucket_gapi.dup bucket_gapi_with_key.encryption = encryption_gapi(key_name: kms_key) bucket_with_key = Google::Cloud::Storage::Bucket.from_gapi bucket_gapi_with_key, storage.service + patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(key_name: kms_key) + patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new( + encryption: Google::Apis::StorageV1::Bucket::Encryption.new( + default_kms_key_name: nil + ) + ) mock = Minitest::Mock.new - mock.expect :patch_bucket, bucket_gapi do |name, patch_obj, **args| - name == bucket_name && patch_obj.encryption&.default_kms_key_name.nil? - end + mock.expect :patch_bucket, bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: {retries: 0}) bucket_with_key.service.mocked_service = mock @@ -123,9 +127,6 @@ end describe "encryption enforcement config" do - let(:customer_managed_encryption) { Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" } - let(:customer_supplied_encryption) { Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" } - let(:google_managed_encryption) { Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" } let(:bucket_encryption) do Google::Apis::StorageV1::Bucket::Encryption.new( customer_managed_encryption_enforcement_config: customer_managed_encryption, @@ -142,8 +143,8 @@ end it "knows its encryption enforcement config" do - _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" - _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" end @@ -163,13 +164,13 @@ mock.expect :patch_bucket, returned_bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: { retries: 0 }) bucket.service.mocked_service = mock - _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" - _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" bucket.update_bucket_encryption_enforcement_config incoming_config - _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" - _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" mock.verify diff --git a/google-cloud-storage/test/helper.rb b/google-cloud-storage/test/helper.rb index cb73937a2eda..1a160b35c597 100644 --- a/google-cloud-storage/test/helper.rb +++ b/google-cloud-storage/test/helper.rb @@ -244,6 +244,24 @@ def download_http_resp gzip: nil OpenStruct.new(header: headers) end + def customer_managed_encryption + Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) + end + + def customer_supplied_encryption + Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( + restriction_mode: "NotRestricted" + ) + end + + def google_managed_encryption + Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: "NotRestricted" + ) + end + def encryption_gapi(key_name: nil, customer_managed_config_restriction_mode: nil, customer_supplied_config_restriction_mode: nil, @@ -258,7 +276,7 @@ def encryption_gapi(key_name: nil, customer_managed_encryption_enforcement_config: cm_config, customer_supplied_encryption_enforcement_config: cs_config, google_managed_encryption_enforcement_config: gm_config - }.compact # This removes the nil values so the API doesn't get empty configs + }.compact Google::Apis::StorageV1::Bucket::Encryption.new(**params) end From 0b76c3447a6d30e0d466bac0ba1699da80ab0259 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Mon, 6 Apr 2026 07:00:21 +0000 Subject: [PATCH 20/28] updating doc --- .../lib/google/cloud/storage/bucket.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 193531385bd9..ae0fb1fe3ccd 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -797,8 +797,9 @@ def update_bucket_encryption_enforcement_config incoming_config # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # bucket.customer_supplied_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new - # restriction_mode: "NotRestricted" + # + # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" + # bucket.customer_supplied_encryption_enforcement_config = new_config # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted". def customer_supplied_encryption_enforcement_config @@ -837,8 +838,8 @@ def customer_supplied_encryption_enforcement_config= new_customer_supplied_encry # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # bucket.google_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new - # restriction_mode: "NotRestricted" + # new_config= Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" + # bucket.google_managed_encryption_enforcement_config = new_config # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted". def google_managed_encryption_enforcement_config @@ -853,7 +854,8 @@ def google_managed_encryption_enforcement_config # # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # new_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" # bucket.google_managed_encryption_enforcement_config = new_config + # new_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # bucket.google_managed_encryption_enforcement_config = new_config # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config From e493d07a54b7a809d8063e1aa09c629de6e2628d Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 7 Apr 2026 09:56:07 +0000 Subject: [PATCH 21/28] updating code --- .../storage/bucket_encryption_test.rb | 22 +-- .../lib/google/cloud/storage/bucket.rb | 136 ++++++++++-------- ...et_bucket_encryption_enforcement_config.rb | 15 +- ...te_bucket_encryption_enforcement_config.rb | 9 +- .../cloud/storage/bucket_encryption_test.rb | 16 +-- google-cloud-storage/test/helper.rb | 15 +- 6 files changed, 100 insertions(+), 113 deletions(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index a675e347c479..17480de0901e 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -25,20 +25,17 @@ ENV["GCLOUD_TEST_STORAGE_KMS_KEY_2"] || "projects/#{storage.project_id}/locations/#{bucket_location}/keyRings/ruby-test/cryptoKeys/ruby-test-key-2" } + let(:customer_managed_config) do - Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( - restriction_mode: "NotRestricted" - ) + { restriction_mode: "NotRestricted" } end + let(:customer_supplied_config) do - Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( - restriction_mode: "FullyRestricted" - ) + { restriction_mode: "FullyRestricted" } end + let(:google_managed_config) do - Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( - restriction_mode: "FullyRestricted" - ) + { restriction_mode: "FullyRestricted" } end let :bucket do @@ -90,6 +87,10 @@ end describe "Encryption Enforcement Config" do + let(:google_managed_config_complete) do + {google_managed_encryption_enforcement_config: { restriction_mode: "FullyRestricted" } } + end + it "knows its encryption enforcement config" do _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" @@ -103,8 +104,7 @@ bucket.customer_supplied_encryption_enforcement_config = customer_supplied_config _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" - - bucket.update_bucket_encryption_enforcement_config google_managed_config + bucket.update_bucket_encryption_enforcement_config google_managed_config_complete _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" bucket.reload! diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index ae0fb1fe3ccd..bb3ef06cfcbb 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -727,25 +727,33 @@ def default_kms_key= new_default_kms_key # # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # bucket.customer_managed_encryption_enforcement_config #=> Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new - # restriction_mode: "NotRestricted" + # bucket.customer_managed_encryption_enforcement_config + # ==> # # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" def customer_managed_encryption_enforcement_config @gapi.encryption&.customer_managed_encryption_enforcement_config end ## - # Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files. - # @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] new_customer_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. - # @example + # Sets the customer-managed encryption enforcement configuration for the bucket. + # + # @param new_customer_managed_encryption_enforcement_config [Hash, nil] + # The configuration hash for encryption enforcement. + # * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted". + # Pass `nil` to clear the current configuration. + # + # @example Enforcing Customer-Managed Encryption # require "google/cloud/storage" - # # + # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # + # # Set restriction mode to FullyRestricted + # new_config = { restriction_mode: "FullyRestricted" } # bucket.customer_managed_encryption_enforcement_config = new_config - # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" - + # + # @return [Hash] The updated configuration hash. + # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments. def customer_managed_encryption_enforcement_config= new_customer_managed_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new @gapi.encryption.customer_managed_encryption_enforcement_config = @@ -753,53 +761,44 @@ def customer_managed_encryption_enforcement_config= new_customer_managed_encrypt patch_gapi! :encryption end - ## - # Updates the bucket's encryption enforcement configuration. - # - # @param [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig] incoming_config The new encryption enforcement configuration to apply. - # - # @raise [ArgumentError] If the provided config type is unsupported. - # - # @example - # require "google/cloud/storage" - # - # storage = Google::Cloud::Storage.new - # bucket = storage.bucket "my-bucket" - # - # new_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" - # bucket.update_bucket_encryption_enforcement_config new_config - # - def update_bucket_encryption_enforcement_config incoming_config - attr_name = case incoming_config - when Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig - :google_managed_encryption_enforcement_config - when Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig - :customer_managed_encryption_enforcement_config - when Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig - :customer_supplied_encryption_enforcement_config - else - raise ArgumentError, "Unsupported config type: #{incoming_config.class}" - end - encryption_patch = Google::Apis::StorageV1::Bucket::Encryption.new - encryption_patch.public_send "#{attr_name}=", incoming_config - patch_gapi! :encryption, bucket_encryption_config: encryption_patch - end - - ## - # The bucket's encryption configuration for customer-supplied encryption keys. This configuration defines the - # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements - # for the bucket. + # Updates the bucket's encryption enforcement configuration. + # + # This method applies a patch to the bucket's encryption settings using the + # provided configuration. + # + # @param incoming_config [Hash, Google::Apis::StorageV1::Bucket::Encryption] + # The encryption configuration to apply. If a Hash is provided, it should + # contain keys corresponding to the encryption enforcement types. + # + # @example Updating to Google-Managed Encryption + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # + # new_config = { + # google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } + # } + # + # bucket.update_bucket_encryption_enforcement_config new_config + # + # @return [void] + # @raise [Google::Cloud::Error] If the API request fails (e.g., insufficient permissions). + def update_bucket_encryption_enforcement_config incoming_config + patch_gapi! :encryption, bucket_encryption_config: incoming_config + end + + ## + # The bucket's encryption configuration for customer-supplied encryption keys. # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/). - # @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] + # @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] # The bucket's encryption configuration, or `nil` if no encryption configuration has been set. # @example # require "google/cloud/storage" # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # - # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" - # bucket.customer_supplied_encryption_enforcement_config = new_config + # + # bucket.customer_supplied_encryption_enforcement_config + # ==> # # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted". def customer_supplied_encryption_enforcement_config @@ -807,16 +806,20 @@ def customer_supplied_encryption_enforcement_config end ## - # Sets the bucket's encryption configuration for customer-managed encryption that will be used to protect files. - # @param [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil] new_customer_supplied_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. + # Sets the bucket's encryption configuration for customer-supplied encryption that will be used to protect files. + # @param new_customer_supplied_encryption_enforcement_config [Hash, nil] + # The configuration hash for encryption enforcement. + # * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted". + # Pass `nil` to clear the current configuration. # @example # require "google/cloud/storage" # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # new_config = Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + # new_config = { restriction_mode: "FullyRestricted" } # bucket.customer_supplied_encryption_enforcement_config = new_config - # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" + # @return [Hash] The updated configuration hash. + # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments. def customer_supplied_encryption_enforcement_config= new_customer_supplied_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new @@ -838,8 +841,8 @@ def customer_supplied_encryption_enforcement_config= new_customer_supplied_encry # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # new_config= Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "NotRestricted" - # bucket.google_managed_encryption_enforcement_config = new_config + # bucket.google_managed_encryption_enforcement_config + # ==> # # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted". def google_managed_encryption_enforcement_config @@ -847,16 +850,25 @@ def google_managed_encryption_enforcement_config end ## - # Sets the bucket's encryption configuration for google-managed encryption that will be used to protect files. - # @param [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, nil] new_google_managed_encryption_enforcement_config The bucket's encryption configuration, or `nil` to delete the encryption configuration. - # @example + # Sets the google-managed encryption enforcement configuration for the bucket. + # + # @param new_google_managed_encryption_enforcement_config [Hash, nil] + # The configuration hash for encryption enforcement. + # * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted". + # Pass `nil` to clear the current configuration. + # + # @example Enforcing Customer-Managed Encryption # require "google/cloud/storage" - # # + # # storage = Google::Cloud::Storage.new # bucket = storage.bucket "my-bucket" - # new_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" - # bucket.google_managed_encryption_enforcement_config = new_config - # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted" + # + # # Set restriction mode to FullyRestricted + # new_config = { restriction_mode: "FullyRestricted" } + # bucket.new_google_managed_encryption_enforcement_config = new_config + # + # @return [Hash] The updated configuration hash. + # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments. def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new diff --git a/google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb index 65c305a41301..92cedc2e6ec6 100644 --- a/google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_set_bucket_encryption_enforcement_config.rb @@ -21,18 +21,9 @@ def set_bucket_encryption_enforcement_config bucket_name: storage = Google::Cloud::Storage.new - customer_managed_config = - Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig.new( - restriction_mode: "NotRestricted" - ) - customer_supplied_config = - Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig.new( - restriction_mode: "FullyRestricted" - ) - google_managed_config = - Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( - restriction_mode: "FullyRestricted" - ) + customer_managed_config = { restriction_mode: "NotRestricted" } + customer_supplied_config = { restriction_mode: "FullyRestricted" } + google_managed_config = { restriction_mode: "FullyRestricted" } bucket = storage.create_bucket bucket_name do |b| b.customer_managed_encryption_enforcement_config = customer_managed_config diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index 94ccf320d044..4208cc49d606 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -22,12 +22,11 @@ def update_bucket_encryption_enforcement_config bucket_name: storage = Google::Cloud::Storage.new bucket = storage.bucket bucket_name - # Update a specific type (e.g., change GMEK to NotRestricted) - google_managed_config = - Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( - restriction_mode: "NotRestricted" - ) + google_managed_config = { + google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } + } + bucket.update_bucket_encryption_enforcement_config google_managed_config puts "Updated google_managed_config to " \ diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index 4a1e7767dc24..cb98a270a984 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -89,7 +89,6 @@ bucket_gapi_with_key = bucket_gapi.dup bucket_gapi_with_key.encryption = encryption_gapi(key_name: kms_key) bucket_with_key = Google::Cloud::Storage::Bucket.from_gapi bucket_gapi_with_key, storage.service - patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new encryption: encryption_gapi(key_name: kms_key) patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new( encryption: Google::Apis::StorageV1::Bucket::Encryption.new( default_kms_key_name: nil @@ -150,17 +149,19 @@ it "updates encryption_enforcement_config using update_bucket_encryption_enforcement_config" do mock = Minitest::Mock.new - incoming_config = Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new restriction_mode: "FullyRestricted" + incoming_config = { google_managed_encryption_enforcement_config: { restriction_mode: "FullyRestricted" } } patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new( encryption: Google::Apis::StorageV1::Bucket::Encryption.new( - google_managed_encryption_enforcement_config: incoming_config + google_managed_encryption_enforcement_config: Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig.new( + restriction_mode: "FullyRestricted" + ) ) ) returned_bucket_gapi = bucket_gapi.dup returned_bucket_gapi.encryption = bucket_gapi.encryption.dup - returned_bucket_gapi.encryption.google_managed_encryption_enforcement_config = incoming_config + returned_bucket_gapi.encryption.google_managed_encryption_enforcement_config = patch_bucket_gapi.encryption.google_managed_encryption_enforcement_config mock.expect :patch_bucket, returned_bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: { retries: 0 }) bucket.service.mocked_service = mock @@ -169,18 +170,13 @@ _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" bucket.update_bucket_encryption_enforcement_config incoming_config - _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" + _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" mock.verify end - it "raises error on invalid config using update_bucket_encryption_enforcement_config" do - expect { - bucket.update_bucket_encryption_enforcement_config "invalid config" - }.must_raise ArgumentError - end it "deletes all encryption enforcement configs together and preserves default_kms_key" do mock = Minitest::Mock.new diff --git a/google-cloud-storage/test/helper.rb b/google-cloud-storage/test/helper.rb index 1a160b35c597..2fef81f70a56 100644 --- a/google-cloud-storage/test/helper.rb +++ b/google-cloud-storage/test/helper.rb @@ -262,20 +262,9 @@ def google_managed_encryption ) end - def encryption_gapi(key_name: nil, - customer_managed_config_restriction_mode: nil, - customer_supplied_config_restriction_mode: nil, - google_managed_config_restriction_mode: nil) - - cm_config = customer_managed_config(restriction_mode: customer_managed_config_restriction_mode) if customer_managed_config_restriction_mode - cs_config = customer_supplied_config(restriction_mode: customer_supplied_config_restriction_mode) if customer_supplied_config_restriction_mode - gm_config = google_managed_config(restriction_mode: google_managed_config_restriction_mode) if google_managed_config_restriction_mode - + def encryption_gapi key_name: nil params = { - default_kms_key_name: key_name, - customer_managed_encryption_enforcement_config: cm_config, - customer_supplied_encryption_enforcement_config: cs_config, - google_managed_encryption_enforcement_config: gm_config + default_kms_key_name: key_name }.compact Google::Apis::StorageV1::Bucket::Encryption.new(**params) From b4e1f137ebe4bf930340d449aa9233c126ef2cc0 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 7 Apr 2026 12:39:53 +0000 Subject: [PATCH 22/28] updating tests --- .../lib/google/cloud/storage/bucket.rb | 68 ++++++++++++------- ...te_bucket_encryption_enforcement_config.rb | 6 +- .../cloud/storage/bucket_encryption_test.rb | 19 ++++++ 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index bb3ef06cfcbb..c1bf0c9205b2 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -761,30 +761,50 @@ def customer_managed_encryption_enforcement_config= new_customer_managed_encrypt patch_gapi! :encryption end - # Updates the bucket's encryption enforcement configuration. - # - # This method applies a patch to the bucket's encryption settings using the - # provided configuration. - # - # @param incoming_config [Hash, Google::Apis::StorageV1::Bucket::Encryption] - # The encryption configuration to apply. If a Hash is provided, it should - # contain keys corresponding to the encryption enforcement types. - # - # @example Updating to Google-Managed Encryption - # storage = Google::Cloud::Storage.new - # bucket = storage.bucket "my-bucket" - # - # new_config = { - # google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } - # } - # - # bucket.update_bucket_encryption_enforcement_config new_config - # - # @return [void] - # @raise [Google::Cloud::Error] If the API request fails (e.g., insufficient permissions). - def update_bucket_encryption_enforcement_config incoming_config - patch_gapi! :encryption, bucket_encryption_config: incoming_config - end + # Updates the bucket's encryption enforcement configuration. + # + # This method applies a patch to the bucket's encryption settings using the + # provided configuration. + # + # @param incoming_config [Hash, Google::Apis::StorageV1::Bucket::Encryption] + # The encryption configuration to apply. If a Hash is provided, it should + # contain keys corresponding to the encryption enforcement types. + # + # @example Updating to Google-Managed Encryption + # storage = Google::Cloud::Storage.new + # bucket = storage.bucket "my-bucket" + # + # new_config = { + # google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } + # } + # + # bucket.update_bucket_encryption_enforcement_config new_config + # + # @return [void] + # @raise [Google::Cloud::Error] If the API request fails (e.g., insufficient permissions). + def update_bucket_encryption_enforcement_config incoming_config + allowed_keys = [ + :google_managed_encryption_enforcement_config, + :customer_managed_encryption_enforcement_config, + :customer_supplied_encryption_enforcement_config + ] + # binding.pry + if incoming_config.is_a? Hash + input_keys = incoming_config.keys + + raise ArgumentError, "Config cannot be empty" if input_keys.empty? + + extra_keys = input_keys - allowed_keys + unless extra_keys.empty? + raise ArgumentError, "Invalid config detected: #{extra_keys.join(', ')}. " \ + "Only #{allowed_keys.join(', ')} are allowed." + end + else + raise ArgumentError, "incoming_config must be a Hash" + end + + patch_gapi! :encryption, bucket_encryption_config: incoming_config + end ## # The bucket's encryption configuration for customer-supplied encryption keys. diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index 4208cc49d606..e3e3858e8ffa 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -23,11 +23,11 @@ def update_bucket_encryption_enforcement_config bucket_name: storage = Google::Cloud::Storage.new bucket = storage.bucket bucket_name # Update a specific type (e.g., change GMEK to NotRestricted) - google_managed_config = { + new_config = { google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } } - - bucket.update_bucket_encryption_enforcement_config google_managed_config + + bucket.update_bucket_encryption_enforcement_config new_config puts "Updated google_managed_config to " \ "#{bucket.google_managed_encryption_enforcement_config.restriction_mode} " \ diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index cb98a270a984..622ba78f7245 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -177,6 +177,25 @@ mock.verify end + it "raises error when invalid config is provided for update " do + config = { + wrongconfig: { restriction_mode: "NotRestricted" } + } + err = assert_raises(ArgumentError) do + bucket.update_bucket_encryption_enforcement_config(config) + end + assert_match /Invalid config detected: wrongconfig/, err.message + + end + + it "raises error when a Hash in not provided for update " do + config = "wrongconfig" + err = assert_raises(ArgumentError) do + bucket.update_bucket_encryption_enforcement_config(config) + end + assert /incoming_config must be a Hash/ + + end it "deletes all encryption enforcement configs together and preserves default_kms_key" do mock = Minitest::Mock.new From c816b92628fa1ccd9ae09410edeb56836137dcce Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Wed, 8 Apr 2026 09:32:01 +0000 Subject: [PATCH 23/28] added example --- .../lib/google/cloud/storage/bucket.rb | 100 +++++++++++++----- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index c1bf0c9205b2..747b92153c36 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -752,7 +752,19 @@ def customer_managed_encryption_enforcement_config # new_config = { restriction_mode: "FullyRestricted" } # bucket.customer_managed_encryption_enforcement_config = new_config # - # @return [Hash] The updated configuration hash. + # @example Setting via Request Object (Google API Client) + # require "google/apis/storage_v1" + # + # # Create the enforcement config sub-object + # enforcement_config = { restriction_mode: "FullyRestricted" } + # + # # Initialize the parent Encryption request object + # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new( + # customer_managed_encryption_enforcement_config: enforcement_config + # ) + # bucket.customer_managed_encryption_enforcement_config = request_obj + # + # @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration. # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments. def customer_managed_encryption_enforcement_config= new_customer_managed_encryption_enforcement_config @gapi.encryption ||= API::Bucket::Encryption.new @@ -780,31 +792,42 @@ def customer_managed_encryption_enforcement_config= new_customer_managed_encrypt # # bucket.update_bucket_encryption_enforcement_config new_config # - # @return [void] - # @raise [Google::Cloud::Error] If the API request fails (e.g., insufficient permissions). + # @example Passing a Request Object + # require "google/apis/storage_v1" + # config_obj = Google::Apis::StorageV1::Bucket::Encryption.new( + # google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } + # ) + # bucket.update_bucket_encryption_enforcement_config config_obj + # @raise [ArgumentError] If the config is empty, contains invalid keys, or is the wrong type. def update_bucket_encryption_enforcement_config incoming_config - allowed_keys = [ - :google_managed_encryption_enforcement_config, - :customer_managed_encryption_enforcement_config, - :customer_supplied_encryption_enforcement_config - ] - # binding.pry - if incoming_config.is_a? Hash - input_keys = incoming_config.keys - - raise ArgumentError, "Config cannot be empty" if input_keys.empty? - - extra_keys = input_keys - allowed_keys - unless extra_keys.empty? - raise ArgumentError, "Invalid config detected: #{extra_keys.join(', ')}. " \ - "Only #{allowed_keys.join(', ')} are allowed." - end - else - raise ArgumentError, "incoming_config must be a Hash" - end + allowed_keys = [ + :google_managed_encryption_enforcement_config, + :customer_managed_encryption_enforcement_config, + :customer_supplied_encryption_enforcement_config + ] + + if incoming_config.is_a? Hash + input_keys = incoming_config.keys + raise ArgumentError, "Config cannot be empty" if input_keys.empty? + + extra_keys = input_keys - allowed_keys + unless extra_keys.empty? + raise ArgumentError, "Invalid config detected: #{extra_keys.join(', ')}. " \ + "Only #{allowed_keys.join(', ')} are allowed." + end - patch_gapi! :encryption, bucket_encryption_config: incoming_config - end + elsif incoming_config.is_a? Google::Apis::StorageV1::Bucket::Encryption + # For objects, ensure at least one of the allowed enforcement configs is present + has_any_config = allowed_keys.any? { |key| !incoming_config.send(key).nil? } + binding.pry + raise ArgumentError, "Encryption request object must have at least one enforcement config set" unless has_any_config + + else + raise ArgumentError, "incoming_config must be a Hash or Google::Apis::StorageV1::Bucket::Encryption" + end + + patch_gapi! :encryption, bucket_encryption_config: incoming_config +end ## # The bucket's encryption configuration for customer-supplied encryption keys. @@ -838,7 +861,20 @@ def customer_supplied_encryption_enforcement_config # bucket = storage.bucket "my-bucket" # new_config = { restriction_mode: "FullyRestricted" } # bucket.customer_supplied_encryption_enforcement_config = new_config - # @return [Hash] The updated configuration hash. + # + # @example Setting via Request Object (Google API Client) + # require "google/apis/storage_v1" + # + # # Create the enforcement config sub-object + # enforcement_config = { restriction_mode: "FullyRestricted" } + # + # # Initialize the parent Encryption request object + # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new( + # customer_supplied_encryption_enforcement_config: enforcement_config + # ) + # bucket.customer_supplied_encryption_enforcement_config = request_obj + # + # @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration. # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments. def customer_supplied_encryption_enforcement_config= new_customer_supplied_encryption_enforcement_config @@ -887,7 +923,19 @@ def google_managed_encryption_enforcement_config # new_config = { restriction_mode: "FullyRestricted" } # bucket.new_google_managed_encryption_enforcement_config = new_config # - # @return [Hash] The updated configuration hash. + # @example Setting via Request Object (Google API Client) + # require "google/apis/storage_v1" + # + # # Create the enforcement config sub-object + # enforcement_config = { restriction_mode: "FullyRestricted" } + # + # # Initialize the parent Encryption request object + # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new( + # google_managed_encryption_enforcement_config: enforcement_config + # ) + # bucket.google_managed_encryption_enforcement_config = request_obj + # + # @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration. # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments. def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config From 13a50a924a08ac308f65a45df16b166374a81336 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Wed, 8 Apr 2026 10:41:30 +0000 Subject: [PATCH 24/28] fix indentation --- .../lib/google/cloud/storage/bucket.rb | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 747b92153c36..918ec908c7b6 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -755,10 +755,8 @@ def customer_managed_encryption_enforcement_config # @example Setting via Request Object (Google API Client) # require "google/apis/storage_v1" # - # # Create the enforcement config sub-object # enforcement_config = { restriction_mode: "FullyRestricted" } # - # # Initialize the parent Encryption request object # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new( # customer_managed_encryption_enforcement_config: enforcement_config # ) @@ -800,34 +798,34 @@ def customer_managed_encryption_enforcement_config= new_customer_managed_encrypt # bucket.update_bucket_encryption_enforcement_config config_obj # @raise [ArgumentError] If the config is empty, contains invalid keys, or is the wrong type. def update_bucket_encryption_enforcement_config incoming_config - allowed_keys = [ - :google_managed_encryption_enforcement_config, - :customer_managed_encryption_enforcement_config, - :customer_supplied_encryption_enforcement_config - ] - - if incoming_config.is_a? Hash - input_keys = incoming_config.keys - raise ArgumentError, "Config cannot be empty" if input_keys.empty? - - extra_keys = input_keys - allowed_keys - unless extra_keys.empty? - raise ArgumentError, "Invalid config detected: #{extra_keys.join(', ')}. " \ - "Only #{allowed_keys.join(', ')} are allowed." - end + allowed_keys = [ + :google_managed_encryption_enforcement_config, + :customer_managed_encryption_enforcement_config, + :customer_supplied_encryption_enforcement_config + ] + + if incoming_config.is_a? Hash + input_keys = incoming_config.keys + raise ArgumentError, "Config cannot be empty" if input_keys.empty? + + extra_keys = input_keys - allowed_keys + unless extra_keys.empty? + raise ArgumentError, "Invalid config detected: #{extra_keys.join(', ')}. " \ + "Only #{allowed_keys.join(', ')} are allowed." + end - elsif incoming_config.is_a? Google::Apis::StorageV1::Bucket::Encryption - # For objects, ensure at least one of the allowed enforcement configs is present - has_any_config = allowed_keys.any? { |key| !incoming_config.send(key).nil? } - binding.pry - raise ArgumentError, "Encryption request object must have at least one enforcement config set" unless has_any_config - - else - raise ArgumentError, "incoming_config must be a Hash or Google::Apis::StorageV1::Bucket::Encryption" - end + elsif incoming_config.is_a? Google::Apis::StorageV1::Bucket::Encryption + # For objects, ensure at least one of the allowed enforcement configs is present + has_any_config = allowed_keys.any? { |key| !incoming_config.send(key).nil? } + binding.pry + raise ArgumentError, "Encryption request object must have at least one enforcement config set" unless has_any_config + + else + raise ArgumentError, "incoming_config must be a Hash or Google::Apis::StorageV1::Bucket::Encryption" + end - patch_gapi! :encryption, bucket_encryption_config: incoming_config -end + patch_gapi! :encryption, bucket_encryption_config: incoming_config + end ## # The bucket's encryption configuration for customer-supplied encryption keys. @@ -865,10 +863,8 @@ def customer_supplied_encryption_enforcement_config # @example Setting via Request Object (Google API Client) # require "google/apis/storage_v1" # - # # Create the enforcement config sub-object # enforcement_config = { restriction_mode: "FullyRestricted" } # - # # Initialize the parent Encryption request object # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new( # customer_supplied_encryption_enforcement_config: enforcement_config # ) @@ -926,10 +922,8 @@ def google_managed_encryption_enforcement_config # @example Setting via Request Object (Google API Client) # require "google/apis/storage_v1" # - # # Create the enforcement config sub-object # enforcement_config = { restriction_mode: "FullyRestricted" } # - # # Initialize the parent Encryption request object # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new( # google_managed_encryption_enforcement_config: enforcement_config # ) From 27f012539a2ab40df9292818b507bea6087720e9 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 14 Apr 2026 09:10:13 +0000 Subject: [PATCH 25/28] using update method --- .../storage/bucket_encryption_test.rb | 4 +- .../lib/google/cloud/storage/bucket.rb | 76 +- .../samples/acceptance/buckets_test.rb | 1145 +++++++++-------- ...te_bucket_encryption_enforcement_config.rb | 9 +- 4 files changed, 600 insertions(+), 634 deletions(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 17480de0901e..0af10571bf66 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -104,7 +104,9 @@ bucket.customer_supplied_encryption_enforcement_config = customer_supplied_config _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" - bucket.update_bucket_encryption_enforcement_config google_managed_config_complete + bucket.update do |b| + b.google_managed_encryption_enforcement_config = google_managed_config + end _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" bucket.reload! diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 918ec908c7b6..ae1e0e5f9603 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -771,62 +771,6 @@ def customer_managed_encryption_enforcement_config= new_customer_managed_encrypt patch_gapi! :encryption end - # Updates the bucket's encryption enforcement configuration. - # - # This method applies a patch to the bucket's encryption settings using the - # provided configuration. - # - # @param incoming_config [Hash, Google::Apis::StorageV1::Bucket::Encryption] - # The encryption configuration to apply. If a Hash is provided, it should - # contain keys corresponding to the encryption enforcement types. - # - # @example Updating to Google-Managed Encryption - # storage = Google::Cloud::Storage.new - # bucket = storage.bucket "my-bucket" - # - # new_config = { - # google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } - # } - # - # bucket.update_bucket_encryption_enforcement_config new_config - # - # @example Passing a Request Object - # require "google/apis/storage_v1" - # config_obj = Google::Apis::StorageV1::Bucket::Encryption.new( - # google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } - # ) - # bucket.update_bucket_encryption_enforcement_config config_obj - # @raise [ArgumentError] If the config is empty, contains invalid keys, or is the wrong type. - def update_bucket_encryption_enforcement_config incoming_config - allowed_keys = [ - :google_managed_encryption_enforcement_config, - :customer_managed_encryption_enforcement_config, - :customer_supplied_encryption_enforcement_config - ] - - if incoming_config.is_a? Hash - input_keys = incoming_config.keys - raise ArgumentError, "Config cannot be empty" if input_keys.empty? - - extra_keys = input_keys - allowed_keys - unless extra_keys.empty? - raise ArgumentError, "Invalid config detected: #{extra_keys.join(', ')}. " \ - "Only #{allowed_keys.join(', ')} are allowed." - end - - elsif incoming_config.is_a? Google::Apis::StorageV1::Bucket::Encryption - # For objects, ensure at least one of the allowed enforcement configs is present - has_any_config = allowed_keys.any? { |key| !incoming_config.send(key).nil? } - binding.pry - raise ArgumentError, "Encryption request object must have at least one enforcement config set" unless has_any_config - - else - raise ArgumentError, "incoming_config must be a Hash or Google::Apis::StorageV1::Bucket::Encryption" - end - - patch_gapi! :encryption, bucket_encryption_config: incoming_config - end - ## # The bucket's encryption configuration for customer-supplied encryption keys. # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/). @@ -1595,6 +1539,7 @@ def update if_metageneration_match: nil, if_metageneration_not_match: nil updater.check_for_changed_labels! updater.check_for_mutable_cors! updater.check_for_mutable_lifecycle! + updater.check_for_encryption_enforcement_config! return if updater.updates.empty? update_gapi! updater.updates, if_metageneration_match: if_metageneration_match, @@ -3587,6 +3532,25 @@ def cors yield @cors_builder if block_given? @cors_builder end + def check_for_encryption_enforcement_config! + return unless @gapi.encryption + + configs = [ + :google_managed_encryption_enforcement_config, + :customer_managed_encryption_enforcement_config, + :customer_supplied_encryption_enforcement_config + ] + + configs.each do |config_name| + sub_config = @gapi.encryption.send config_name + if sub_config.respond_to? :effective_time= + sub_config.effective_time = nil + elsif sub_config.is_a? Hash + sub_config.delete :effective_time + sub_config.delete "effective_time" + end + end + end ## # @private Make sure any cors changes are saved diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index a8a9326a5e41..65bd4efba249 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -58,6 +58,7 @@ require_relative "../storage_get_autoclass" require_relative "../storage_set_autoclass" require_relative "../storage_move_object" +require 'pry' describe "Buckets Snippets" do let(:storage_client) { Google::Cloud::Storage.new } @@ -65,112 +66,112 @@ let(:retention_period) { rand 1..99 } let(:bucket) { fixture_bucket } - describe "bucket lifecycle" do - it "create_bucket, create_bucket_class_location, list_buckets, get_bucket_metadata, delete_bucket" do - # create_bucket - bucket_name = random_bucket_name - refute storage_client.bucket bucket_name - - retry_resource_exhaustion do - assert_output "Created bucket: #{bucket_name}\n" do - create_bucket bucket_name: bucket_name - end - end - - refute_nil storage_client.bucket bucket_name - - # create_bucket_class_location - - secondary_bucket_name = random_bucket_name - location = "ASIA" - storage_class = "COLDLINE" - refute storage_client.bucket secondary_bucket_name - - retry_resource_exhaustion do - assert_output "Created bucket #{secondary_bucket_name} in #{location} with #{storage_class} class\n" do - create_bucket_class_location bucket_name: secondary_bucket_name - end - end - - secondary_bucket = storage_client.bucket secondary_bucket_name - refute_nil secondary_bucket - assert_equal location, secondary_bucket.location - assert_equal storage_class, secondary_bucket.storage_class - - # list_buckets - out, _err = capture_io do - list_buckets - end - - assert_includes out, "ruby-storage-samples-" - - # get_bucket_metadata - out, _err = capture_io do - get_bucket_metadata bucket_name: bucket_name - end - - assert_includes out, bucket_name - - # delete_bucket - assert_output "Deleted bucket: #{bucket_name}\n" do - delete_bucket bucket_name: bucket_name - end - - - refute storage_client.bucket bucket_name - - delete_bucket_helper bucket_name - delete_bucket_helper secondary_bucket_name - end - end - - describe "storage_create_bucket_dual_region" do - it "creates dual region bucket" do - location = "US" - region_1 = "US-EAST1" - region_2 = "US-WEST1" - location_type = "dual-region" - bucket_name = random_bucket_name - refute storage_client.bucket bucket_name - - expected = "Bucket #{bucket_name} created:\n" - expected += "- location: #{location}\n" - expected += "- location_type: #{location_type}\n" - expected += "- custom_placement_config:\n" - expected += " - data_locations: #{[region_1, region_2]}\n" - - retry_resource_exhaustion do - assert_output expected do - StorageCreateBucketDualRegion.new.storage_create_bucket_dual_region bucket_name: bucket_name, - region_1: region_1, - region_2: region_2 - end - end - - refute_nil storage_client.bucket bucket_name - - delete_bucket_helper bucket_name - end - end - - describe "storage_create_bucket_hierarchical_namespace" do - it "creates hierarchical namespace enabled bucket" do - bucket_name = random_bucket_name - refute storage_client.bucket bucket_name - - expected = "Created bucket #{bucket_name} with Hierarchical Namespace enabled.\n" - - retry_resource_exhaustion do - assert_output expected do - create_bucket_hierarchical_namespace bucket_name: bucket_name - end - end - - refute_nil storage_client.bucket bucket_name - - delete_bucket_helper bucket_name - end - end + # describe "bucket lifecycle" do + # it "create_bucket, create_bucket_class_location, list_buckets, get_bucket_metadata, delete_bucket" do + # # create_bucket + # bucket_name = random_bucket_name + # refute storage_client.bucket bucket_name + + # retry_resource_exhaustion do + # assert_output "Created bucket: #{bucket_name}\n" do + # create_bucket bucket_name: bucket_name + # end + # end + + # refute_nil storage_client.bucket bucket_name + + # # create_bucket_class_location + + # secondary_bucket_name = random_bucket_name + # location = "ASIA" + # storage_class = "COLDLINE" + # refute storage_client.bucket secondary_bucket_name + + # retry_resource_exhaustion do + # assert_output "Created bucket #{secondary_bucket_name} in #{location} with #{storage_class} class\n" do + # create_bucket_class_location bucket_name: secondary_bucket_name + # end + # end + + # secondary_bucket = storage_client.bucket secondary_bucket_name + # refute_nil secondary_bucket + # assert_equal location, secondary_bucket.location + # assert_equal storage_class, secondary_bucket.storage_class + + # # list_buckets + # out, _err = capture_io do + # list_buckets + # end + + # assert_includes out, "ruby-storage-samples-" + + # # get_bucket_metadata + # out, _err = capture_io do + # get_bucket_metadata bucket_name: bucket_name + # end + + # assert_includes out, bucket_name + + # # delete_bucket + # assert_output "Deleted bucket: #{bucket_name}\n" do + # delete_bucket bucket_name: bucket_name + # end + + + # refute storage_client.bucket bucket_name + + # delete_bucket_helper bucket_name + # delete_bucket_helper secondary_bucket_name + # end + # end + + # describe "storage_create_bucket_dual_region" do + # it "creates dual region bucket" do + # location = "US" + # region_1 = "US-EAST1" + # region_2 = "US-WEST1" + # location_type = "dual-region" + # bucket_name = random_bucket_name + # refute storage_client.bucket bucket_name + + # expected = "Bucket #{bucket_name} created:\n" + # expected += "- location: #{location}\n" + # expected += "- location_type: #{location_type}\n" + # expected += "- custom_placement_config:\n" + # expected += " - data_locations: #{[region_1, region_2]}\n" + + # retry_resource_exhaustion do + # assert_output expected do + # StorageCreateBucketDualRegion.new.storage_create_bucket_dual_region bucket_name: bucket_name, + # region_1: region_1, + # region_2: region_2 + # end + # end + + # refute_nil storage_client.bucket bucket_name + + # delete_bucket_helper bucket_name + # end + # end + + # describe "storage_create_bucket_hierarchical_namespace" do + # it "creates hierarchical namespace enabled bucket" do + # bucket_name = random_bucket_name + # refute storage_client.bucket bucket_name + + # expected = "Created bucket #{bucket_name} with Hierarchical Namespace enabled.\n" + + # retry_resource_exhaustion do + # assert_output expected do + # create_bucket_hierarchical_namespace bucket_name: bucket_name + # end + # end + + # refute_nil storage_client.bucket bucket_name + + # delete_bucket_helper bucket_name + # end + # end describe "storage_bucket_encryption_enforcement_config" do bucket_name = random_bucket_name @@ -210,470 +211,470 @@ delete_bucket_helper bucket_name end - describe "storage_create_bucket_with_object_retention" do - it "creates a bucket with object retention enabled." do - bucket_name = random_bucket_name - refute storage_client.bucket bucket_name - - expected = "Created bucket #{bucket_name} with object retention setting: Enabled\n" - - retry_resource_exhaustion do - assert_output expected do - create_bucket_with_object_retention bucket_name: bucket_name - end - end - - refute_nil storage_client.bucket bucket_name - - file_name = "test_object_retention" - - bucket = storage_client.bucket bucket_name - - out, _err = capture_io do - set_object_retention_policy bucket_name: bucket.name, - content: "hello world", - destination_file_name: file_name - end - - assert_includes out, "Retention policy for file #{file_name}" - - file = bucket.file file_name - file.retention = { - mode: nil, - retain_until_time: nil, - override_unlocked_retention: true - } - delete_bucket_helper bucket_name - end - end - - describe "autoclass" do - it "get_autoclass, set_autoclass" do - bucket_name = random_bucket_name - refute storage_client.bucket bucket_name - - storage_client.create_bucket bucket_name, autoclass_enabled: true - - assert_output(/autoclass config set to true./) do - get_autoclass bucket_name: bucket_name - end - - assert_output(/autoclass terminal storage class set to NEARLINE./) do - get_autoclass bucket_name: bucket_name - end - - assert_output(/autoclass terminal storage class set to ARCHIVE./) do - set_autoclass bucket_name: bucket_name, toggle: true, terminal_storage_class: "ARCHIVE" - end - - assert_output(/autoclass config set to false./) do - set_autoclass bucket_name: bucket_name, toggle: false - end - - delete_bucket_helper bucket_name - end - end - - describe "cors" do - it "cors_configuration, remove_cors_configuration" do - bucket.cors { |c| c.clear } - assert bucket.cors.empty? - - # cors_configuration - assert_output "Set CORS policies for bucket #{bucket.name}\n" do - cors_configuration bucket_name: bucket.name - end - - bucket.refresh! - assert_equal 1, bucket.cors.count - rule = bucket.cors.first - assert_equal ["*"], rule.origin - assert_equal ["PUT", "POST"], rule.methods - assert_equal ["Content-Type", "x-goog-resumable"], rule.headers - assert_equal 3600, rule.max_age - - # remove_cors_configuration - assert_output "Remove CORS policies for bucket #{bucket.name}\n" do - remove_cors_configuration bucket_name: bucket.name - end - bucket.refresh! - assert bucket.cors.empty? - end - end - - describe "requester_pays" do - it "enable_requester_pays, disable_requester_pays, get_requester_pays_status" do - # enable_requester_pays - bucket.requester_pays = false - - assert_output "Requester pays has been enabled for #{bucket.name}\n" do - enable_requester_pays bucket_name: bucket.name - end - bucket.refresh! - assert bucket.requester_pays? - - # get_requester_pays_status - assert_output "Requester pays status is enabled for #{bucket.name}\n" do - get_requester_pays_status bucket_name: bucket.name - end - assert bucket.requester_pays? - - # disable_requester_pays - assert_output "Requester pays has been disabled for #{bucket.name}\n" do - disable_requester_pays bucket_name: bucket.name - end - bucket.refresh! - refute bucket.requester_pays? - - # get_requester_pays_status - assert_output "Requester pays status is disabled for #{bucket.name}\n" do - get_requester_pays_status bucket_name: bucket.name - end - refute bucket.requester_pays? - end - end - - describe "uniform_bucket_level_access" do - it "enable_uniform_bucket_level_access, get_uniform_bucket_level_access, disable_uniform_bucket_level_access" do - # enable_uniform_bucket_level_access - bucket.uniform_bucket_level_access = false - - assert_output "Uniform bucket-level access was enabled for #{bucket.name}.\n" do - enable_uniform_bucket_level_access bucket_name: bucket.name - end - - bucket.refresh! - assert bucket.uniform_bucket_level_access? - - # get_uniform_bucket_level_access - assert_output "Uniform bucket-level access is enabled for #{bucket.name}.\nBucket " \ - "will be locked on #{bucket.uniform_bucket_level_access_locked_at}.\n" do - get_uniform_bucket_level_access bucket_name: bucket.name - end - assert bucket.uniform_bucket_level_access? - - # disable_uniform_bucket_level_access - assert_output "Uniform bucket-level access was disabled for #{bucket.name}.\n" do - disable_uniform_bucket_level_access bucket_name: bucket.name - end - - bucket.refresh! - refute bucket.uniform_bucket_level_access? - - # get_uniform_bucket_level_access - assert_output "Uniform bucket-level access is disabled for #{bucket.name}.\n" do - get_uniform_bucket_level_access bucket_name: bucket.name - end - refute bucket.uniform_bucket_level_access? - - bucket.uniform_bucket_level_access = false - end - end - - describe "default Cloud KMS encryption key" do - it "set_bucket_default_kms_key, bucket_delete_default_kms_key" do - refute bucket.default_kms_key - - # set_bucket_default_kms_key - assert_output "Default KMS key for #{bucket.name} was set to #{kms_key}\n" do - set_bucket_default_kms_key bucket_name: bucket.name, - default_kms_key: kms_key - end - - bucket.refresh! - assert_equal bucket.default_kms_key, kms_key - - # bucket_delete_default_kms_key - assert_output "Default KMS key was removed from #{bucket.name}\n" do - bucket_delete_default_kms_key bucket_name: bucket.name - end - - bucket.refresh! - refute bucket.default_kms_key - end - end - - describe "get bucket class and location data" do - bucket_name = random_bucket_name - location = "US" - storage_class = "COLDLINE" - - it "get_bucket_class_and_location" do - storage_client.create_bucket bucket_name, - location: location, - storage_class: storage_class - expected_output = "Bucket #{bucket_name} storage class is " \ - "#{storage_class}, and the location is #{location}\n" - assert_output expected_output do - get_bucket_class_and_location bucket_name: bucket_name - end - end - end - - describe "labels" do - it "add_bucket_label, remove_bucket_label" do - # add_bucket_label - label_key = "label_key" - label_value = "label_value" - - assert_output "Added label #{label_key} with value #{label_value} to #{bucket.name}\n" do - add_bucket_label bucket_name: bucket.name, - label_value: label_value, - label_key: label_key - end - - bucket.refresh! - assert_equal bucket.labels[label_key], label_value - - # remove_bucket_label - assert_output "Deleted label #{label_key} from #{bucket.name}\n" do - remove_bucket_label bucket_name: bucket.name, - label_key: label_key - end - - bucket.refresh! - assert bucket.labels[label_key].empty? - end - end - - describe "lifecycle management" do - let(:bucket) { create_bucket_helper random_bucket_name } - after { delete_bucket_helper bucket.name } - - it "enable_bucket_lifecycle_management, disable_bucket_lifecycle_management" do - # enable_bucket_lifecycle_management - out, _err = capture_io do - enable_bucket_lifecycle_management bucket_name: bucket.name - end - - assert_includes out, "Lifecycle management is enabled" - - # disable_bucket_lifecycle_management - out, _err = capture_io do - disable_bucket_lifecycle_management bucket_name: bucket.name - end - - assert_includes out, "Lifecycle management is disabled" - end - end - - describe "retention policy" do - let(:bucket) { create_bucket_helper random_bucket_name } - after { delete_bucket_helper bucket.name } - - it "set_retention_policy, get_retention_policy, remove_retention_policy" do - # set_retention_policy - assert_output "Retention period for #{bucket.name} is now #{retention_period} seconds.\n" do - set_retention_policy bucket_name: bucket.name, - retention_period: retention_period - end - - bucket.refresh! - assert_equal bucket.retention_period, retention_period - - # get_retention_policy - out, _err = capture_io do - get_retention_policy bucket_name: bucket.name - end - - assert_includes out, "period: #{retention_period}\n" - - # remove_retention_policy - assert_equal bucket.retention_period, retention_period - assert_output "Retention policy for #{bucket.name} has been removed.\n" do - remove_retention_policy bucket_name: bucket.name - end - - bucket.refresh! - refute bucket.retention_period - - # lock_retention_policy - bucket.retention_period = retention_period - out, _err = capture_io do - lock_retention_policy bucket_name: bucket.name - end - - assert_includes out, "Retention policy for #{bucket.name} is now locked." - bucket.refresh! - assert bucket.retention_policy_locked? - - # remove_retention_policy - assert_output "Policy is locked and retention policy can't be removed.\n" do - remove_retention_policy bucket_name: bucket.name - end - end - end - - describe "default_event_based_hold" do - it "enable_default_event_based_hold, get_default_event_based_hold, disable_default_event_based_hold" do - # enable_default_event_based_hold - assert_output "Default event-based hold was enabled for #{bucket.name}.\n" do - enable_default_event_based_hold bucket_name: bucket.name - end - - bucket.refresh! - assert bucket.default_event_based_hold? - - # get_default_event_based_hold - assert_output "Default event-based hold is enabled for #{bucket.name}.\n" do - get_default_event_based_hold bucket_name: bucket.name - end - - # disable_default_event_based_hold - bucket.update do |b| - b.default_event_based_hold = true - end - - assert_output "Default event-based hold was disabled for #{bucket.name}.\n" do - disable_default_event_based_hold bucket_name: bucket.name - end - - bucket.refresh! - refute bucket.default_event_based_hold? - - # get_default_event_based_hold - assert_output "Default event-based hold is not enabled for #{bucket.name}.\n" do - get_default_event_based_hold bucket_name: bucket.name - end - end - end - - describe "storage_class" do - it "change_default_storage_class" do - assert_equal "STANDARD", bucket.storage_class - - assert_output "Default storage class for bucket #{bucket.name} has been set to COLDLINE\n" do - change_default_storage_class bucket_name: bucket.name - end - - bucket.refresh! - assert_equal "COLDLINE", bucket.storage_class - # teardown - bucket.storage_class = "STANDARD" - end - end - - describe "versioning" do - it "enable_versioning, disable_versioning" do - # enable_versioning - bucket.versioning = false - - assert_output "Versioning was enabled for bucket #{bucket.name}\n" do - enable_versioning bucket_name: bucket.name - end - bucket.refresh! - assert bucket.versioning? - - # disable_versioning - assert_output "Versioning was disabled for bucket #{bucket.name}\n" do - disable_versioning bucket_name: bucket.name - end - bucket.refresh! - refute bucket.versioning? - end - end - - describe "website_configuration" do - let(:main_page_suffix) { "index.html" } - let(:not_found_page) { "404.html" } - - it "define_bucket_website_configuration" do - expected_out = "Static website bucket #{bucket.name} is set up to use #{main_page_suffix} as the index page " \ - "and #{not_found_page} as the 404 page\n" - - assert_output expected_out do - define_bucket_website_configuration bucket_name: bucket.name, - main_page_suffix: main_page_suffix, - not_found_page: not_found_page - end - - bucket.refresh! - assert_equal main_page_suffix, bucket.website_main - assert_equal not_found_page, bucket.website_404 - end - end - - describe "public_access_prevention" do - it "set_public_access_prevention_enforced, get_public_access_prevention, " \ - "set_public_access_prevention_inherited" do - bucket.public_access_prevention = :inherited - bucket.refresh! - _(bucket.public_access_prevention).must_equal "inherited" - - # set_public_access_prevention_enforced - assert_output "Public access prevention is set to enforced for #{bucket.name}.\n" do - set_public_access_prevention_enforced bucket_name: bucket.name - end - - bucket.refresh! - _(bucket.public_access_prevention).must_equal "enforced" - - # get_public_access_prevention - assert_output "Public access prevention is 'enforced' for #{bucket.name}.\n" do - get_public_access_prevention bucket_name: bucket.name - end - _(bucket.public_access_prevention).must_equal "enforced" - - # set_public_access_prevention_inherited - assert_output "Public access prevention is 'inherited' for #{bucket.name}.\n" do - set_public_access_prevention_inherited bucket_name: bucket.name - end - - bucket.refresh! - _(bucket.public_access_prevention).must_equal "inherited" - bucket.public_access_prevention = :inherited - end - end - - describe "storage move file" do - let(:source_file) { "file_1_name_#{SecureRandom.hex}.txt" } - let(:destination_file) { "file_2_name_#{SecureRandom.hex}.txt" } - let :hns_bucket do - hierarchical_namespace = Google::Apis::StorageV1::Bucket::HierarchicalNamespace.new enabled: true - storage_client.create_bucket random_bucket_name do |b| - b.uniform_bucket_level_access = true - b.hierarchical_namespace = hierarchical_namespace - end - end - let :create_source_file do - file_content = "A" * (3 * 1024 * 1024) # 3 MB of 'A' characters - file = StringIO.new file_content - hns_bucket.create_file file, source_file - end - it "file is moved and old file is deleted" do - create_source_file - out, _err = capture_io do - move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: destination_file - end - assert_includes out, "New File #{destination_file} created\n" - refute_nil(hns_bucket.file(destination_file)) - assert_nil(hns_bucket.file(source_file)) - end - - it "raises error if source and destination are having same filename" do - create_source_file - exception = assert_raises Google::Cloud::InvalidArgumentError do - move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: source_file - end - assert_equal "invalid: Source and destination object names must be different.", exception.message - end - end - - describe "list buckets with partial success" do - it 'returns a list of bucket names if return_partial_success_flag is true' do - result = list_buckets_with_partial_success return_partial_success_flag: true - assert_kind_of Array, result - assert result.all? { |n| n.is_a? String }, "expected all items to be String" - end - - it 'returns nil for unreachable if return_partial_success_flag is false' do - result = list_buckets_with_partial_success return_partial_success_flag: false - assert_nil result - end - - it 'returns nil for unreachable if return_partial_success_flag is not passed' do - result = list_buckets_with_partial_success return_partial_success_flag: nil - assert_nil result - end - end + # describe "storage_create_bucket_with_object_retention" do + # it "creates a bucket with object retention enabled." do + # bucket_name = random_bucket_name + # refute storage_client.bucket bucket_name + + # expected = "Created bucket #{bucket_name} with object retention setting: Enabled\n" + + # retry_resource_exhaustion do + # assert_output expected do + # create_bucket_with_object_retention bucket_name: bucket_name + # end + # end + + # refute_nil storage_client.bucket bucket_name + + # file_name = "test_object_retention" + + # bucket = storage_client.bucket bucket_name + + # out, _err = capture_io do + # set_object_retention_policy bucket_name: bucket.name, + # content: "hello world", + # destination_file_name: file_name + # end + + # assert_includes out, "Retention policy for file #{file_name}" + + # file = bucket.file file_name + # file.retention = { + # mode: nil, + # retain_until_time: nil, + # override_unlocked_retention: true + # } + # delete_bucket_helper bucket_name + # end + # end + + # describe "autoclass" do + # it "get_autoclass, set_autoclass" do + # bucket_name = random_bucket_name + # refute storage_client.bucket bucket_name + + # storage_client.create_bucket bucket_name, autoclass_enabled: true + + # assert_output(/autoclass config set to true./) do + # get_autoclass bucket_name: bucket_name + # end + + # assert_output(/autoclass terminal storage class set to NEARLINE./) do + # get_autoclass bucket_name: bucket_name + # end + + # assert_output(/autoclass terminal storage class set to ARCHIVE./) do + # set_autoclass bucket_name: bucket_name, toggle: true, terminal_storage_class: "ARCHIVE" + # end + + # assert_output(/autoclass config set to false./) do + # set_autoclass bucket_name: bucket_name, toggle: false + # end + + # delete_bucket_helper bucket_name + # end + # end + + # describe "cors" do + # it "cors_configuration, remove_cors_configuration" do + # bucket.cors { |c| c.clear } + # assert bucket.cors.empty? + + # # cors_configuration + # assert_output "Set CORS policies for bucket #{bucket.name}\n" do + # cors_configuration bucket_name: bucket.name + # end + + # bucket.refresh! + # assert_equal 1, bucket.cors.count + # rule = bucket.cors.first + # assert_equal ["*"], rule.origin + # assert_equal ["PUT", "POST"], rule.methods + # assert_equal ["Content-Type", "x-goog-resumable"], rule.headers + # assert_equal 3600, rule.max_age + + # # remove_cors_configuration + # assert_output "Remove CORS policies for bucket #{bucket.name}\n" do + # remove_cors_configuration bucket_name: bucket.name + # end + # bucket.refresh! + # assert bucket.cors.empty? + # end + # end + + # describe "requester_pays" do + # it "enable_requester_pays, disable_requester_pays, get_requester_pays_status" do + # # enable_requester_pays + # bucket.requester_pays = false + + # assert_output "Requester pays has been enabled for #{bucket.name}\n" do + # enable_requester_pays bucket_name: bucket.name + # end + # bucket.refresh! + # assert bucket.requester_pays? + + # # get_requester_pays_status + # assert_output "Requester pays status is enabled for #{bucket.name}\n" do + # get_requester_pays_status bucket_name: bucket.name + # end + # assert bucket.requester_pays? + + # # disable_requester_pays + # assert_output "Requester pays has been disabled for #{bucket.name}\n" do + # disable_requester_pays bucket_name: bucket.name + # end + # bucket.refresh! + # refute bucket.requester_pays? + + # # get_requester_pays_status + # assert_output "Requester pays status is disabled for #{bucket.name}\n" do + # get_requester_pays_status bucket_name: bucket.name + # end + # refute bucket.requester_pays? + # end + # end + + # describe "uniform_bucket_level_access" do + # it "enable_uniform_bucket_level_access, get_uniform_bucket_level_access, disable_uniform_bucket_level_access" do + # # enable_uniform_bucket_level_access + # bucket.uniform_bucket_level_access = false + + # assert_output "Uniform bucket-level access was enabled for #{bucket.name}.\n" do + # enable_uniform_bucket_level_access bucket_name: bucket.name + # end + + # bucket.refresh! + # assert bucket.uniform_bucket_level_access? + + # # get_uniform_bucket_level_access + # assert_output "Uniform bucket-level access is enabled for #{bucket.name}.\nBucket " \ + # "will be locked on #{bucket.uniform_bucket_level_access_locked_at}.\n" do + # get_uniform_bucket_level_access bucket_name: bucket.name + # end + # assert bucket.uniform_bucket_level_access? + + # # disable_uniform_bucket_level_access + # assert_output "Uniform bucket-level access was disabled for #{bucket.name}.\n" do + # disable_uniform_bucket_level_access bucket_name: bucket.name + # end + + # bucket.refresh! + # refute bucket.uniform_bucket_level_access? + + # # get_uniform_bucket_level_access + # assert_output "Uniform bucket-level access is disabled for #{bucket.name}.\n" do + # get_uniform_bucket_level_access bucket_name: bucket.name + # end + # refute bucket.uniform_bucket_level_access? + + # bucket.uniform_bucket_level_access = false + # end + # end + + # describe "default Cloud KMS encryption key" do + # it "set_bucket_default_kms_key, bucket_delete_default_kms_key" do + # refute bucket.default_kms_key + + # # set_bucket_default_kms_key + # assert_output "Default KMS key for #{bucket.name} was set to #{kms_key}\n" do + # set_bucket_default_kms_key bucket_name: bucket.name, + # default_kms_key: kms_key + # end + + # bucket.refresh! + # assert_equal bucket.default_kms_key, kms_key + + # # bucket_delete_default_kms_key + # assert_output "Default KMS key was removed from #{bucket.name}\n" do + # bucket_delete_default_kms_key bucket_name: bucket.name + # end + + # bucket.refresh! + # refute bucket.default_kms_key + # end + # end + + # describe "get bucket class and location data" do + # bucket_name = random_bucket_name + # location = "US" + # storage_class = "COLDLINE" + + # it "get_bucket_class_and_location" do + # storage_client.create_bucket bucket_name, + # location: location, + # storage_class: storage_class + # expected_output = "Bucket #{bucket_name} storage class is " \ + # "#{storage_class}, and the location is #{location}\n" + # assert_output expected_output do + # get_bucket_class_and_location bucket_name: bucket_name + # end + # end + # end + + # describe "labels" do + # it "add_bucket_label, remove_bucket_label" do + # # add_bucket_label + # label_key = "label_key" + # label_value = "label_value" + + # assert_output "Added label #{label_key} with value #{label_value} to #{bucket.name}\n" do + # add_bucket_label bucket_name: bucket.name, + # label_value: label_value, + # label_key: label_key + # end + + # bucket.refresh! + # assert_equal bucket.labels[label_key], label_value + + # # remove_bucket_label + # assert_output "Deleted label #{label_key} from #{bucket.name}\n" do + # remove_bucket_label bucket_name: bucket.name, + # label_key: label_key + # end + + # bucket.refresh! + # assert bucket.labels[label_key].empty? + # end + # end + + # describe "lifecycle management" do + # let(:bucket) { create_bucket_helper random_bucket_name } + # after { delete_bucket_helper bucket.name } + + # it "enable_bucket_lifecycle_management, disable_bucket_lifecycle_management" do + # # enable_bucket_lifecycle_management + # out, _err = capture_io do + # enable_bucket_lifecycle_management bucket_name: bucket.name + # end + + # assert_includes out, "Lifecycle management is enabled" + + # # disable_bucket_lifecycle_management + # out, _err = capture_io do + # disable_bucket_lifecycle_management bucket_name: bucket.name + # end + + # assert_includes out, "Lifecycle management is disabled" + # end + # end + + # describe "retention policy" do + # let(:bucket) { create_bucket_helper random_bucket_name } + # after { delete_bucket_helper bucket.name } + + # it "set_retention_policy, get_retention_policy, remove_retention_policy" do + # # set_retention_policy + # assert_output "Retention period for #{bucket.name} is now #{retention_period} seconds.\n" do + # set_retention_policy bucket_name: bucket.name, + # retention_period: retention_period + # end + + # bucket.refresh! + # assert_equal bucket.retention_period, retention_period + + # # get_retention_policy + # out, _err = capture_io do + # get_retention_policy bucket_name: bucket.name + # end + + # assert_includes out, "period: #{retention_period}\n" + + # # remove_retention_policy + # assert_equal bucket.retention_period, retention_period + # assert_output "Retention policy for #{bucket.name} has been removed.\n" do + # remove_retention_policy bucket_name: bucket.name + # end + + # bucket.refresh! + # refute bucket.retention_period + + # # lock_retention_policy + # bucket.retention_period = retention_period + # out, _err = capture_io do + # lock_retention_policy bucket_name: bucket.name + # end + + # assert_includes out, "Retention policy for #{bucket.name} is now locked." + # bucket.refresh! + # assert bucket.retention_policy_locked? + + # # remove_retention_policy + # assert_output "Policy is locked and retention policy can't be removed.\n" do + # remove_retention_policy bucket_name: bucket.name + # end + # end + # end + + # describe "default_event_based_hold" do + # it "enable_default_event_based_hold, get_default_event_based_hold, disable_default_event_based_hold" do + # # enable_default_event_based_hold + # assert_output "Default event-based hold was enabled for #{bucket.name}.\n" do + # enable_default_event_based_hold bucket_name: bucket.name + # end + + # bucket.refresh! + # assert bucket.default_event_based_hold? + + # # get_default_event_based_hold + # assert_output "Default event-based hold is enabled for #{bucket.name}.\n" do + # get_default_event_based_hold bucket_name: bucket.name + # end + + # # disable_default_event_based_hold + # bucket.update do |b| + # b.default_event_based_hold = true + # end + + # assert_output "Default event-based hold was disabled for #{bucket.name}.\n" do + # disable_default_event_based_hold bucket_name: bucket.name + # end + + # bucket.refresh! + # refute bucket.default_event_based_hold? + + # # get_default_event_based_hold + # assert_output "Default event-based hold is not enabled for #{bucket.name}.\n" do + # get_default_event_based_hold bucket_name: bucket.name + # end + # end + # end + + # describe "storage_class" do + # it "change_default_storage_class" do + # assert_equal "STANDARD", bucket.storage_class + + # assert_output "Default storage class for bucket #{bucket.name} has been set to COLDLINE\n" do + # change_default_storage_class bucket_name: bucket.name + # end + + # bucket.refresh! + # assert_equal "COLDLINE", bucket.storage_class + # # teardown + # bucket.storage_class = "STANDARD" + # end + # end + + # describe "versioning" do + # it "enable_versioning, disable_versioning" do + # # enable_versioning + # bucket.versioning = false + + # assert_output "Versioning was enabled for bucket #{bucket.name}\n" do + # enable_versioning bucket_name: bucket.name + # end + # bucket.refresh! + # assert bucket.versioning? + + # # disable_versioning + # assert_output "Versioning was disabled for bucket #{bucket.name}\n" do + # disable_versioning bucket_name: bucket.name + # end + # bucket.refresh! + # refute bucket.versioning? + # end + # end + + # describe "website_configuration" do + # let(:main_page_suffix) { "index.html" } + # let(:not_found_page) { "404.html" } + + # it "define_bucket_website_configuration" do + # expected_out = "Static website bucket #{bucket.name} is set up to use #{main_page_suffix} as the index page " \ + # "and #{not_found_page} as the 404 page\n" + + # assert_output expected_out do + # define_bucket_website_configuration bucket_name: bucket.name, + # main_page_suffix: main_page_suffix, + # not_found_page: not_found_page + # end + + # bucket.refresh! + # assert_equal main_page_suffix, bucket.website_main + # assert_equal not_found_page, bucket.website_404 + # end + # end + + # describe "public_access_prevention" do + # it "set_public_access_prevention_enforced, get_public_access_prevention, " \ + # "set_public_access_prevention_inherited" do + # bucket.public_access_prevention = :inherited + # bucket.refresh! + # _(bucket.public_access_prevention).must_equal "inherited" + + # # set_public_access_prevention_enforced + # assert_output "Public access prevention is set to enforced for #{bucket.name}.\n" do + # set_public_access_prevention_enforced bucket_name: bucket.name + # end + + # bucket.refresh! + # _(bucket.public_access_prevention).must_equal "enforced" + + # # get_public_access_prevention + # assert_output "Public access prevention is 'enforced' for #{bucket.name}.\n" do + # get_public_access_prevention bucket_name: bucket.name + # end + # _(bucket.public_access_prevention).must_equal "enforced" + + # # set_public_access_prevention_inherited + # assert_output "Public access prevention is 'inherited' for #{bucket.name}.\n" do + # set_public_access_prevention_inherited bucket_name: bucket.name + # end + + # bucket.refresh! + # _(bucket.public_access_prevention).must_equal "inherited" + # bucket.public_access_prevention = :inherited + # end + # end + + # describe "storage move file" do + # let(:source_file) { "file_1_name_#{SecureRandom.hex}.txt" } + # let(:destination_file) { "file_2_name_#{SecureRandom.hex}.txt" } + # let :hns_bucket do + # hierarchical_namespace = Google::Apis::StorageV1::Bucket::HierarchicalNamespace.new enabled: true + # storage_client.create_bucket random_bucket_name do |b| + # b.uniform_bucket_level_access = true + # b.hierarchical_namespace = hierarchical_namespace + # end + # end + # let :create_source_file do + # file_content = "A" * (3 * 1024 * 1024) # 3 MB of 'A' characters + # file = StringIO.new file_content + # hns_bucket.create_file file, source_file + # end + # it "file is moved and old file is deleted" do + # create_source_file + # out, _err = capture_io do + # move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: destination_file + # end + # assert_includes out, "New File #{destination_file} created\n" + # refute_nil(hns_bucket.file(destination_file)) + # assert_nil(hns_bucket.file(source_file)) + # end + + # it "raises error if source and destination are having same filename" do + # create_source_file + # exception = assert_raises Google::Cloud::InvalidArgumentError do + # move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: source_file + # end + # assert_equal "invalid: Source and destination object names must be different.", exception.message + # end + # end + + # describe "list buckets with partial success" do + # it 'returns a list of bucket names if return_partial_success_flag is true' do + # result = list_buckets_with_partial_success return_partial_success_flag: true + # assert_kind_of Array, result + # assert result.all? { |n| n.is_a? String }, "expected all items to be String" + # end + + # it 'returns nil for unreachable if return_partial_success_flag is false' do + # result = list_buckets_with_partial_success return_partial_success_flag: false + # assert_nil result + # end + + # it 'returns nil for unreachable if return_partial_success_flag is not passed' do + # result = list_buckets_with_partial_success return_partial_success_flag: nil + # assert_nil result + # end + # end end diff --git a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb index e3e3858e8ffa..a1e5bed3ab32 100644 --- a/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb +++ b/google-cloud-storage/samples/storage_update_bucket_encryption_enforcement_config.rb @@ -23,12 +23,11 @@ def update_bucket_encryption_enforcement_config bucket_name: storage = Google::Cloud::Storage.new bucket = storage.bucket bucket_name # Update a specific type (e.g., change GMEK to NotRestricted) - new_config = { - google_managed_encryption_enforcement_config: { restriction_mode: "NotRestricted" } - } - - bucket.update_bucket_encryption_enforcement_config new_config + new_config = { restriction_mode: "NotRestricted" } + bucket.update do |b| + b.google_managed_encryption_enforcement_config = new_config + end puts "Updated google_managed_config to " \ "#{bucket.google_managed_encryption_enforcement_config.restriction_mode} " \ "for bucket #{bucket.name}." From 4f4e258c4c6ed9998b621d8a5b9d977c8b3519a2 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 14 Apr 2026 09:13:10 +0000 Subject: [PATCH 26/28] updating patch gapi --- google-cloud-storage/lib/google/cloud/storage/bucket.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index ae1e0e5f9603..3155d638c50e 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -3419,18 +3419,13 @@ def ensure_gapi! def patch_gapi! attributes, if_metageneration_match: nil, - if_metageneration_not_match: nil, - bucket_encryption_config: nil + if_metageneration_not_match: nil attributes = Array(attributes) attributes.flatten! return if attributes.empty? ensure_service! patch_args = attributes.to_h do |attr| - if bucket_encryption_config - [attr, bucket_encryption_config] - else - [attr, @gapi.send(attr)] - end + [attr, @gapi.send(attr)] end patch_gapi = API::Bucket.new(**patch_args) @gapi = service.patch_bucket name, From ef551cb883bc342e081544eaad895e2a9e0cbf7d Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 14 Apr 2026 09:14:53 +0000 Subject: [PATCH 27/28] updating acceptance tests --- .../samples/acceptance/buckets_test.rb | 1144 ++++++++--------- 1 file changed, 572 insertions(+), 572 deletions(-) diff --git a/google-cloud-storage/samples/acceptance/buckets_test.rb b/google-cloud-storage/samples/acceptance/buckets_test.rb index 65bd4efba249..90a62ec83352 100644 --- a/google-cloud-storage/samples/acceptance/buckets_test.rb +++ b/google-cloud-storage/samples/acceptance/buckets_test.rb @@ -66,112 +66,112 @@ let(:retention_period) { rand 1..99 } let(:bucket) { fixture_bucket } - # describe "bucket lifecycle" do - # it "create_bucket, create_bucket_class_location, list_buckets, get_bucket_metadata, delete_bucket" do - # # create_bucket - # bucket_name = random_bucket_name - # refute storage_client.bucket bucket_name - - # retry_resource_exhaustion do - # assert_output "Created bucket: #{bucket_name}\n" do - # create_bucket bucket_name: bucket_name - # end - # end - - # refute_nil storage_client.bucket bucket_name - - # # create_bucket_class_location - - # secondary_bucket_name = random_bucket_name - # location = "ASIA" - # storage_class = "COLDLINE" - # refute storage_client.bucket secondary_bucket_name - - # retry_resource_exhaustion do - # assert_output "Created bucket #{secondary_bucket_name} in #{location} with #{storage_class} class\n" do - # create_bucket_class_location bucket_name: secondary_bucket_name - # end - # end - - # secondary_bucket = storage_client.bucket secondary_bucket_name - # refute_nil secondary_bucket - # assert_equal location, secondary_bucket.location - # assert_equal storage_class, secondary_bucket.storage_class - - # # list_buckets - # out, _err = capture_io do - # list_buckets - # end - - # assert_includes out, "ruby-storage-samples-" - - # # get_bucket_metadata - # out, _err = capture_io do - # get_bucket_metadata bucket_name: bucket_name - # end - - # assert_includes out, bucket_name - - # # delete_bucket - # assert_output "Deleted bucket: #{bucket_name}\n" do - # delete_bucket bucket_name: bucket_name - # end - - - # refute storage_client.bucket bucket_name - - # delete_bucket_helper bucket_name - # delete_bucket_helper secondary_bucket_name - # end - # end - - # describe "storage_create_bucket_dual_region" do - # it "creates dual region bucket" do - # location = "US" - # region_1 = "US-EAST1" - # region_2 = "US-WEST1" - # location_type = "dual-region" - # bucket_name = random_bucket_name - # refute storage_client.bucket bucket_name - - # expected = "Bucket #{bucket_name} created:\n" - # expected += "- location: #{location}\n" - # expected += "- location_type: #{location_type}\n" - # expected += "- custom_placement_config:\n" - # expected += " - data_locations: #{[region_1, region_2]}\n" - - # retry_resource_exhaustion do - # assert_output expected do - # StorageCreateBucketDualRegion.new.storage_create_bucket_dual_region bucket_name: bucket_name, - # region_1: region_1, - # region_2: region_2 - # end - # end - - # refute_nil storage_client.bucket bucket_name - - # delete_bucket_helper bucket_name - # end - # end - - # describe "storage_create_bucket_hierarchical_namespace" do - # it "creates hierarchical namespace enabled bucket" do - # bucket_name = random_bucket_name - # refute storage_client.bucket bucket_name - - # expected = "Created bucket #{bucket_name} with Hierarchical Namespace enabled.\n" - - # retry_resource_exhaustion do - # assert_output expected do - # create_bucket_hierarchical_namespace bucket_name: bucket_name - # end - # end - - # refute_nil storage_client.bucket bucket_name - - # delete_bucket_helper bucket_name - # end - # end + describe "bucket lifecycle" do + it "create_bucket, create_bucket_class_location, list_buckets, get_bucket_metadata, delete_bucket" do + # create_bucket + bucket_name = random_bucket_name + refute storage_client.bucket bucket_name + + retry_resource_exhaustion do + assert_output "Created bucket: #{bucket_name}\n" do + create_bucket bucket_name: bucket_name + end + end + + refute_nil storage_client.bucket bucket_name + + # create_bucket_class_location + + secondary_bucket_name = random_bucket_name + location = "ASIA" + storage_class = "COLDLINE" + refute storage_client.bucket secondary_bucket_name + + retry_resource_exhaustion do + assert_output "Created bucket #{secondary_bucket_name} in #{location} with #{storage_class} class\n" do + create_bucket_class_location bucket_name: secondary_bucket_name + end + end + + secondary_bucket = storage_client.bucket secondary_bucket_name + refute_nil secondary_bucket + assert_equal location, secondary_bucket.location + assert_equal storage_class, secondary_bucket.storage_class + + # list_buckets + out, _err = capture_io do + list_buckets + end + + assert_includes out, "ruby-storage-samples-" + + # get_bucket_metadata + out, _err = capture_io do + get_bucket_metadata bucket_name: bucket_name + end + + assert_includes out, bucket_name + + # delete_bucket + assert_output "Deleted bucket: #{bucket_name}\n" do + delete_bucket bucket_name: bucket_name + end + + + refute storage_client.bucket bucket_name + + delete_bucket_helper bucket_name + delete_bucket_helper secondary_bucket_name + end + end + + describe "storage_create_bucket_dual_region" do + it "creates dual region bucket" do + location = "US" + region_1 = "US-EAST1" + region_2 = "US-WEST1" + location_type = "dual-region" + bucket_name = random_bucket_name + refute storage_client.bucket bucket_name + + expected = "Bucket #{bucket_name} created:\n" + expected += "- location: #{location}\n" + expected += "- location_type: #{location_type}\n" + expected += "- custom_placement_config:\n" + expected += " - data_locations: #{[region_1, region_2]}\n" + + retry_resource_exhaustion do + assert_output expected do + StorageCreateBucketDualRegion.new.storage_create_bucket_dual_region bucket_name: bucket_name, + region_1: region_1, + region_2: region_2 + end + end + + refute_nil storage_client.bucket bucket_name + + delete_bucket_helper bucket_name + end + end + + describe "storage_create_bucket_hierarchical_namespace" do + it "creates hierarchical namespace enabled bucket" do + bucket_name = random_bucket_name + refute storage_client.bucket bucket_name + + expected = "Created bucket #{bucket_name} with Hierarchical Namespace enabled.\n" + + retry_resource_exhaustion do + assert_output expected do + create_bucket_hierarchical_namespace bucket_name: bucket_name + end + end + + refute_nil storage_client.bucket bucket_name + + delete_bucket_helper bucket_name + end + end describe "storage_bucket_encryption_enforcement_config" do bucket_name = random_bucket_name @@ -211,470 +211,470 @@ delete_bucket_helper bucket_name end - # describe "storage_create_bucket_with_object_retention" do - # it "creates a bucket with object retention enabled." do - # bucket_name = random_bucket_name - # refute storage_client.bucket bucket_name - - # expected = "Created bucket #{bucket_name} with object retention setting: Enabled\n" - - # retry_resource_exhaustion do - # assert_output expected do - # create_bucket_with_object_retention bucket_name: bucket_name - # end - # end - - # refute_nil storage_client.bucket bucket_name - - # file_name = "test_object_retention" - - # bucket = storage_client.bucket bucket_name - - # out, _err = capture_io do - # set_object_retention_policy bucket_name: bucket.name, - # content: "hello world", - # destination_file_name: file_name - # end - - # assert_includes out, "Retention policy for file #{file_name}" - - # file = bucket.file file_name - # file.retention = { - # mode: nil, - # retain_until_time: nil, - # override_unlocked_retention: true - # } - # delete_bucket_helper bucket_name - # end - # end - - # describe "autoclass" do - # it "get_autoclass, set_autoclass" do - # bucket_name = random_bucket_name - # refute storage_client.bucket bucket_name - - # storage_client.create_bucket bucket_name, autoclass_enabled: true - - # assert_output(/autoclass config set to true./) do - # get_autoclass bucket_name: bucket_name - # end - - # assert_output(/autoclass terminal storage class set to NEARLINE./) do - # get_autoclass bucket_name: bucket_name - # end - - # assert_output(/autoclass terminal storage class set to ARCHIVE./) do - # set_autoclass bucket_name: bucket_name, toggle: true, terminal_storage_class: "ARCHIVE" - # end - - # assert_output(/autoclass config set to false./) do - # set_autoclass bucket_name: bucket_name, toggle: false - # end - - # delete_bucket_helper bucket_name - # end - # end - - # describe "cors" do - # it "cors_configuration, remove_cors_configuration" do - # bucket.cors { |c| c.clear } - # assert bucket.cors.empty? - - # # cors_configuration - # assert_output "Set CORS policies for bucket #{bucket.name}\n" do - # cors_configuration bucket_name: bucket.name - # end - - # bucket.refresh! - # assert_equal 1, bucket.cors.count - # rule = bucket.cors.first - # assert_equal ["*"], rule.origin - # assert_equal ["PUT", "POST"], rule.methods - # assert_equal ["Content-Type", "x-goog-resumable"], rule.headers - # assert_equal 3600, rule.max_age - - # # remove_cors_configuration - # assert_output "Remove CORS policies for bucket #{bucket.name}\n" do - # remove_cors_configuration bucket_name: bucket.name - # end - # bucket.refresh! - # assert bucket.cors.empty? - # end - # end - - # describe "requester_pays" do - # it "enable_requester_pays, disable_requester_pays, get_requester_pays_status" do - # # enable_requester_pays - # bucket.requester_pays = false - - # assert_output "Requester pays has been enabled for #{bucket.name}\n" do - # enable_requester_pays bucket_name: bucket.name - # end - # bucket.refresh! - # assert bucket.requester_pays? - - # # get_requester_pays_status - # assert_output "Requester pays status is enabled for #{bucket.name}\n" do - # get_requester_pays_status bucket_name: bucket.name - # end - # assert bucket.requester_pays? - - # # disable_requester_pays - # assert_output "Requester pays has been disabled for #{bucket.name}\n" do - # disable_requester_pays bucket_name: bucket.name - # end - # bucket.refresh! - # refute bucket.requester_pays? - - # # get_requester_pays_status - # assert_output "Requester pays status is disabled for #{bucket.name}\n" do - # get_requester_pays_status bucket_name: bucket.name - # end - # refute bucket.requester_pays? - # end - # end - - # describe "uniform_bucket_level_access" do - # it "enable_uniform_bucket_level_access, get_uniform_bucket_level_access, disable_uniform_bucket_level_access" do - # # enable_uniform_bucket_level_access - # bucket.uniform_bucket_level_access = false - - # assert_output "Uniform bucket-level access was enabled for #{bucket.name}.\n" do - # enable_uniform_bucket_level_access bucket_name: bucket.name - # end - - # bucket.refresh! - # assert bucket.uniform_bucket_level_access? - - # # get_uniform_bucket_level_access - # assert_output "Uniform bucket-level access is enabled for #{bucket.name}.\nBucket " \ - # "will be locked on #{bucket.uniform_bucket_level_access_locked_at}.\n" do - # get_uniform_bucket_level_access bucket_name: bucket.name - # end - # assert bucket.uniform_bucket_level_access? - - # # disable_uniform_bucket_level_access - # assert_output "Uniform bucket-level access was disabled for #{bucket.name}.\n" do - # disable_uniform_bucket_level_access bucket_name: bucket.name - # end - - # bucket.refresh! - # refute bucket.uniform_bucket_level_access? - - # # get_uniform_bucket_level_access - # assert_output "Uniform bucket-level access is disabled for #{bucket.name}.\n" do - # get_uniform_bucket_level_access bucket_name: bucket.name - # end - # refute bucket.uniform_bucket_level_access? - - # bucket.uniform_bucket_level_access = false - # end - # end - - # describe "default Cloud KMS encryption key" do - # it "set_bucket_default_kms_key, bucket_delete_default_kms_key" do - # refute bucket.default_kms_key - - # # set_bucket_default_kms_key - # assert_output "Default KMS key for #{bucket.name} was set to #{kms_key}\n" do - # set_bucket_default_kms_key bucket_name: bucket.name, - # default_kms_key: kms_key - # end - - # bucket.refresh! - # assert_equal bucket.default_kms_key, kms_key - - # # bucket_delete_default_kms_key - # assert_output "Default KMS key was removed from #{bucket.name}\n" do - # bucket_delete_default_kms_key bucket_name: bucket.name - # end - - # bucket.refresh! - # refute bucket.default_kms_key - # end - # end - - # describe "get bucket class and location data" do - # bucket_name = random_bucket_name - # location = "US" - # storage_class = "COLDLINE" - - # it "get_bucket_class_and_location" do - # storage_client.create_bucket bucket_name, - # location: location, - # storage_class: storage_class - # expected_output = "Bucket #{bucket_name} storage class is " \ - # "#{storage_class}, and the location is #{location}\n" - # assert_output expected_output do - # get_bucket_class_and_location bucket_name: bucket_name - # end - # end - # end - - # describe "labels" do - # it "add_bucket_label, remove_bucket_label" do - # # add_bucket_label - # label_key = "label_key" - # label_value = "label_value" - - # assert_output "Added label #{label_key} with value #{label_value} to #{bucket.name}\n" do - # add_bucket_label bucket_name: bucket.name, - # label_value: label_value, - # label_key: label_key - # end - - # bucket.refresh! - # assert_equal bucket.labels[label_key], label_value - - # # remove_bucket_label - # assert_output "Deleted label #{label_key} from #{bucket.name}\n" do - # remove_bucket_label bucket_name: bucket.name, - # label_key: label_key - # end - - # bucket.refresh! - # assert bucket.labels[label_key].empty? - # end - # end - - # describe "lifecycle management" do - # let(:bucket) { create_bucket_helper random_bucket_name } - # after { delete_bucket_helper bucket.name } - - # it "enable_bucket_lifecycle_management, disable_bucket_lifecycle_management" do - # # enable_bucket_lifecycle_management - # out, _err = capture_io do - # enable_bucket_lifecycle_management bucket_name: bucket.name - # end - - # assert_includes out, "Lifecycle management is enabled" - - # # disable_bucket_lifecycle_management - # out, _err = capture_io do - # disable_bucket_lifecycle_management bucket_name: bucket.name - # end - - # assert_includes out, "Lifecycle management is disabled" - # end - # end - - # describe "retention policy" do - # let(:bucket) { create_bucket_helper random_bucket_name } - # after { delete_bucket_helper bucket.name } - - # it "set_retention_policy, get_retention_policy, remove_retention_policy" do - # # set_retention_policy - # assert_output "Retention period for #{bucket.name} is now #{retention_period} seconds.\n" do - # set_retention_policy bucket_name: bucket.name, - # retention_period: retention_period - # end - - # bucket.refresh! - # assert_equal bucket.retention_period, retention_period - - # # get_retention_policy - # out, _err = capture_io do - # get_retention_policy bucket_name: bucket.name - # end - - # assert_includes out, "period: #{retention_period}\n" - - # # remove_retention_policy - # assert_equal bucket.retention_period, retention_period - # assert_output "Retention policy for #{bucket.name} has been removed.\n" do - # remove_retention_policy bucket_name: bucket.name - # end - - # bucket.refresh! - # refute bucket.retention_period - - # # lock_retention_policy - # bucket.retention_period = retention_period - # out, _err = capture_io do - # lock_retention_policy bucket_name: bucket.name - # end - - # assert_includes out, "Retention policy for #{bucket.name} is now locked." - # bucket.refresh! - # assert bucket.retention_policy_locked? - - # # remove_retention_policy - # assert_output "Policy is locked and retention policy can't be removed.\n" do - # remove_retention_policy bucket_name: bucket.name - # end - # end - # end - - # describe "default_event_based_hold" do - # it "enable_default_event_based_hold, get_default_event_based_hold, disable_default_event_based_hold" do - # # enable_default_event_based_hold - # assert_output "Default event-based hold was enabled for #{bucket.name}.\n" do - # enable_default_event_based_hold bucket_name: bucket.name - # end - - # bucket.refresh! - # assert bucket.default_event_based_hold? - - # # get_default_event_based_hold - # assert_output "Default event-based hold is enabled for #{bucket.name}.\n" do - # get_default_event_based_hold bucket_name: bucket.name - # end - - # # disable_default_event_based_hold - # bucket.update do |b| - # b.default_event_based_hold = true - # end - - # assert_output "Default event-based hold was disabled for #{bucket.name}.\n" do - # disable_default_event_based_hold bucket_name: bucket.name - # end - - # bucket.refresh! - # refute bucket.default_event_based_hold? - - # # get_default_event_based_hold - # assert_output "Default event-based hold is not enabled for #{bucket.name}.\n" do - # get_default_event_based_hold bucket_name: bucket.name - # end - # end - # end - - # describe "storage_class" do - # it "change_default_storage_class" do - # assert_equal "STANDARD", bucket.storage_class - - # assert_output "Default storage class for bucket #{bucket.name} has been set to COLDLINE\n" do - # change_default_storage_class bucket_name: bucket.name - # end - - # bucket.refresh! - # assert_equal "COLDLINE", bucket.storage_class - # # teardown - # bucket.storage_class = "STANDARD" - # end - # end - - # describe "versioning" do - # it "enable_versioning, disable_versioning" do - # # enable_versioning - # bucket.versioning = false - - # assert_output "Versioning was enabled for bucket #{bucket.name}\n" do - # enable_versioning bucket_name: bucket.name - # end - # bucket.refresh! - # assert bucket.versioning? - - # # disable_versioning - # assert_output "Versioning was disabled for bucket #{bucket.name}\n" do - # disable_versioning bucket_name: bucket.name - # end - # bucket.refresh! - # refute bucket.versioning? - # end - # end - - # describe "website_configuration" do - # let(:main_page_suffix) { "index.html" } - # let(:not_found_page) { "404.html" } - - # it "define_bucket_website_configuration" do - # expected_out = "Static website bucket #{bucket.name} is set up to use #{main_page_suffix} as the index page " \ - # "and #{not_found_page} as the 404 page\n" - - # assert_output expected_out do - # define_bucket_website_configuration bucket_name: bucket.name, - # main_page_suffix: main_page_suffix, - # not_found_page: not_found_page - # end - - # bucket.refresh! - # assert_equal main_page_suffix, bucket.website_main - # assert_equal not_found_page, bucket.website_404 - # end - # end - - # describe "public_access_prevention" do - # it "set_public_access_prevention_enforced, get_public_access_prevention, " \ - # "set_public_access_prevention_inherited" do - # bucket.public_access_prevention = :inherited - # bucket.refresh! - # _(bucket.public_access_prevention).must_equal "inherited" - - # # set_public_access_prevention_enforced - # assert_output "Public access prevention is set to enforced for #{bucket.name}.\n" do - # set_public_access_prevention_enforced bucket_name: bucket.name - # end - - # bucket.refresh! - # _(bucket.public_access_prevention).must_equal "enforced" - - # # get_public_access_prevention - # assert_output "Public access prevention is 'enforced' for #{bucket.name}.\n" do - # get_public_access_prevention bucket_name: bucket.name - # end - # _(bucket.public_access_prevention).must_equal "enforced" - - # # set_public_access_prevention_inherited - # assert_output "Public access prevention is 'inherited' for #{bucket.name}.\n" do - # set_public_access_prevention_inherited bucket_name: bucket.name - # end - - # bucket.refresh! - # _(bucket.public_access_prevention).must_equal "inherited" - # bucket.public_access_prevention = :inherited - # end - # end - - # describe "storage move file" do - # let(:source_file) { "file_1_name_#{SecureRandom.hex}.txt" } - # let(:destination_file) { "file_2_name_#{SecureRandom.hex}.txt" } - # let :hns_bucket do - # hierarchical_namespace = Google::Apis::StorageV1::Bucket::HierarchicalNamespace.new enabled: true - # storage_client.create_bucket random_bucket_name do |b| - # b.uniform_bucket_level_access = true - # b.hierarchical_namespace = hierarchical_namespace - # end - # end - # let :create_source_file do - # file_content = "A" * (3 * 1024 * 1024) # 3 MB of 'A' characters - # file = StringIO.new file_content - # hns_bucket.create_file file, source_file - # end - # it "file is moved and old file is deleted" do - # create_source_file - # out, _err = capture_io do - # move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: destination_file - # end - # assert_includes out, "New File #{destination_file} created\n" - # refute_nil(hns_bucket.file(destination_file)) - # assert_nil(hns_bucket.file(source_file)) - # end - - # it "raises error if source and destination are having same filename" do - # create_source_file - # exception = assert_raises Google::Cloud::InvalidArgumentError do - # move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: source_file - # end - # assert_equal "invalid: Source and destination object names must be different.", exception.message - # end - # end - - # describe "list buckets with partial success" do - # it 'returns a list of bucket names if return_partial_success_flag is true' do - # result = list_buckets_with_partial_success return_partial_success_flag: true - # assert_kind_of Array, result - # assert result.all? { |n| n.is_a? String }, "expected all items to be String" - # end - - # it 'returns nil for unreachable if return_partial_success_flag is false' do - # result = list_buckets_with_partial_success return_partial_success_flag: false - # assert_nil result - # end - - # it 'returns nil for unreachable if return_partial_success_flag is not passed' do - # result = list_buckets_with_partial_success return_partial_success_flag: nil - # assert_nil result - # end - # end + describe "storage_create_bucket_with_object_retention" do + it "creates a bucket with object retention enabled." do + bucket_name = random_bucket_name + refute storage_client.bucket bucket_name + + expected = "Created bucket #{bucket_name} with object retention setting: Enabled\n" + + retry_resource_exhaustion do + assert_output expected do + create_bucket_with_object_retention bucket_name: bucket_name + end + end + + refute_nil storage_client.bucket bucket_name + + file_name = "test_object_retention" + + bucket = storage_client.bucket bucket_name + + out, _err = capture_io do + set_object_retention_policy bucket_name: bucket.name, + content: "hello world", + destination_file_name: file_name + end + + assert_includes out, "Retention policy for file #{file_name}" + + file = bucket.file file_name + file.retention = { + mode: nil, + retain_until_time: nil, + override_unlocked_retention: true + } + delete_bucket_helper bucket_name + end + end + + describe "autoclass" do + it "get_autoclass, set_autoclass" do + bucket_name = random_bucket_name + refute storage_client.bucket bucket_name + + storage_client.create_bucket bucket_name, autoclass_enabled: true + + assert_output(/autoclass config set to true./) do + get_autoclass bucket_name: bucket_name + end + + assert_output(/autoclass terminal storage class set to NEARLINE./) do + get_autoclass bucket_name: bucket_name + end + + assert_output(/autoclass terminal storage class set to ARCHIVE./) do + set_autoclass bucket_name: bucket_name, toggle: true, terminal_storage_class: "ARCHIVE" + end + + assert_output(/autoclass config set to false./) do + set_autoclass bucket_name: bucket_name, toggle: false + end + + delete_bucket_helper bucket_name + end + end + + describe "cors" do + it "cors_configuration, remove_cors_configuration" do + bucket.cors { |c| c.clear } + assert bucket.cors.empty? + + # cors_configuration + assert_output "Set CORS policies for bucket #{bucket.name}\n" do + cors_configuration bucket_name: bucket.name + end + + bucket.refresh! + assert_equal 1, bucket.cors.count + rule = bucket.cors.first + assert_equal ["*"], rule.origin + assert_equal ["PUT", "POST"], rule.methods + assert_equal ["Content-Type", "x-goog-resumable"], rule.headers + assert_equal 3600, rule.max_age + + # remove_cors_configuration + assert_output "Remove CORS policies for bucket #{bucket.name}\n" do + remove_cors_configuration bucket_name: bucket.name + end + bucket.refresh! + assert bucket.cors.empty? + end + end + + describe "requester_pays" do + it "enable_requester_pays, disable_requester_pays, get_requester_pays_status" do + # enable_requester_pays + bucket.requester_pays = false + + assert_output "Requester pays has been enabled for #{bucket.name}\n" do + enable_requester_pays bucket_name: bucket.name + end + bucket.refresh! + assert bucket.requester_pays? + + # get_requester_pays_status + assert_output "Requester pays status is enabled for #{bucket.name}\n" do + get_requester_pays_status bucket_name: bucket.name + end + assert bucket.requester_pays? + + # disable_requester_pays + assert_output "Requester pays has been disabled for #{bucket.name}\n" do + disable_requester_pays bucket_name: bucket.name + end + bucket.refresh! + refute bucket.requester_pays? + + # get_requester_pays_status + assert_output "Requester pays status is disabled for #{bucket.name}\n" do + get_requester_pays_status bucket_name: bucket.name + end + refute bucket.requester_pays? + end + end + + describe "uniform_bucket_level_access" do + it "enable_uniform_bucket_level_access, get_uniform_bucket_level_access, disable_uniform_bucket_level_access" do + # enable_uniform_bucket_level_access + bucket.uniform_bucket_level_access = false + + assert_output "Uniform bucket-level access was enabled for #{bucket.name}.\n" do + enable_uniform_bucket_level_access bucket_name: bucket.name + end + + bucket.refresh! + assert bucket.uniform_bucket_level_access? + + # get_uniform_bucket_level_access + assert_output "Uniform bucket-level access is enabled for #{bucket.name}.\nBucket " \ + "will be locked on #{bucket.uniform_bucket_level_access_locked_at}.\n" do + get_uniform_bucket_level_access bucket_name: bucket.name + end + assert bucket.uniform_bucket_level_access? + + # disable_uniform_bucket_level_access + assert_output "Uniform bucket-level access was disabled for #{bucket.name}.\n" do + disable_uniform_bucket_level_access bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.uniform_bucket_level_access? + + # get_uniform_bucket_level_access + assert_output "Uniform bucket-level access is disabled for #{bucket.name}.\n" do + get_uniform_bucket_level_access bucket_name: bucket.name + end + refute bucket.uniform_bucket_level_access? + + bucket.uniform_bucket_level_access = false + end + end + + describe "default Cloud KMS encryption key" do + it "set_bucket_default_kms_key, bucket_delete_default_kms_key" do + refute bucket.default_kms_key + + # set_bucket_default_kms_key + assert_output "Default KMS key for #{bucket.name} was set to #{kms_key}\n" do + set_bucket_default_kms_key bucket_name: bucket.name, + default_kms_key: kms_key + end + + bucket.refresh! + assert_equal bucket.default_kms_key, kms_key + + # bucket_delete_default_kms_key + assert_output "Default KMS key was removed from #{bucket.name}\n" do + bucket_delete_default_kms_key bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.default_kms_key + end + end + + describe "get bucket class and location data" do + bucket_name = random_bucket_name + location = "US" + storage_class = "COLDLINE" + + it "get_bucket_class_and_location" do + storage_client.create_bucket bucket_name, + location: location, + storage_class: storage_class + expected_output = "Bucket #{bucket_name} storage class is " \ + "#{storage_class}, and the location is #{location}\n" + assert_output expected_output do + get_bucket_class_and_location bucket_name: bucket_name + end + end + end + + describe "labels" do + it "add_bucket_label, remove_bucket_label" do + # add_bucket_label + label_key = "label_key" + label_value = "label_value" + + assert_output "Added label #{label_key} with value #{label_value} to #{bucket.name}\n" do + add_bucket_label bucket_name: bucket.name, + label_value: label_value, + label_key: label_key + end + + bucket.refresh! + assert_equal bucket.labels[label_key], label_value + + # remove_bucket_label + assert_output "Deleted label #{label_key} from #{bucket.name}\n" do + remove_bucket_label bucket_name: bucket.name, + label_key: label_key + end + + bucket.refresh! + assert bucket.labels[label_key].empty? + end + end + + describe "lifecycle management" do + let(:bucket) { create_bucket_helper random_bucket_name } + after { delete_bucket_helper bucket.name } + + it "enable_bucket_lifecycle_management, disable_bucket_lifecycle_management" do + # enable_bucket_lifecycle_management + out, _err = capture_io do + enable_bucket_lifecycle_management bucket_name: bucket.name + end + + assert_includes out, "Lifecycle management is enabled" + + # disable_bucket_lifecycle_management + out, _err = capture_io do + disable_bucket_lifecycle_management bucket_name: bucket.name + end + + assert_includes out, "Lifecycle management is disabled" + end + end + + describe "retention policy" do + let(:bucket) { create_bucket_helper random_bucket_name } + after { delete_bucket_helper bucket.name } + + it "set_retention_policy, get_retention_policy, remove_retention_policy" do + # set_retention_policy + assert_output "Retention period for #{bucket.name} is now #{retention_period} seconds.\n" do + set_retention_policy bucket_name: bucket.name, + retention_period: retention_period + end + + bucket.refresh! + assert_equal bucket.retention_period, retention_period + + # get_retention_policy + out, _err = capture_io do + get_retention_policy bucket_name: bucket.name + end + + assert_includes out, "period: #{retention_period}\n" + + # remove_retention_policy + assert_equal bucket.retention_period, retention_period + assert_output "Retention policy for #{bucket.name} has been removed.\n" do + remove_retention_policy bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.retention_period + + # lock_retention_policy + bucket.retention_period = retention_period + out, _err = capture_io do + lock_retention_policy bucket_name: bucket.name + end + + assert_includes out, "Retention policy for #{bucket.name} is now locked." + bucket.refresh! + assert bucket.retention_policy_locked? + + # remove_retention_policy + assert_output "Policy is locked and retention policy can't be removed.\n" do + remove_retention_policy bucket_name: bucket.name + end + end + end + + describe "default_event_based_hold" do + it "enable_default_event_based_hold, get_default_event_based_hold, disable_default_event_based_hold" do + # enable_default_event_based_hold + assert_output "Default event-based hold was enabled for #{bucket.name}.\n" do + enable_default_event_based_hold bucket_name: bucket.name + end + + bucket.refresh! + assert bucket.default_event_based_hold? + + # get_default_event_based_hold + assert_output "Default event-based hold is enabled for #{bucket.name}.\n" do + get_default_event_based_hold bucket_name: bucket.name + end + + # disable_default_event_based_hold + bucket.update do |b| + b.default_event_based_hold = true + end + + assert_output "Default event-based hold was disabled for #{bucket.name}.\n" do + disable_default_event_based_hold bucket_name: bucket.name + end + + bucket.refresh! + refute bucket.default_event_based_hold? + + # get_default_event_based_hold + assert_output "Default event-based hold is not enabled for #{bucket.name}.\n" do + get_default_event_based_hold bucket_name: bucket.name + end + end + end + + describe "storage_class" do + it "change_default_storage_class" do + assert_equal "STANDARD", bucket.storage_class + + assert_output "Default storage class for bucket #{bucket.name} has been set to COLDLINE\n" do + change_default_storage_class bucket_name: bucket.name + end + + bucket.refresh! + assert_equal "COLDLINE", bucket.storage_class + # teardown + bucket.storage_class = "STANDARD" + end + end + + describe "versioning" do + it "enable_versioning, disable_versioning" do + # enable_versioning + bucket.versioning = false + + assert_output "Versioning was enabled for bucket #{bucket.name}\n" do + enable_versioning bucket_name: bucket.name + end + bucket.refresh! + assert bucket.versioning? + + # disable_versioning + assert_output "Versioning was disabled for bucket #{bucket.name}\n" do + disable_versioning bucket_name: bucket.name + end + bucket.refresh! + refute bucket.versioning? + end + end + + describe "website_configuration" do + let(:main_page_suffix) { "index.html" } + let(:not_found_page) { "404.html" } + + it "define_bucket_website_configuration" do + expected_out = "Static website bucket #{bucket.name} is set up to use #{main_page_suffix} as the index page " \ + "and #{not_found_page} as the 404 page\n" + + assert_output expected_out do + define_bucket_website_configuration bucket_name: bucket.name, + main_page_suffix: main_page_suffix, + not_found_page: not_found_page + end + + bucket.refresh! + assert_equal main_page_suffix, bucket.website_main + assert_equal not_found_page, bucket.website_404 + end + end + + describe "public_access_prevention" do + it "set_public_access_prevention_enforced, get_public_access_prevention, " \ + "set_public_access_prevention_inherited" do + bucket.public_access_prevention = :inherited + bucket.refresh! + _(bucket.public_access_prevention).must_equal "inherited" + + # set_public_access_prevention_enforced + assert_output "Public access prevention is set to enforced for #{bucket.name}.\n" do + set_public_access_prevention_enforced bucket_name: bucket.name + end + + bucket.refresh! + _(bucket.public_access_prevention).must_equal "enforced" + + # get_public_access_prevention + assert_output "Public access prevention is 'enforced' for #{bucket.name}.\n" do + get_public_access_prevention bucket_name: bucket.name + end + _(bucket.public_access_prevention).must_equal "enforced" + + # set_public_access_prevention_inherited + assert_output "Public access prevention is 'inherited' for #{bucket.name}.\n" do + set_public_access_prevention_inherited bucket_name: bucket.name + end + + bucket.refresh! + _(bucket.public_access_prevention).must_equal "inherited" + bucket.public_access_prevention = :inherited + end + end + + describe "storage move file" do + let(:source_file) { "file_1_name_#{SecureRandom.hex}.txt" } + let(:destination_file) { "file_2_name_#{SecureRandom.hex}.txt" } + let :hns_bucket do + hierarchical_namespace = Google::Apis::StorageV1::Bucket::HierarchicalNamespace.new enabled: true + storage_client.create_bucket random_bucket_name do |b| + b.uniform_bucket_level_access = true + b.hierarchical_namespace = hierarchical_namespace + end + end + let :create_source_file do + file_content = "A" * (3 * 1024 * 1024) # 3 MB of 'A' characters + file = StringIO.new file_content + hns_bucket.create_file file, source_file + end + it "file is moved and old file is deleted" do + create_source_file + out, _err = capture_io do + move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: destination_file + end + assert_includes out, "New File #{destination_file} created\n" + refute_nil(hns_bucket.file(destination_file)) + assert_nil(hns_bucket.file(source_file)) + end + + it "raises error if source and destination are having same filename" do + create_source_file + exception = assert_raises Google::Cloud::InvalidArgumentError do + move_object bucket_name: hns_bucket.name, source_file_name: source_file, destination_file_name: source_file + end + assert_equal "invalid: Source and destination object names must be different.", exception.message + end + end + + describe "list buckets with partial success" do + it 'returns a list of bucket names if return_partial_success_flag is true' do + result = list_buckets_with_partial_success return_partial_success_flag: true + assert_kind_of Array, result + assert result.all? { |n| n.is_a? String }, "expected all items to be String" + end + + it 'returns nil for unreachable if return_partial_success_flag is false' do + result = list_buckets_with_partial_success return_partial_success_flag: false + assert_nil result + end + + it 'returns nil for unreachable if return_partial_success_flag is not passed' do + result = list_buckets_with_partial_success return_partial_success_flag: nil + assert_nil result + end + end end From 736b3f60c52c3db0c105fb90ae235d53efcf56a4 Mon Sep 17 00:00:00 2001 From: Shubhangi Singh Date: Tue, 14 Apr 2026 14:16:24 +0000 Subject: [PATCH 28/28] updating tests --- .../storage/bucket_encryption_test.rb | 8 ---- .../lib/google/cloud/storage/bucket.rb | 39 ++++++++++--------- .../cloud/storage/bucket_encryption_test.rb | 35 +++++++++-------- 3 files changed, 39 insertions(+), 43 deletions(-) diff --git a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb index 0af10571bf66..bec4e32da3a7 100644 --- a/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/acceptance/storage/bucket_encryption_test.rb @@ -115,14 +115,6 @@ end it "deletes all encryption enforcement configs" do - # For the update, need to specify all three configs - bucket.update do |b| - b.customer_supplied_encryption_enforcement_config = customer_supplied_config - b.google_managed_encryption_enforcement_config = google_managed_config - end - _(bucket.customer_managed_encryption_enforcement_config).wont_be :nil? - _(bucket.customer_supplied_encryption_enforcement_config).wont_be :nil? - _(bucket.google_managed_encryption_enforcement_config).wont_be :nil? bucket.update do |b| b.customer_managed_encryption_enforcement_config = nil diff --git a/google-cloud-storage/lib/google/cloud/storage/bucket.rb b/google-cloud-storage/lib/google/cloud/storage/bucket.rb index 3155d638c50e..1fae4642d8b7 100644 --- a/google-cloud-storage/lib/google/cloud/storage/bucket.rb +++ b/google-cloud-storage/lib/google/cloud/storage/bucket.rb @@ -3527,25 +3527,6 @@ def cors yield @cors_builder if block_given? @cors_builder end - def check_for_encryption_enforcement_config! - return unless @gapi.encryption - - configs = [ - :google_managed_encryption_enforcement_config, - :customer_managed_encryption_enforcement_config, - :customer_supplied_encryption_enforcement_config - ] - - configs.each do |config_name| - sub_config = @gapi.encryption.send config_name - if sub_config.respond_to? :effective_time= - sub_config.effective_time = nil - elsif sub_config.is_a? Hash - sub_config.delete :effective_time - sub_config.delete "effective_time" - end - end - end ## # @private Make sure any cors changes are saved @@ -3572,6 +3553,26 @@ def check_for_mutable_lifecycle! patch_gapi! :lifecycle end + def check_for_encryption_enforcement_config! + return unless @gapi.encryption + + [ + :google_managed_encryption_enforcement_config, + :customer_managed_encryption_enforcement_config, + :customer_supplied_encryption_enforcement_config + ].each do |attr| + config = @gapi.encryption.send(attr) + next unless config + unless config.respond_to?(:to_h) + raise ArgumentError, "Encryption config for #{attr} must be a Hash or valid Config object" + end + clean_config = config.to_h + clean_config.delete :effective_time + clean_config.delete "effective_time" + @gapi.encryption.send "#{attr}=", clean_config + end + end + protected ## diff --git a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb index 622ba78f7245..9b21317bc276 100644 --- a/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb +++ b/google-cloud-storage/test/google/cloud/storage/bucket_encryption_test.rb @@ -149,7 +149,7 @@ it "updates encryption_enforcement_config using update_bucket_encryption_enforcement_config" do mock = Minitest::Mock.new - incoming_config = { google_managed_encryption_enforcement_config: { restriction_mode: "FullyRestricted" } } + incoming_config = { restriction_mode: "FullyRestricted" } patch_bucket_gapi = Google::Apis::StorageV1::Bucket.new( encryption: Google::Apis::StorageV1::Bucket::Encryption.new( @@ -162,14 +162,23 @@ returned_bucket_gapi = bucket_gapi.dup returned_bucket_gapi.encryption = bucket_gapi.encryption.dup returned_bucket_gapi.encryption.google_managed_encryption_enforcement_config = patch_bucket_gapi.encryption.google_managed_encryption_enforcement_config - mock.expect :patch_bucket, returned_bucket_gapi, [bucket_name, patch_bucket_gapi], **patch_bucket_args(options: { retries: 0 }) + + mock.expect :update_bucket, returned_bucket_gapi do |name, patch_obj, **kwargs| + cm_config = patch_obj.encryption.customer_managed_encryption_enforcement_config + cs_config = patch_obj.encryption.customer_supplied_encryption_enforcement_config + gm_config = patch_obj.encryption.google_managed_encryption_enforcement_config + + end bucket.service.mocked_service = mock _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" - bucket.update_bucket_encryption_enforcement_config incoming_config + bucket.update do |b| + b.google_managed_encryption_enforcement_config = incoming_config + end + # bucket.update_bucket_encryption_enforcement_config incoming_config _(bucket.customer_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" _(bucket.customer_supplied_encryption_enforcement_config.restriction_mode).must_equal "NotRestricted" _(bucket.google_managed_encryption_enforcement_config.restriction_mode).must_equal "FullyRestricted" @@ -177,24 +186,18 @@ mock.verify end - it "raises error when invalid config is provided for update " do - config = { - wrongconfig: { restriction_mode: "NotRestricted" } - } - err = assert_raises(ArgumentError) do - bucket.update_bucket_encryption_enforcement_config(config) - end - assert_match /Invalid config detected: wrongconfig/, err.message - end + it "raises error when a Hash is not provided for encryption enforcement config" do + invalid_config = "test" - it "raises error when a Hash in not provided for update " do - config = "wrongconfig" err = assert_raises(ArgumentError) do - bucket.update_bucket_encryption_enforcement_config(config) + bucket.update do |b| + b.google_managed_encryption_enforcement_config = invalid_config + end end - assert /incoming_config must be a Hash/ + # Update the regex to match the error message in your validation method + assert_match(/must be a Hash or valid Config object/, err.message) end it "deletes all encryption enforcement configs together and preserves default_kms_key" do