diff options
author | Tom Page <tpage@redhat.com> | 2020-06-16 14:56:49 +0200 |
---|---|---|
committer | Tom Page <tpage@redhat.com> | 2020-06-16 14:56:49 +0200 |
commit | 1c78190385db53b18fd70253c246410a031e2d4f (patch) | |
tree | 23e6fe13b40257e7567513fb63a01d4b509e71b0 /awx_collection | |
parent | Add tower_credential_input_source to awx_collection (diff) | |
download | awx-1c78190385db53b18fd70253c246410a031e2d4f.tar.xz awx-1c78190385db53b18fd70253c246410a031e2d4f.zip |
Change cred_input_src to remove src_cred as primarykey
Signed-off-by: Tom Page <tpage@redhat.com>
Diffstat (limited to 'awx_collection')
4 files changed, 123 insertions, 19 deletions
diff --git a/awx_collection/plugins/module_utils/tower_api.py b/awx_collection/plugins/module_utils/tower_api.py index d836c457c0..a0b8b789ff 100644 --- a/awx_collection/plugins/module_utils/tower_api.py +++ b/awx_collection/plugins/module_utils/tower_api.py @@ -521,6 +521,9 @@ class TowerModule(AnsibleModule): elif item_type == 'o_auth2_access_token': # An oauth2 token has no name, instead we will use its id for any of the messages item_name = existing_item['id'] + elif item_type == 'credential_input_source': + # An credential_input_source has no name, instead we will use its id for any of the messages + item_name = existing_item['id'] else: self.fail_json(msg="Unable to process delete of {0} due to missing name".format(item_type)) @@ -691,6 +694,8 @@ class TowerModule(AnsibleModule): item_name = existing_item['username'] elif item_type == 'workflow_job_template_node': item_name = existing_item['identifier'] + elif item_type == 'credential_input_source': + item_name = existing_item['id'] else: item_name = existing_item['name'] item_id = existing_item['id'] diff --git a/awx_collection/plugins/modules/tower_credential_input_source.py b/awx_collection/plugins/modules/tower_credential_input_source.py index d6245911ec..ffaae2642f 100644 --- a/awx_collection/plugins/modules/tower_credential_input_source.py +++ b/awx_collection/plugins/modules/tower_credential_input_source.py @@ -1,7 +1,7 @@ #!/usr/bin/python # coding: utf-8 -*- -# Copyright: (c) 2017, Wayne Witzel III <wayne@riotousliving.com> +# Copyright: (c) 2020, Tom Page <tpage@redhat.com> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function @@ -45,7 +45,6 @@ options: source_credential: description: - The credential which is the source of the credential lookup - required: true type: str state: description: @@ -79,7 +78,7 @@ def main(): description=dict(default=''), input_field_name=dict(required=True), target_credential=dict(required=True), - source_credential=dict(required=True), + source_credential=dict(default=''), metadata=dict(type=dict), state=dict(choices=['present', 'absent'], default='present'), ) @@ -96,29 +95,25 @@ def main(): state = module.params.get('state') target_credential_id = module.resolve_name_to_id('credentials', target_credential) - source_credential_id = module.resolve_name_to_id('credentials', source_credential) - # Attempt to look up the object based on the provided name, credential type and optional organization + # Attempt to look up the object based on the target credential and input field lookup_data = { 'target_credential': target_credential_id, - 'source_credential': source_credential_id, 'input_field_name': input_field_name, } - + module.json_output['all'] = module.get_all_endpoint('credential_input_sources', **{'data': {}}) credential_input_source = module.get_one('credential_input_sources', **{'data': lookup_data}) if state == 'absent': - # If the state was absent we can let the module delete it if needed, the module will handle exiting from this - if credential_input_source: - credential_input_source['name'] = '' module.delete_if_needed(credential_input_source) # Create the data that gets sent for create and update credential_input_source_fields = { 'target_credential': target_credential_id, - 'source_credential': source_credential_id, 'input_field_name': input_field_name, } + if source_credential: + credential_input_source_fields['source_credential'] = module.resolve_name_to_id('credentials', source_credential) if metadata: credential_input_source_fields['metadata'] = metadata if description: diff --git a/awx_collection/test/awx/test_credential_input_source.py b/awx_collection/test/awx/test_credential_input_source.py index 4c5cf84e8f..7c6a46093a 100644 --- a/awx_collection/test/awx/test_credential_input_source.py +++ b/awx_collection/test/awx/test_credential_input_source.py @@ -5,13 +5,16 @@ import pytest from awx.main.models import CredentialInputSource, Credential, CredentialType, Organization - -# Test CyberArk AIM credential source @pytest.fixture -def source_cred_aim(organization): - # Make a credential type which will be used by the credential +def get_aim_cred_type(): ct=CredentialType.defaults['aim']() ct.save() + return ct + + +# Test CyberArk AIM credential source +@pytest.fixture +def source_cred_aim(ct): return Credential.objects.create( name='CyberArk AIM Cred', credential_type=ct, @@ -25,7 +28,8 @@ def source_cred_aim(organization): @pytest.mark.django_db def test_aim_credential_source(run_module, admin_user, organization, silence_deprecation): - src_cred = source_cred_aim(organization) + cred_type = get_aim_cred_type() + src_cred = source_cred_aim(cred_type) ct=CredentialType.defaults['ssh']() ct.save() tgt_cred = Credential.objects.create( @@ -266,3 +270,72 @@ def test_azure_kv_credential_source(run_module, admin_user, organization, silenc assert cis.target_credential.name == tgt_cred.name assert cis.input_field_name == 'password' assert result['id'] == cis.pk + + +# Test Changing Credential Source +@pytest.fixture +def source_cred_aim_alt(ct): + return Credential.objects.create( + name='Alternate CyberArk AIM Cred', + credential_type=ct, + inputs={ + "url": "https://cyberark-alt.example.com", + "app_id": "myAltID", + "verify": "false" + } + ) + +@pytest.mark.django_db +def test_aim_credential_source(run_module, admin_user, organization, silence_deprecation): + cred_type=get_aim_cred_type() + src_cred = source_cred_aim(cred_type) + ct=CredentialType.defaults['ssh']() + ct.save() + tgt_cred = Credential.objects.create( + name='Test Machine Credential', + organization=organization, + credential_type=ct, + inputs={'username': 'bob'} + ) + + result = run_module('tower_credential_input_source', dict( + source_credential=src_cred.name, + target_credential=tgt_cred.name, + input_field_name='password', + metadata={"object_query": "Safe=SUPERSAFE;Object=MyAccount"}, + state='present' + ), admin_user) + + assert not result.get('failed', False), result.get('msg', result) + assert result.get('changed'), result + + unchangedResult = run_module('tower_credential_input_source', dict( + source_credential=src_cred.name, + target_credential=tgt_cred.name, + input_field_name='password', + metadata={"object_query": "Safe=SUPERSAFE;Object=MyAccount"}, + state='present' + ), admin_user) + + assert not unchangedResult.get('failed', False), result.get('msg', result) + assert not unchangedResult.get('changed'), result + + src_cred_alt = source_cred_aim_alt(cred_type) + + changedResult = run_module('tower_credential_input_source', dict( + source_credential=src_cred_alt.name, + target_credential=tgt_cred.name, + input_field_name='password', + state='present' + ), admin_user) + + assert not changedResult.get('failed', False), changedResult.get('msg', result) + assert changedResult.get('changed'), result + + assert CredentialInputSource.objects.count() == 1 + cis = CredentialInputSource.objects.first() + + assert cis.metadata['object_query'] == "Safe=SUPERSAFE;Object=MyAccount" + assert cis.source_credential.name == src_cred_alt.name + assert cis.target_credential.name == tgt_cred.name + assert cis.input_field_name == 'password' diff --git a/awx_collection/tests/integration/targets/tower_credential_input_source/tasks/main.yml b/awx_collection/tests/integration/targets/tower_credential_input_source/tasks/main.yml index 9e17847818..45be47ddf7 100644 --- a/awx_collection/tests/integration/targets/tower_credential_input_source/tasks/main.yml +++ b/awx_collection/tests/integration/targets/tower_credential_input_source/tasks/main.yml @@ -47,11 +47,32 @@ that: - "result is changed" -- name: Remove a Tower credential type +- name: Add Second Tower credential Lookup + tower_credential: + description: Credential for Testing Source Change + name: "{{ src_cred_name }}-2" + credential_type: CyberArk AIM Central Credential Provider Lookup + inputs: + url: "https://cyberark-prod.example.com" + app_id: "My-App-ID" + organization: Default + register: result + +- name: Change credential Input Source + tower_credential_input_source: + input_field_name: password + target_credential: "{{ target_cred_name }}" + source_credential: "{{ src_cred_name }}-2" + state: present + +- assert: + that: + - "result is changed" + +- name: Remove a Tower credential source tower_credential_input_source: input_field_name: password target_credential: "{{ target_cred_name }}" - source_credential: "{{ src_cred_name }}" state: absent register: result @@ -63,12 +84,22 @@ tower_credential: name: "{{ src_cred_name }}" organization: Default + credential_type: CyberArk AIM Central Credential Provider Lookup state: absent register: result -- name: Remove Tower credential Lookup +- name: Remove Alt Tower credential Lookup + tower_credential: + name: "{{ src_cred_name }}-2" + organization: Default + credential_type: CyberArk AIM Central Credential Provider Lookup + state: absent + register: result + +- name: Remove Tower credential tower_credential: name: "{{ target_cred_name }}" organization: Default + credential_type: Machine state: absent register: result |