diff --git a/awx_collection/plugins/module_utils/tower_api.py b/awx_collection/plugins/module_utils/tower_api.py index a7bbc93857..b7145e15f4 100644 --- a/awx_collection/plugins/module_utils/tower_api.py +++ b/awx_collection/plugins/module_utils/tower_api.py @@ -574,30 +574,6 @@ class TowerModule(AnsibleModule): else: self.exit_json(**self.json_output) - # We need to be able to recursevly step through fields in the case of inputs for credentials. - # They are dicts and we can't just compare them at the top level because the dict from the tower api may have more fields that we have. - # For example, say someone did: - # - tower_credential: - # name: 'a cred' - # username: 'John' - # Our new dict would be like { 'username': 'new_name' } - # But the existing cred from tower might come back as: { 'username': 'new_name', 'password': '$encrypted$', 'field2': 'something else' } - @staticmethod - def compare_fields(new_item, existing_item): - needs_update = False - for field in new_item: - existing_field = existing_item.get(field, None) - new_field = new_item.get(field, None) - if type(existing_field) == dict and type(new_field) == dict: - needs_update = needs_update or TowerModule.compare_fields(new_field, existing_field) - # If the two items don't match and we are not comparing '' to None - # In the case of extra_vars in a job template, we have to pass in {} for nothing ('' is not valid) - # But when its returned from the API, instead of {} we get back ''. - elif existing_field != new_field and not (existing_field in (None, '') and new_field in ('', {})): - # Something doesn't match so let's update it - needs_update = True - return needs_update - def update_if_needed(self, existing_item, new_item, on_update=None, associations=None): # This will exit from the module on its own # If the method successfully updates an item and on_update param is defined, @@ -625,7 +601,15 @@ class TowerModule(AnsibleModule): self.fail_json(msg="Unable to process update of item due to missing data {0}".format(ke)) # Check to see if anything within the item requires the item to be updated - needs_update = TowerModule.compare_fields(new_item, existing_item) + needs_update = False + for field in new_item: + existing_field = existing_item.get(field, None) + new_field = new_item.get(field, None) + # If the two items don't match and we are not comparing '' to None + if existing_field != new_field and not (existing_field in (None, '') and new_field == ''): + # Something doesn't match so let's update it + needs_update = True + break # If we decided the item needs to be updated, update it self.json_output['id'] = item_id diff --git a/awx_collection/plugins/modules/tower_credential.py b/awx_collection/plugins/modules/tower_credential.py index 1cdc222de8..c57efc87d8 100644 --- a/awx_collection/plugins/modules/tower_credential.py +++ b/awx_collection/plugins/modules/tower_credential.py @@ -194,7 +194,12 @@ options: required: False type: str version_added: "3.7" + extends_documentation_fragment: awx.awx.auth + +notes: + - Values `inputs` and the other deprecated fields (such as `tenant`) are replacements of existing values. + See the last 4 examples for details. ''' @@ -224,6 +229,7 @@ EXAMPLES = ''' slurp: src: '$HOME/.ssh/aws-private.pem' register: aws_ssh_key + - name: Add Credential Into Tower tower_credential: name: Workshop Credential @@ -242,6 +248,40 @@ EXAMPLES = ''' tower_username: admin tower_password: ansible tower_host: https://localhost + +- name: Create a Vaiult credential (example for notes) + tower_credential: + name: Example password + credential_type: Vault + organization: Default + inputs: + vault_password: 'hello' + vault_id: 'My ID' + +- name: Bad password update (will replace vault_id) + tower_credential: + name: Example password + credential_type: Vault + organization: Default + inputs: + vault_password: 'new_password' + +- name: Another bad password update (will replace vault_id) + tower_credential: + name: Example password + credential_type: Vault + organization: Default + vault_password: 'new_password' + +- name: A safe way to update a password and keep vault_id + tower_credential: + name: Example password + credential_type: Vault + organization: Default + inputs: + vault_password: 'new_password' + vault_id: 'My ID' + ''' from ..module_utils.tower_api import TowerModule diff --git a/awx_collection/tests/integration/targets/tower_credential/tasks/main.yml b/awx_collection/tests/integration/targets/tower_credential/tasks/main.yml index b7e7172eba..55d98396b5 100644 --- a/awx_collection/tests/integration/targets/tower_credential/tasks/main.yml +++ b/awx_collection/tests/integration/targets/tower_credential/tasks/main.yml @@ -177,7 +177,7 @@ that: - result is changed -- name: Create a valid SSH credential (new school) (no change) +- name: Create a valid SSH credential (new school) tower_credential: name: "{{ ssh_cred_name2 }}" organization: Default @@ -193,7 +193,7 @@ # This should no longer be changed because we aren't passing any secure fields - assert: that: - - result is not changed + - result is changed - name: Create a valid SSH credential from lookup source (old school) tower_credential: