Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
minor_changes:
- gcp_secret_manager - added new function check_secret_exists to properly determine if a secret exists in GCP Secret Manager
- gcp_secret_manager - added ability to create a secret without an initial value by splitting the create_secret function into two separate functions - create_secret_with_value and create_secret_without_value
- gcp_secret_manager - improved logic for handling existence of secrets and their versions to better support empty secrets
64 changes: 49 additions & 15 deletions plugins/modules/gcp_secret_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,30 @@
return z


# create secret is a create call + an add version call
def create_secret(module):
def check_secret_exists(module):
url = (make_url_prefix(module) + "secrets/{name}").format(**module.params)
auth = get_auth(module)
response = auth.get(url)
return response.status_code == 200


# Create a secret without an initial value
def create_secret_without_value(module):
payload = {"replication": {"automatic": {}}}
if module.params['location']:
payload = dict()

Check warning on line 385 in plugins/modules/gcp_secret_manager.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this constructor call with a literal.

See more on https://sonarcloud.io/project/issues?id=ansible-collections_google.cloud&issues=AZ53ab8S5WQG7-EhqP_2&open=AZ53ab8S5WQG7-EhqP_2&pullRequest=706
if module.params['labels']:
payload['labels'] = module.params['labels']

url = (make_url_prefix(module) + "secrets").format(**module.params)
auth = get_auth(module)
post_response = auth.post(url, body=payload, params={'secretId': module.params['name']})
module.raise_for_status(post_response)
return {"msg": "Secret '{name}' created without a value".format(**module.params)}


# Create a secret AND its first version
def create_secret_with_value(module):
# build the payload
payload = {"replication": {"automatic": {}}}
if module.params['location']:
Expand Down Expand Up @@ -489,27 +511,39 @@
module.params['calc_version'] = module.params['version']

state = module.params['state']
secret_exists = check_secret_exists(module)
fetch = fetch_resource(module, allow_not_found=True)
changed = False

# nothing came back, so the secret doesn't exist
if not fetch:
# doesn't exist, must create
if module.params.get('value') and state == 'present':
# create a new secret
fetch = create_secret(module)
changed = True
# specified present but no value
# fail, let the user know
# that no secret could be created without a value to encrypt
elif state == 'present':
module.fail_json(msg="secret '{name}' not present in '{project}' and no value for the secret is provided".format(**module.params))

# secret is absent, success
# Logic to handle a secret that does NOT exist
# Create the secret AND its first version with a value or Create the secret but without a value (empty secret)
if not secret_exists:
if state == 'present':
if module.params.get('value'):
fetch = create_secret_with_value(module)
changed = True
else:
fetch = create_secret_without_value(module)
changed = True
else:
# state is 'absent'
# secret doesn't exist, so no changes needed
fetch = {"msg": "secret '{name}' in project '{project}' not present".format(**module.params)}

else:
if state == 'present':
# Handle cases where the secret exists but has no versions
if not fetch and module.params.get('value'):
fetch = update_secret(module)
changed = True
# Handle updates to a secret with existing versions
elif fetch and "value" in fetch and module.params.get('value') is not None:
if fetch['value'] != module.params['value']:
update_secret(module)
changed = True
else:
fetch['msg'] = "values identical, no need to update secret"
# delete the secret version (latest if no version is specified)
if state == "absent":
# delete the secret
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,24 @@
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
# ----------------------------------------------------------
- name: Create a regional secret
- name: Create an empty regional secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
labels:
key1: "val1"
key2: "val2"
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
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Create a regional secret with a value
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
- name: Create a regional secret
- name: Create a regional secret with a value
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
location: "us-central1"
Expand Down
52 changes: 49 additions & 3 deletions tests/integration/targets/gcp_secret_manager/tasks/secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,53 @@
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
# ----------------------------------------------------------
- name: Create a secret
- name: Create an empty secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
labels:
key1: "val1"
key2: "val2"
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
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Create an empty secret that already exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
labels:
key1: "val1"
key2: "val2"
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
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Delete an empty secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Create a secret with a value
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value"
Expand All @@ -39,7 +85,7 @@
that:
- result.changed == true
# ----------------------------------------------------------
- name: Create a secret that already exists
- name: Create a secret with a value that already exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value"
Expand All @@ -53,7 +99,7 @@
that:
- result.changed == false
# ----------------------------------------------------------
- name: Add a new version to a secret
- name: Add a new version to an empty secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value-updated"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
- name: Create a secret
- name: Create a secret with a value
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
value: "ansible lookup test secret value"
Expand Down