Closed aj-cruz closed 10 months ago
Hi @aj-cruz,
I just tried to recreate your issue on 5.2(7f) APIC and do not have this double prepend of hmac- error. Also in our tests that all pass we run the code on 4.2(7s), Version 5.2(7g), and Version 6.0(2h). Could you provide some more verbose logging?
@akinross Sorry I'm not sure what happened, but it's working now. I've since re-factored my playbook to use listify instead of nested loops and in doing that pulled and re-built the collection from source. Sorry to waste your time on that, thanks for checking.
Actually, I might still have a problem with it though might be a different problem. Now the task is posting but has an idempotency problem. Lemme do some digging and get back...
Confirmed the task shows a change every time I run the playbook. Here's my task:
- name: Add SNMPv3 Users to SNMP Policies
cisco.aci.aci_snmp_user:
<<: *apic_login
state: present
policy: MySNMP_Pol
name: snmpuser1
auth_type: hmac-sha2-512
auth_key: keykeykey
privacy_type: aes-128
privacy_key: keykeykey
delegate_to: localhost
If I do it via aci_rest it doesn't show a change after the first run:
- name: Add SNMPv3 Users to SNMP Policies
cisco.aci.aci_rest:
<<: *apic_login
path: /api/node/mo/uni/fabric/snmppol-MySNMP_Pol/user-snmpuser1.json
method: post
content:
snmpUserP:
attributes:
dn: "uni/fabric/snmppol-MySNMP_Pol/user-snmpuser1"
name: snmpuser1
privType: aes-128
privKey: keykeykey
authType: hmac-sha2-512
authKey: keykeykey
rn: user-snmpuser1
status: created,modified
delegate_to: localhost
Here's the verbose output of the task:
TASK [apic_fabric_policies : Add SNMPv3 Users to SNMP Policies] *******************************************************************************************
task path: /home/aj/projects/ansible-labs/basic-apic/roles/apic_fabric_policies/tasks/policies_pod.yml:191
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: aj
<localhost> EXEC /bin/sh -c 'echo ~aj && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/aj/.ansible/tmp `"&& mkdir "` echo /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905 `" && echo ansible-tmp-1704728257.8934727-13878-119087577592905="` echo /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905 `" ) && sleep 0'
Using module file /home/aj/.ansible/collections/ansible_collections/cisco/aci/plugins/modules/aci_snmp_user.py
<localhost> PUT /home/aj/.ansible/tmp/ansible-local-13845i6_wmd7y/tmp0yis534b TO /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905/AnsiballZ_aci_snmp_user.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905/ /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905/AnsiballZ_aci_snmp_user.py && sleep 0'
<localhost> EXEC /bin/sh -c '/home/aj/.pyenv/versions/3.11.4/envs/ansible-aci/bin/python3.11 /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905/AnsiballZ_aci_snmp_user.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/aj/.ansible/tmp/ansible-tmp-1704728257.8934727-13878-119087577592905/ > /dev/null 2>&1 && sleep 0'
changed: [APIC1 -> localhost] => {
"changed": true,
"current": [
{
"snmpUserP": {
"attributes": {
"annotation": "orchestrator:ansible",
"authType": "hmac-sha2-512",
"descr": "",
"dn": "uni/fabric/snmppol-MySNMP_Pol/user-snmpuser1",
"name": "snmpuser1",
"nameAlias": "",
"privType": "aes-128",
"userdom": ":all:"
}
}
}
],
"invocation": {
"module_args": {
"annotation": "orchestrator:ansible",
"auth_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"auth_type": "hmac-sha2-512",
"certificate_name": null,
"description": null,
"host": "192.168.253.2",
"name": "snmpuser1",
"output_level": "normal",
"output_path": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"policy": "MySNMP_Pol",
"port": null,
"privacy_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"privacy_type": "aes-128",
"private_key": null,
"protocol": "https",
"state": "present",
"timeout": null,
"use_proxy": false,
"use_ssl": null,
"username": "admin",
"validate_certs": false
}
},
"mo": {
"snmpUserP": {
"attributes": {
"annotation": "orchestrator:ansible",
"authKey": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"authType": "hmac-sha2-512",
"dn": "uni/fabric/snmppol-MySNMP_Pol/user-snmpuser1",
"name": "snmpuser1",
"privKey": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"privType": "aes-128"
}
}
}
}
PLAY RECAP ************************************************************************************************************************************************
APIC1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Hi @aj-cruz,
Currently this is expected behaviour due to this class having protected properties (auth_key and privacy_key) that are not being returned in the GET request. Let me explain a bit more the difference in implementation for regular modules versus the aci_rest module.
All regular modules should work with the following steps for configuration applies (state=present
):
For the aci_rest module these steps for configuration applies (method=post
) are:
?rsp-subtree=modified
to the path when method is not a GET operation.?rsp-subtree=modified
is appended to url, because imdata in response can then be non-empty list)As you can see there are a few differences:
?rsp-subtree=modified
in the aci_rest moduleGetting back to the issue as to why the aci_snmp_user is not idempotent. This is because of the payload construction in step 4. When the configuration difference is constructed with the GET response and the user provided arguments in the module, there will always be a difference because of the protected properties (auth_key
and privacy_key
) which are not returned in the GET response. So with every execution of the task with state=present
the module will execute a POST operation and thus the changed output is always set to true.
The aci_rest module on the other hand, will execute the POST request but depending on the rsp_subtree_preserve=false
and can have a response with imdata list containing the modified attributes. Depending on this response changed value will reflected in the output.
I can have a discussion in our team to see if this is something that we could adjust.
@akinross Thanks for the explanation, I appreciate it.
Community Note
Description
Affected Module Name(s):
APIC version and APIC Platform
Collection versions
Output/ Error message
failed: [APIC1 -> localhost] (item=User 'snmpuser' for SNMP Policy 'MySNMP_Pol') => {"ansible_loop_var": "item", "changed": false, "error": {"code": "120", "text": "unknown property value hmac-hmac-sha2-512, name authType, class snmpUserP [(Dn0)] Dn0=uni/fabric/snmppol-MySNMP_Pol/user-snmpuser, "}, "item": [{"administratively_enabled": true, "client_group_profiles": [{"client_entries": [{"address": "10.9.9.1", "name": "SolarWinds1"}, {"address": "10.9.9.2", "name": "SolarWinds2"}], "description": "A Client Group Description", "management_epg": "default", "name": "MyClientGroup"}], "community_policies": [{"community": "mysnmpcommunity", "description": "Some Description"}, {"community": "mysnmpcommunitytoo", "description": "Some Other Description"}], "description": "POD1 SNMP Policy", "name": "MySNMP_Pol", "snmp_contact": "AJ Cruz (aj.cruz@adomain.com)", "snmp_location": "Kerrville, TX", "trap_forward_servers": [{"address": "10.9.9.1", "port": 162}, {"address": "10.9.9.2", "port": 162}]}, {"authorization_key": "keykeykey", "authorization_type": "hmac-sha2-512", "enable_aes_128_privacy": true, "privacy_key": "keykeykey", "user": "snmpuser"}], "msg": "APIC Error 120: unknown property value hmac-hmac-sha2-512, name authType, class snmpUserP [(Dn0)] Dn0=uni/fabric/snmppol-MySNMP_Pol/user-snmpuser, ", "status": -1}
Expected Behavior
*Payload posts with Auth Type property value:
hmac-sha2-512
Actual Behavior
*Payload posts with Auth Type property value:
hmac-hmac-sha2-512
Playbook tasks to Reproduce
Important Factoids
References
494
496