diff --git a/plugins/modules/aci_snmp_user.py b/plugins/modules/aci_snmp_user.py index 49a9f5ae5..9e9b6d852 100644 --- a/plugins/modules/aci_snmp_user.py +++ b/plugins/modules/aci_snmp_user.py @@ -1,6 +1,8 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2021, Tim Cragg (@timcragg) +# Copyright: (c) 2023, Akini Ross (@akinross) # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function @@ -21,7 +23,7 @@ description: - SNMP authentication method type: str - choices: [ hmac-md5-96, hmac-sha1-96] + choices: [ hmac-md5-96, hmac-sha1-96, hmac-sha2-224, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512 ] auth_key: description: - SNMP authentication key @@ -31,6 +33,11 @@ - Name of the SNMP user policy type: str aliases: [ snmp_user_policy ] + description: + description: + - Description of the SNMP user policy + type: str + aliases: [ descr ] policy: description: - Name of an existing SNMP policy @@ -56,12 +63,17 @@ - cisco.aci.aci - cisco.aci.annotation +notes: +- The C(policy) used must exist before using this module in your playbook. + The M(cisco.aci.aci_snmp_policy) module can be used for this. seealso: +- module: cisco.aci.aci_snmp_policy - name: APIC Management Information Model reference description: More information about the internal APIC class B(snmp:UserP). link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Tim Cragg (@timcragg) +- Akini Ross (@akinross) """ EXAMPLES = r""" @@ -72,7 +84,7 @@ password: SomeSecretPassword policy: my_snmp_policy name: my_snmp_user - auth_type: hmac-sha1-96 + auth_type: hmac-sha2-256 auth_key: "{{ hmac_key }}" state: present delegate_to: localhost @@ -238,7 +250,8 @@ def main(): argument_spec.update( policy=dict(type="str", aliases=["snmp_policy", "snmp_policy_name"]), name=dict(type="str", aliases=["snmp_user_policy"]), - auth_type=dict(type="str", choices=["hmac-md5-96", "hmac-sha1-96"]), + description=dict(type="str", aliases=["descr"]), + auth_type=dict(type="str", choices=["hmac-md5-96", "hmac-sha1-96", "hmac-sha2-224", "hmac-sha2-256", "hmac-sha2-384", "hmac-sha2-512"]), auth_key=dict(type="str", no_log=True), privacy_type=dict(type="str", choices=["aes-128", "des", "none"]), privacy_key=dict(type="str", no_log=True), @@ -258,6 +271,7 @@ def main(): policy = module.params.get("policy") name = module.params.get("name") + description = module.params.get("description") auth_type = module.params.get("auth_type") auth_key = module.params.get("auth_key") privacy_type = module.params.get("privacy_type") @@ -284,7 +298,7 @@ def main(): if state == "present": aci.payload( aci_class="snmpUserP", - class_config=dict(privType=privacy_type, privKey=privacy_key, authType=auth_type, authKey=auth_key, name=name), + class_config=dict(privType=privacy_type, privKey=privacy_key, authType=auth_type, authKey=auth_key, name=name, descr=description), ) aci.get_diff(aci_class="snmpUserP") diff --git a/tests/integration/targets/aci_snmp_user/tasks/main.yml b/tests/integration/targets/aci_snmp_user/tasks/main.yml index 1b2608189..aabfd4c67 100644 --- a/tests/integration/targets/aci_snmp_user/tasks/main.yml +++ b/tests/integration/targets/aci_snmp_user/tasks/main.yml @@ -1,16 +1,16 @@ # Test code for the ACI modules # Copyright: (c) 2021, Tim Cragg (@timcragg) +# Copyright: (c) 2023, Akini Ross (@akinross) # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - name: Test that we have an ACI APIC host, ACI username and ACI password - fail: + ansible.builtin.fail: msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined -# GET Credentials from the inventory - name: Set vars - set_fact: + ansible.builtin.set_fact: aci_info: &aci_info host: "{{ aci_hostname }}" username: "{{ aci_username }}" @@ -18,26 +18,25 @@ validate_certs: '{{ aci_validate_certs | default(false) }}' use_ssl: '{{ aci_use_ssl | default(true) }}' use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug + output_level: '{{ aci_output_level | default("info") }}' # CLEAN ENVIRONMENT - name: Remove ansible_snmp_policy if it already exists - aci_snmp_policy: + cisco.aci.aci_snmp_policy: <<: *aci_info name: ansible_snmp_policy state: absent -# ADD snmp policy -- name: Add snmp policy - aci_snmp_policy: +# CREATE SNMP USER +- name: Create snmp policy + cisco.aci.aci_snmp_policy: <<: *aci_info name: ansible_snmp_policy admin_state: enabled state: present -# ADD snmp user -- name: Add snmp user - aci_snmp_user: +- name: Create a snmp user (checkmode) + cisco.aci.aci_snmp_user: &snmp_user <<: *aci_info policy: ansible_snmp_policy name: ansible_snmp_user @@ -46,66 +45,223 @@ privacy_type: aes-128 privacy_key: "priv-test-key" state: present - register: add_snmp_user + register: cm_create_snmp_user + check_mode: true -- name: Verify that ansible_snmp_community has been created with correct attributes - assert: +- name: Create a snmp user + cisco.aci.aci_snmp_user: + <<: *snmp_user + register: nm_create_snmp_user + +- name: Create a snmp user again without secrets + cisco.aci.aci_snmp_user: + <<: *snmp_user + auth_key: "{{ fake_var | default(omit) }}" + privacy_key: "{{ fake_var | default(omit) }}" + register: nm_create_snmp_user_again + +- name: Verify create of ansible_snmp_user + ansible.builtin.assert: + that: + - cm_create_snmp_user is changed + - cm_create_snmp_user.proposed.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - cm_create_snmp_user.proposed.snmpUserP.attributes.name == "ansible_snmp_user" + - cm_create_snmp_user.proposed.snmpUserP.attributes.authType == "hmac-sha1-96" + - cm_create_snmp_user.proposed.snmpUserP.attributes.privType == "aes-128" + - cm_create_snmp_user.proposed.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - cm_create_snmp_user.previous == [] + - nm_create_snmp_user is changed + - nm_create_snmp_user.current.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_create_snmp_user.current.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_create_snmp_user.current.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_create_snmp_user.current.0.snmpUserP.attributes.privType == "aes-128" + - nm_create_snmp_user.current.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_create_snmp_user.current.0.snmpUserP.attributes.descr == "" + - nm_create_snmp_user.previous == [] + - nm_create_snmp_user_again is not changed + - nm_create_snmp_user_again.previous.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_create_snmp_user_again.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_create_snmp_user_again.previous.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_create_snmp_user_again.previous.0.snmpUserP.attributes.privType == "aes-128" + - nm_create_snmp_user_again.previous.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_create_snmp_user_again.previous.0.snmpUserP.attributes.descr == "" + - nm_create_snmp_user_again.current.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_create_snmp_user_again.current.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_create_snmp_user_again.current.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_create_snmp_user_again.current.0.snmpUserP.attributes.privType == "aes-128" + - nm_create_snmp_user_again.current.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_create_snmp_user_again.current.0.snmpUserP.attributes.descr == "" + +# CHANGE SNMP USER +- name: Change a snmp user (checkmode) + cisco.aci.aci_snmp_user: &snmp_user_changed + <<: *snmp_user + descr: description_change + register: cm_change_snmp_user + check_mode: true + +- name: Change a snmp user + cisco.aci.aci_snmp_user: + <<: *snmp_user_changed + register: nm_change_snmp_user + +- name: Change a snmp user again without secrets + cisco.aci.aci_snmp_user: + <<: *snmp_user_changed + auth_key: "{{ fake_var | default(omit) }}" + privacy_key: "{{ fake_var | default(omit) }}" + register: nm_change_snmp_user_again + +- name: Verify change of ansible_snmp_user + ansible.builtin.assert: that: - - add_snmp_user.current.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" - - add_snmp_user.current.0.snmpUserP.attributes.name == "ansible_snmp_user" - - add_snmp_user.current.0.snmpUserP.attributes.authType == "hmac-sha1-96" - - add_snmp_user.current.0.snmpUserP.attributes.privType == "aes-128" - - add_snmp_user.current.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' - -# QUERY snmp user -- name: Query snmp user - aci_snmp_user: + - cm_change_snmp_user is changed + - cm_change_snmp_user.previous.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - cm_change_snmp_user.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - cm_change_snmp_user.previous.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - cm_change_snmp_user.previous.0.snmpUserP.attributes.privType == "aes-128" + - cm_change_snmp_user.previous.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - cm_change_snmp_user.previous.0.snmpUserP.attributes.descr == "" + - cm_change_snmp_user.proposed.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - cm_change_snmp_user.proposed.snmpUserP.attributes.name == "ansible_snmp_user" + - cm_change_snmp_user.proposed.snmpUserP.attributes.authType == "hmac-sha1-96" + - cm_change_snmp_user.proposed.snmpUserP.attributes.privType == "aes-128" + - cm_change_snmp_user.proposed.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - cm_change_snmp_user.proposed.snmpUserP.attributes.descr == "description_change" + - nm_change_snmp_user is changed + - nm_change_snmp_user.previous.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_change_snmp_user.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_change_snmp_user.previous.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_change_snmp_user.previous.0.snmpUserP.attributes.privType == "aes-128" + - nm_change_snmp_user.previous.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_change_snmp_user.previous.0.snmpUserP.attributes.descr == "" + - nm_change_snmp_user.current.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_change_snmp_user.current.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_change_snmp_user.current.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_change_snmp_user.current.0.snmpUserP.attributes.privType == "aes-128" + - nm_change_snmp_user.current.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_change_snmp_user.current.0.snmpUserP.attributes.descr == "description_change" + - nm_change_snmp_user_again is not changed + - nm_change_snmp_user_again.previous.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_change_snmp_user_again.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_change_snmp_user_again.previous.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_change_snmp_user_again.previous.0.snmpUserP.attributes.privType == "aes-128" + - nm_change_snmp_user_again.previous.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_change_snmp_user_again.previous.0.snmpUserP.attributes.descr == "description_change" + - nm_change_snmp_user_again.current.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" + - nm_change_snmp_user_again.current.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_change_snmp_user_again.current.0.snmpUserP.attributes.authType == "hmac-sha1-96" + - nm_change_snmp_user_again.current.0.snmpUserP.attributes.privType == "aes-128" + - nm_change_snmp_user_again.current.0.snmpUserP.attributes.annotation == 'orchestrator:ansible' + - nm_change_snmp_user_again.current.0.snmpUserP.attributes.descr == "description_change" + +# QUERY SNMP USER +- name: Create another snmp user with auth_type hmac-sha2-224 + cisco.aci.aci_snmp_user: + <<: *snmp_user + name: ansible_snmp_user_2 + auth_type: hmac-sha2-224 + register: nm_create_snmp_user_2 + +- name: Create another snmp user with auth_type hmac-sha2-256 + cisco.aci.aci_snmp_user: + <<: *snmp_user + name: ansible_snmp_user_3 + auth_type: hmac-sha2-256 + register: nm_create_snmp_user_3 + +- name: Create another snmp user with auth_type hmac-sha2-384 + cisco.aci.aci_snmp_user: + <<: *snmp_user + name: ansible_snmp_user_4 + auth_type: hmac-sha2-384 + register: nm_create_snmp_user_4 + +- name: Create another snmp user with auth_type hmac-sha2-512 + cisco.aci.aci_snmp_user: + <<: *snmp_user + name: ansible_snmp_user_5 + auth_type: hmac-sha2-512 + register: nm_create_snmp_user_5 + +- name: Verify change of ansible_snmp_user + ansible.builtin.assert: + that: + - nm_create_snmp_user_2 is changed + - nm_create_snmp_user_2.current.0.snmpUserP.attributes.authType == "hmac-sha2-224" + - nm_create_snmp_user_3 is changed + - nm_create_snmp_user_3.current.0.snmpUserP.attributes.authType == "hmac-sha2-256" + - nm_create_snmp_user_4 is changed + - nm_create_snmp_user_4.current.0.snmpUserP.attributes.authType == "hmac-sha2-384" + - nm_create_snmp_user_5 is changed + - nm_create_snmp_user_5.current.0.snmpUserP.attributes.authType == "hmac-sha2-512" + +- name: Query ansible_snmp_user + cisco.aci.aci_snmp_user: <<: *aci_info policy: ansible_snmp_policy name: ansible_snmp_user state: query register: query_snmp_user -- name: Verify the attributes under query_snmp_client_group - assert: +- name: Verify query of ansible_snmp_user + ansible.builtin.assert: that: - query_snmp_user is not changed + - query_snmp_user.current | length == 1 - query_snmp_user.current.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" - query_snmp_user.current.0.snmpUserP.attributes.name == "ansible_snmp_user" - query_snmp_user.current.0.snmpUserP.attributes.authType == "hmac-sha1-96" - query_snmp_user.current.0.snmpUserP.attributes.privType == "aes-128" -- name: Query all snmp communities - aci_snmp_user: +- name: Query all snmp users + cisco.aci.aci_snmp_user: <<: *aci_info state: query register: query_snmp_user_all -- name: Verify query_snmp_user_all - assert: +- name: Verify query of all snmp users + ansible.builtin.assert: that: - query_snmp_user_all is not changed + - query_snmp_user_all.current | length >= 5 -# DELETE snmp user -- name: Remove the snmp user - aci_snmp_user: +# REMOVE SNMP USER +- name: Remove the snmp user (checkmode) + cisco.aci.aci_snmp_user: &snmp_user_remove <<: *aci_info policy: ansible_snmp_policy name: ansible_snmp_user state: absent - register: remove_snmp_user + register: cm_remove_snmp_user + check_mode: true + +- name: Remove the snmp user + cisco.aci.aci_snmp_user: + <<: *snmp_user_remove + register: nm_remove_snmp_user + +- name: Remove the snmp user again + cisco.aci.aci_snmp_user: + <<: *snmp_user_remove + register: nm_remove_snmp_user_again - name: Verify remove_snmp_user - assert: + ansible.builtin.assert: that: - - remove_snmp_user is changed - - remove_snmp_user.current == [] - - remove_snmp_user.previous.0.snmpUserP.attributes.dn == "uni/fabric/snmppol-ansible_snmp_policy/user-ansible_snmp_user" - - remove_snmp_user.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - cm_remove_snmp_user is changed + - cm_remove_snmp_user.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - cm_remove_snmp_user.proposed == {} + - nm_remove_snmp_user is changed + - nm_remove_snmp_user.current == [] + - nm_remove_snmp_user.previous.0.snmpUserP.attributes.name == "ansible_snmp_user" + - nm_remove_snmp_user_again is not changed + - nm_remove_snmp_user_again.current == [] + - nm_remove_snmp_user_again.previous == [] -# DELETE snmp policy +# CLEAN ENVIRONMENT - name: Remove the snmp policy - aci_snmp_policy: + cisco.aci.aci_snmp_policy: <<: *aci_info name: ansible_snmp_policy state: absent