mirror of
https://github.com/ansible-collections/google.cloud.git
synced 2025-08-04 05:04:27 -07:00
Add iamConfiguration support to gcp_storage_bucket
You can now set the iam configuration for a given bucket, you can set: 1. publicAccessPrevention and 2. uniformBucketLevelAccess no support for bucketPolicyOnly because according to the storage docs: Note: iamConfiguration also includes the bucketPolicyOnly field, which uses a legacy name but has the same functionality as the uniformBucketLevelAccess field. We recommend only using uniformBucketLevelAccess, as specifying both fields may result in unreliable behavior. Also added integration tests for this feature Signed-off-by: Jorge Gallegos <jgallego@redhat.com>
This commit is contained in:
parent
8863545bef
commit
f9f0b33542
3 changed files with 180 additions and 2 deletions
|
@ -186,6 +186,33 @@ options:
|
||||||
- 'Some valid choices include: "OWNER", "READER"'
|
- 'Some valid choices include: "OWNER", "READER"'
|
||||||
required: true
|
required: true
|
||||||
type: str
|
type: str
|
||||||
|
iam_configuration:
|
||||||
|
description:
|
||||||
|
- IAM configuration for the storage bucket.
|
||||||
|
required: false
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
public_access_prevention:
|
||||||
|
description:
|
||||||
|
- The bucket's public access prevention status.
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
|
default: inherited
|
||||||
|
choices:
|
||||||
|
- inherited
|
||||||
|
- enforced
|
||||||
|
uniform_bucket_level_access:
|
||||||
|
description:
|
||||||
|
- The bucket's uniform bucket-level access configuration.
|
||||||
|
required: false
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
enabled:
|
||||||
|
description:
|
||||||
|
- Whether or not the bucket uses uniform bucket-level access.
|
||||||
|
- If set, access checks only use bucket-level IAM policies or above.
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
lifecycle:
|
lifecycle:
|
||||||
description:
|
description:
|
||||||
- The bucket's lifecycle configuration.
|
- The bucket's lifecycle configuration.
|
||||||
|
@ -209,7 +236,7 @@ options:
|
||||||
suboptions:
|
suboptions:
|
||||||
storage_class:
|
storage_class:
|
||||||
description:
|
description:
|
||||||
- Target storage class. Required iff the type of the action is SetStorageClass.
|
- Target storage class. Required if the type of the action is SetStorageClass.
|
||||||
required: false
|
required: false
|
||||||
type: str
|
type: str
|
||||||
type:
|
type:
|
||||||
|
@ -627,6 +654,29 @@ defaultObjectAcl:
|
||||||
- The access permission for the entity.
|
- The access permission for the entity.
|
||||||
returned: success
|
returned: success
|
||||||
type: str
|
type: str
|
||||||
|
iamConfiguration:
|
||||||
|
description:
|
||||||
|
- IAM configuration for the storage bucket.
|
||||||
|
returned: success
|
||||||
|
type: complex
|
||||||
|
contains:
|
||||||
|
publicAccessPrevention:
|
||||||
|
description:
|
||||||
|
- The bucket's public access prevention status.
|
||||||
|
returned: success
|
||||||
|
type: str
|
||||||
|
uniformBucketLevelAccess:
|
||||||
|
description:
|
||||||
|
- The bucket's uniform bucket-level access configuration.
|
||||||
|
returned: success
|
||||||
|
type: complex
|
||||||
|
contains:
|
||||||
|
enabled:
|
||||||
|
description:
|
||||||
|
- Whether or not the bucket uses uniform bucket-level access.
|
||||||
|
- If set, access checks only use bucket-level IAM policies or above.
|
||||||
|
returned: success
|
||||||
|
type: bool
|
||||||
id:
|
id:
|
||||||
description:
|
description:
|
||||||
- The ID of the bucket. For buckets, the id and name properities are the same.
|
- The ID of the bucket. For buckets, the id and name properities are the same.
|
||||||
|
@ -922,6 +972,21 @@ def main():
|
||||||
role=dict(required=True, type='str'),
|
role=dict(required=True, type='str'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
iam_configuration=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
public_access_prevention=dict(
|
||||||
|
type='str', default='inherited',
|
||||||
|
choices=['inherited', 'enforced'],
|
||||||
|
),
|
||||||
|
uniform_bucket_level_access=dict(
|
||||||
|
type='dict',
|
||||||
|
options=dict(
|
||||||
|
enabled=dict(type='bool'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
lifecycle=dict(
|
lifecycle=dict(
|
||||||
type='dict',
|
type='dict',
|
||||||
options=dict(
|
options=dict(
|
||||||
|
@ -1017,6 +1082,7 @@ def resource_to_request(module):
|
||||||
u'cors': BucketCorsArray(module.params.get('cors', []), module).to_request(),
|
u'cors': BucketCorsArray(module.params.get('cors', []), module).to_request(),
|
||||||
u'defaultEventBasedHold': module.params.get('default_event_based_hold'),
|
u'defaultEventBasedHold': module.params.get('default_event_based_hold'),
|
||||||
u'defaultObjectAcl': BucketDefaultobjectaclArray(module.params.get('default_object_acl', []), module).to_request(),
|
u'defaultObjectAcl': BucketDefaultobjectaclArray(module.params.get('default_object_acl', []), module).to_request(),
|
||||||
|
u'iamConfiguration': BucketIamconfiguration(module.params.get('iam_configuration', {}), module).to_request(),
|
||||||
u'lifecycle': BucketLifecycle(module.params.get('lifecycle', {}), module).to_request(),
|
u'lifecycle': BucketLifecycle(module.params.get('lifecycle', {}), module).to_request(),
|
||||||
u'location': module.params.get('location'),
|
u'location': module.params.get('location'),
|
||||||
u'logging': BucketLogging(module.params.get('logging', {}), module).to_request(),
|
u'logging': BucketLogging(module.params.get('logging', {}), module).to_request(),
|
||||||
|
@ -1095,8 +1161,9 @@ def response_to_hash(module, response):
|
||||||
u'acl': BucketAclArray(response.get(u'acl', []), module).from_response(),
|
u'acl': BucketAclArray(response.get(u'acl', []), module).from_response(),
|
||||||
u'cors': BucketCorsArray(response.get(u'cors', []), module).from_response(),
|
u'cors': BucketCorsArray(response.get(u'cors', []), module).from_response(),
|
||||||
u'defaultEventBasedHold': response.get(u'defaultEventBasedHold'),
|
u'defaultEventBasedHold': response.get(u'defaultEventBasedHold'),
|
||||||
u'defaultObjectAcl': BucketDefaultobjectaclArray(module.params.get('default_object_acl', []), module).to_request(),
|
u'defaultObjectAcl': BucketDefaultobjectaclArray(module.params.get('default_object_acl', []), module).from_response(),
|
||||||
u'id': response.get(u'id'),
|
u'id': response.get(u'id'),
|
||||||
|
u'iamConfiguration': BucketIamconfiguration(response.get('iamConfiguration', {}), module).from_response(),
|
||||||
u'lifecycle': BucketLifecycle(response.get(u'lifecycle', {}), module).from_response(),
|
u'lifecycle': BucketLifecycle(response.get(u'lifecycle', {}), module).from_response(),
|
||||||
u'location': response.get(u'location'),
|
u'location': response.get(u'location'),
|
||||||
u'logging': BucketLogging(response.get(u'logging', {}), module).from_response(),
|
u'logging': BucketLogging(response.get(u'logging', {}), module).from_response(),
|
||||||
|
@ -1429,5 +1496,27 @@ class BucketWebsite(object):
|
||||||
return remove_nones_from_dict({u'mainPageSuffix': self.request.get(u'mainPageSuffix'), u'notFoundPage': self.request.get(u'notFoundPage')})
|
return remove_nones_from_dict({u'mainPageSuffix': self.request.get(u'mainPageSuffix'), u'notFoundPage': self.request.get(u'notFoundPage')})
|
||||||
|
|
||||||
|
|
||||||
|
class BucketIamconfiguration(object):
|
||||||
|
def __init__(self, transport, module):
|
||||||
|
self.module = module
|
||||||
|
# transport can be either the request or response objects
|
||||||
|
if transport:
|
||||||
|
self.transport = transport
|
||||||
|
else:
|
||||||
|
self.transport = {}
|
||||||
|
|
||||||
|
def to_request(self):
|
||||||
|
return remove_nones_from_dict({
|
||||||
|
u'publicAccessPrevention': self.transport.get('public_access_prevention'),
|
||||||
|
u'uniformBucketLevelAccess': self.transport.get('uniform_bucket_level_access'),
|
||||||
|
})
|
||||||
|
|
||||||
|
def from_response(self):
|
||||||
|
return remove_nones_from_dict({
|
||||||
|
u'publicAccessPrevention': self.transport.get('publicAccessPrevention'),
|
||||||
|
u'uniformBucketLevelAccess': self.transport.get('uniformBucketLevelAccess'),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
---
|
||||||
|
- name: Run test cases
|
||||||
|
block:
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
- name: Create default bucket
|
||||||
|
google.cloud.gcp_storage_bucket:
|
||||||
|
name: "{{ resource_name }}-default"
|
||||||
|
project: "{{ gcp_project }}"
|
||||||
|
auth_kind: "{{ gcp_cred_kind }}"
|
||||||
|
service_account_file: "{{ gcp_cred_file | default(omit) }}"
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert changed is true and default values are returned
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result.changed == true
|
||||||
|
- result.iamConfiguration.publicAccessPrevention == 'inherited'
|
||||||
|
- result.iamConfiguration.uniformBucketLevelAccess.enabled == false
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
- name: Create bucket with enforced PAP
|
||||||
|
google.cloud.gcp_storage_bucket:
|
||||||
|
name: "{{ resource_name }}-pap"
|
||||||
|
project: "{{ gcp_project }}"
|
||||||
|
auth_kind: "{{ gcp_cred_kind }}"
|
||||||
|
service_account_file: "{{ gcp_cred_file | default(omit) }}"
|
||||||
|
state: present
|
||||||
|
iam_configuration:
|
||||||
|
public_access_prevention: enforced
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert changed is true and IAM PAP is 'enforced'
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result.changed == true
|
||||||
|
- result.iamConfiguration.publicAccessPrevention == 'enforced'
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
- name: Create bucket with UBLA enabled
|
||||||
|
google.cloud.gcp_storage_bucket:
|
||||||
|
name: "{{ resource_name }}-ublae"
|
||||||
|
project: "{{ gcp_project }}"
|
||||||
|
auth_kind: "{{ gcp_cred_kind }}"
|
||||||
|
service_account_file: "{{ gcp_cred_file | default(omit) }}"
|
||||||
|
state: present
|
||||||
|
iam_configuration:
|
||||||
|
uniform_bucket_level_access:
|
||||||
|
enabled: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert changed is true and IAM UBLA is enabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result.changed == true
|
||||||
|
- result.iamConfiguration.uniformBucketLevelAccess.enabled == true
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
- name: Create bucket with UBLA disabled
|
||||||
|
google.cloud.gcp_storage_bucket:
|
||||||
|
name: "{{ resource_name }}-ublad"
|
||||||
|
project: "{{ gcp_project }}"
|
||||||
|
auth_kind: "{{ gcp_cred_kind }}"
|
||||||
|
service_account_file: "{{ gcp_cred_file | default(omit) }}"
|
||||||
|
state: present
|
||||||
|
iam_configuration:
|
||||||
|
uniform_bucket_level_access:
|
||||||
|
enabled: false
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert changed is true and IAM UBLA is disabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result.changed == true
|
||||||
|
- result.iamConfiguration.uniformBucketLevelAccess.enabled == false
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
always:
|
||||||
|
- name: Clean up buckets
|
||||||
|
google.cloud.gcp_storage_bucket:
|
||||||
|
name: "{{ resource_name }}-{{ item }}"
|
||||||
|
project: "{{ gcp_project }}"
|
||||||
|
auth_kind: "{{ gcp_cred_kind }}"
|
||||||
|
service_account_file: "{{ gcp_cred_file | default(omit) }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- default
|
||||||
|
- pap
|
||||||
|
- ublae
|
||||||
|
- ublad
|
|
@ -1,3 +1,6 @@
|
||||||
---
|
---
|
||||||
- name: Generated tests
|
- name: Generated tests
|
||||||
ansible.builtin.include_tasks: autogen.yml
|
ansible.builtin.include_tasks: autogen.yml
|
||||||
|
|
||||||
|
- name: Tests for IAM Configuration support
|
||||||
|
ansible.builtin.include_tasks: iam_configuration.yml
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue