When the input parameter for tower_credentials.ply is not supplied, our expected behavior of tower_credentials would be to not change any of the input values like usernames and passwords . However, we find that any username or password previously set is wiped out and set to blank.
tower_credential should not change any existing input fields if input parameter is not supplied; i.e.: usernames and passwords previously set should not change
tower_credential is changing previously set input fields; i.e.: usernames and passwords
none
When the input parameter for tower_credentials.ply is not supplied, our expected behavior of tower_credentials would be to not change any of the input values like usernames and passwords
I'm not sure I agree. Correctly designed ansible modules are idempotent and so not providing input values to the module _could_ be construed as "put the credential into a state with no inputs (clear them)"
More importantly this probably depends on how other awx modules treat this sort of thing. @AlanCoding thoughts?
I wish to be able to change any of the non-input credential's attributes without knowing or modifying the password or other inputs. There should be a way to to keep current input values in place while updating other attributes. If you don't specify the input field leave those items alone. If you want to wipe certain one's then post a null or "" - thoughts?
I would like to code this and do a pull request
I agree with @jpell958's expectation. This is the whole not-provided vs. blank issue.
It is _extremely_ uncommon that an API parameter should have a default. Some parameters related to the _module action_ should validly have a default. These are parameters that tell the module _what to do_, such as state='present' this is a sensible default. Some API fields may be _required_ because it's hard to make sense of intent without it. However, the vast majority of API fields should be _optional_ and have _no default_.
If a field is _optional_, has _no default_, and the user does _not provide_ the field, then the Ansible core utilities give its value as None. There are some cases where None may be a valid API value, and the user may wish to set it to null where it was previously a different value. I have never heard of someone needing to do this, and I can flatly say that it is not supported.
I think the module has a bug, in that it sets inputs when no inputs are provided. See this line in preparing the update data, it will always have the inputs entry.
It should not include this data iff the inputs option is None and _all_ the legacy fields are also None.
For a silly hypothetical, say that someone is setting the description field and does not wish to set anything else.
But what if someone provides inputs: {}? That should be detectable by the module because {} is absolutely not the same thing as None.
So maybe a way to alter the existing code would be to check if (not credential_inputs) and inputs is None, and don't include the field in the payload in this case.
That's a great explanation @AlanCoding, thanks.
@AlanCoding - thanks for your excellent response.
Your statement:
"For a silly hypothetical, say that someone is setting the description field and does not wish to set anything else."
This is what I was referring too. I may wish to change the description and may not want to change the username or password [or worse I may not know the password - so how can I re-enter it]. There should be an option to skip changing any inputs. AND When creating a credential if inputs are not specified - Only then should they be set to default or NULL (empty)
The fix in PR https://github.com/ansible/awx/pull/7840 has been merged, closing this issue!
I have tested the PR #7840 and the behavior has not changed. Issuing a call to tower_credentials without inputs continues to wipe-out existing inputs (i.e. username and password)
Here is an example of my test:
- name : Create a machine credential with a username and password - no description
- tower_credential:
name: Joe_Test
credential_type: "Machine"
organization: "my_org"
inputs:
username: joe
password: secret
- name : Change just the description (username and password should be unchanged)
- tower_credential:
name: Joe_Test
credential_type: "Machine"
description: "My Credential"
organization: "my_org"
notice: no inputs - I am requesting to make no further changes to inputs (current values should remain in place but they are wiped in current PR)
Please test and let me know your findings or explain how to set the parameters so that the fields under inputs: are not replaced
Thank you
I was able to run your tasks in a playbook
---
- hosts: localhost
gather_facts: false
connection: local
collections:
- awx.awx
tasks:
- name : Create a machine credential with a username and password - no description
tower_credential:
name: Joe_Test
credential_type: "Machine"
organization: "Default"
inputs:
username: joe
password: secret
- name : Change just the description (username and password should be unchanged)
tower_credential:
name: Joe_Test
credential_type: "Machine"
description: "My Credential"
organization: "Default"
At the end of that, I find that the Joe_test credential still has the inputs. In the API:
"inputs": {
"password": "$encrypted$",
"username": "joe"
},
It looks like that example is working to me.
@AlanCoding - I figured out what was happening on my end. The controller I was using to target my AWX 14.0 environment was running collections version 13.0. I move over to the machine that had collections 14.0 installed and it worked as you noted - Thank you for the reply and the verification script. I am good to go now.
Thank you @beeankha for fixing this!