diff --git a/awx_collection/plugins/modules/credential.py b/awx_collection/plugins/modules/credential.py index 4e7f02e558..2f037f68dc 100644 --- a/awx_collection/plugins/modules/credential.py +++ b/awx_collection/plugins/modules/credential.py @@ -87,7 +87,7 @@ options: update_secrets: description: - C(true) will always update encrypted values. - - C(false) will only updated encrypted values if a change is absolutely known to be needed. + - C(false) will only update encrypted values if a change is absolutely known to be needed. type: bool default: true user: @@ -100,8 +100,8 @@ options: type: str state: description: - - Desired state of the resource. - choices: ["present", "absent"] + - Desired state of the resource. C(exists) will not modify the resource if it is present. + choices: ["present", "absent", "exists"] default: "present" type: str @@ -216,7 +216,7 @@ def main(): update_secrets=dict(type='bool', default=True, no_log=False), user=dict(), team=dict(), - state=dict(choices=['present', 'absent'], default='present'), + state=dict(choices=['present', 'absent', 'exists'], default='present'), ) # Create a module for ourselves @@ -265,6 +265,10 @@ def main(): # If the state was absent we can let the module delete it if needed, the module will handle exiting from this module.delete_if_needed(credential) + if state == 'exists' and credential is not None: + # If credential exists and state is exists, we're done here. + module.exit_json(**module.json_output) + # Attempt to look up the related items the user specified (these will fail the module if not found) if user: user_id = module.resolve_name_to_id('users', user) diff --git a/awx_collection/test/awx/test_credential.py b/awx_collection/test/awx/test_credential.py index f12594bee8..c67953197e 100644 --- a/awx_collection/test/awx/test_credential.py +++ b/awx_collection/test/awx/test_credential.py @@ -132,3 +132,20 @@ def test_secret_field_write_twice(run_module, organization, admin_user, cred_typ else: assert result.get('changed') is False, result assert Credential.objects.get(id=result['id']).get_input('token') == val1 + + +@pytest.mark.django_db +@pytest.mark.parametrize('state', ('present', 'absent', 'exists')) +def test_credential_state(run_module, organization, admin_user, cred_type, state): + result = run_module( + 'credential', + dict( + name='Galaxy Token for Steve', + organization=organization.name, + credential_type=cred_type.name, + inputs={'token': '7rEZK38DJl58A7RxA6EC7lLvUHbBQ1'}, + state=state, + ), + admin_user, + ) + assert not result.get('failed', False), result.get('msg', result) diff --git a/awx_collection/tests/integration/targets/credential/tasks/main.yml b/awx_collection/tests/integration/targets/credential/tasks/main.yml index 57b2168f25..42d22d8bc7 100644 --- a/awx_collection/tests/integration/targets/credential/tasks/main.yml +++ b/awx_collection/tests/integration/targets/credential/tasks/main.yml @@ -178,6 +178,60 @@ that: - result is changed +- name: Delete an SSH credential + credential: + name: "{{ ssh_cred_name2 }}" + organization: Default + state: absent + credential_type: Machine + register: result + +- assert: + that: + - "result is changed" + +- name: Ensure existence of SSH credential + credential: + name: "{{ ssh_cred_name2 }}" + organization: Default + state: exists + credential_type: Machine + description: An example SSH awx.awx.credential + inputs: + username: joe + password: secret + become_method: sudo + become_username: superuser + become_password: supersecret + ssh_key_data: "{{ ssh_key_data }}" + ssh_key_unlock: "passphrase" + register: result + +- assert: + that: + - result is changed + +- name: Ensure existence of SSH credential, not updating any inputs + credential: + name: "{{ ssh_cred_name2 }}" + organization: Default + state: exists + credential_type: Machine + description: An example SSH awx.awx.credential + inputs: + username: joe + password: no-update-secret + become_method: sudo + become_username: some-other-superuser + become_password: some-other-secret + ssh_key_data: "{{ ssh_key_data }}" + ssh_key_unlock: "another-pass-phrase" + register: result + +- assert: + that: + - result is not changed + - name: Create an invalid SSH credential (passphrase required) credential: name: SSH Credential