-
Notifications
You must be signed in to change notification settings - Fork 567
feat(storage): Support bucket encryption config #33452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
598851a
53ee419
be44e07
96e3fa2
3658979
221d38b
a0ddae3
87a5e37
d01e6d1
a21d625
2d5b5e3
67e25f9
69e6fd9
f88d02e
27632c6
794c7cc
d7a5cca
36ea00e
88c4b82
0b76c34
e493d07
b4e1f13
c816b92
13a50a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -716,6 +716,228 @@ 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. | ||
| # 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:0x00007f3b1c102e90 @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 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" | ||
| # | ||
| # # Set restriction mode to FullyRestricted | ||
| # new_config = { restriction_mode: "FullyRestricted" } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for updating this. We should also add example of how we can set it using the request object.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| # bucket.customer_managed_encryption_enforcement_config = new_config | ||
| # | ||
| # @example Setting via Request Object (Google API Client) | ||
| # require "google/apis/storage_v1" | ||
| # | ||
| # enforcement_config = { restriction_mode: "FullyRestricted" } | ||
| # | ||
| # 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 | ||
| @gapi.encryption.customer_managed_encryption_enforcement_config = | ||
| new_customer_managed_encryption_enforcement_config || {} | ||
| 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/). | ||
| # @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:0x00007f3b1c102e90 @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-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 = { restriction_mode: "FullyRestricted" } | ||
shubhangi-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # bucket.customer_supplied_encryption_enforcement_config = new_config | ||
| # | ||
| # @example Setting via Request Object (Google API Client) | ||
| # require "google/apis/storage_v1" | ||
| # | ||
| # enforcement_config = { restriction_mode: "FullyRestricted" } | ||
| # | ||
| # 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 | ||
| @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:0x00007f3b1c102e90 @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 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" | ||
| # | ||
| # # Set restriction mode to FullyRestricted | ||
| # new_config = { restriction_mode: "FullyRestricted" } | ||
| # bucket.new_google_managed_encryption_enforcement_config = new_config | ||
| # | ||
| # @example Setting via Request Object (Google API Client) | ||
| # require "google/apis/storage_v1" | ||
| # | ||
| # enforcement_config = { restriction_mode: "FullyRestricted" } | ||
| # | ||
| # 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 | ||
| @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 | ||
|
|
@@ -3252,13 +3474,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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we introducing new parameter here? Why can't we combine this in existing parameter
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When using the standard The FixWe implemented the update_bucket_encryption_enforcement_configmethod to send only the changed data to the patch request. How it Works
update_bucket_encryption_enforcement_config sends the correct patch json in bucket_encryption_config Comparison of JSON PayloadsWrong Request (Polluted){
"encryption": {
"customerManagedEncryptionEnforcementConfig": {
"restrictionMode": "NotRestricted"
},
"customerSuppliedEncryptionEnforcementConfig": {
"restrictionMode": "NotRestricted"
},
"googleManagedEncryptionEnforcementConfig": {
"effectiveTime": "2026-03-25T11:40:17.182+00:00",
"restrictionMode": "FullyRestricted"
}
}
}Correct request{
"encryption": {
"customerManagedEncryptionEnforcementConfig": {
"restrictionMode": "NotRestricted"
}
}
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bajajneha27 can you please provide your views on this approach
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. User can still pass
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Besides, if user wants to update other attributes AND bucket_encryption_configs, that won't work
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @bajajneha27 the existing patch method is sending all the encryption attribute (the existing one and the updated patch together)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't follow. Why would you get
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Example we want to update customerManagedEncryptionEnforcementConfig restriction mode to "FullyRestricted" {
"encryption": {
"customerManagedEncryptionEnforcementConfig": {
"restrictionMode": "NotRestricted"
},
"customerSuppliedEncryptionEnforcementConfig": {
"restrictionMode": "NotRestricted"
},
"googleManagedEncryptionEnforcementConfig": {
"effectiveTime": "2026-03-25T11:40:17.182+00:00",
"restrictionMode": "FullyRestricted"
}
}
}when this hash is submitted to server its returning error |
||
| 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, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this statement is correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got reference from Java pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nidhiii-27 Is this correct statement?