From bb2924f82cd6387ac6348abfc0921d67f696bbe8 Mon Sep 17 00:00:00 2001 From: anvitha-jain Date: Mon, 9 Oct 2023 06:24:19 -0700 Subject: [PATCH] [minor_changes] Added BFD Multihop Interface policy (bfdMhIfPol) class. --- .../aci_bfd_multihop_interface_policy.py | 312 ++++++++++++++++++ .../aci_bfd_multihop_interface_policy/aliases | 2 + .../tasks/main.yml | 181 ++++++++++ 3 files changed, 495 insertions(+) create mode 100644 plugins/modules/aci_bfd_multihop_interface_policy.py create mode 100644 tests/integration/targets/aci_bfd_multihop_interface_policy/aliases create mode 100644 tests/integration/targets/aci_bfd_multihop_interface_policy/tasks/main.yml diff --git a/plugins/modules/aci_bfd_multihop_interface_policy.py b/plugins/modules/aci_bfd_multihop_interface_policy.py new file mode 100644 index 000000000..2f4a36840 --- /dev/null +++ b/plugins/modules/aci_bfd_multihop_interface_policy.py @@ -0,0 +1,312 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2023, Anvitha Jain (@anvjain) +# 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 + +__metaclass__ = type + +ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} + +DOCUMENTATION = r""" +--- +module: aci_bfd_multihop_interface_policy +short_description: Manage BFD Multihop Interface policies. +description: +- Manage BFD Multihop Interface policy (bfdMhIfPol) configuration on Cisco ACI fabrics. +- Only availavle in APIC version 5.2 or later. +options: + tenant: + description: + - Name of an existing tenant. + type: str + name: + description: + - Name of the BFD Multihop Interface policy + type: str + aliases: [ bfd_multihop_interface_policy ] + description: + description: + - Description of the BFD Multihop Interface policy + type: str + admin_state: + description: + - Admin state of the BFD Multihop Interface policy + type: str + choices: [ enabled, disabled ] + default: enabled + detection_multiplier: + description: + - Detection multiplier of the BFD Multihop Interface policy + type: int + default: 3 + min_transmit_interval: + description: + - Minimum transmit (Tx) interval of the BFD Multihop Interface policy + - Allowed range is 250-999. + type: int + default: 250 + min_receive_interval: + description: + - Minimum receive (Rx) interval of the BFD Multihop Interface policy + - Allowed range is 250-999. + type: int + default: 250 + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci +- cisco.aci.annotation + +notes: +- The C(tenant) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) modules can be used for this. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(bfdMhIfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Anvitha Jain (@anvjain) +""" + +EXAMPLES = r""" +- name: Add a new BFD Multihop Interface policy + cisco.aci.aci_bfd_multihop_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_tenant + name: ansible_bfd_multihop_interface_policy + description: Ansible BFD Multihop Interface Policy + state: present + state: present + delegate_to: localhost + +- name: Remove a BFD Multihop Interface policy + cisco.aci.aci_bfd_multihop_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_tenant + name: ansible_bfd_multihop_interface_policy + state: absent + delegate_to: localhost + +- name: Query a BFD Multihop Interface policy + cisco.aci.aci_bfd_multihop_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_tenant + name: my_dhcp_relay + state: query + delegate_to: localhost + register: query_result + +- name: Query all BFD Multihop Interface policies in a specific tenant + cisco.aci.aci_bfd_multihop_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_tenant + state: query + delegate_to: localhost + register: query_result +""" + +RETURN = r""" + current: + description: The existing configuration from the APIC after the module has finished + returned: success + type: list + sample: + [ + { + "fvTenant": { + "attributes": { + "descr": "Production environment", + "dn": "uni/tn-production", + "name": "production", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "" + } + } + } + ] + error: + description: The error information as returned from the APIC + returned: failure + type: dict + sample: + { + "code": "122", + "text": "unknown managed object class foo" + } + raw: + description: The raw output returned by the APIC REST API (xml or json) + returned: parse error + type: str + sample: '' + sent: + description: The actual/minimal configuration pushed to the APIC + returned: info + type: list + sample: + { + "fvTenant": { + "attributes": { + "descr": "Production environment" + } + } + } + previous: + description: The original configuration from the APIC before the module has started + returned: info + type: list + sample: + [ + { + "fvTenant": { + "attributes": { + "descr": "Production", + "dn": "uni/tn-production", + "name": "production", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "" + } + } + } + ] + proposed: + description: The assembled configuration from the user-provided parameters + returned: info + type: dict + sample: + { + "fvTenant": { + "attributes": { + "descr": "Production environment", + "name": "production" + } + } + } + filter_string: + description: The filter string used for the request + returned: failure or debug + type: str + sample: ?rsp-prop-include=config-only + method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST + response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + sample: OK (30 bytes) + status: + description: The HTTP status from the APIC + returned: failure or debug + type: int + sample: 200 + url: + description: The HTTP url used for the request to the APIC + returned: failure or debug + type: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json + """ + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update(aci_annotation_spec()) + argument_spec.update( + name=dict(type="str", aliases=["bfd_multihop_interface_policy"]), + description=dict(type="str"), + admin_state=dict(type="str", default="enabled", choices=["enabled", "disabled"]), + detection_multiplier=dict(type="int", default=3), + min_transmit_interval=dict(type="int", default=250), + min_receive_interval=dict(type="int", default=250), + state=dict(type="str", default="present", choices=["absent", "present", "query"]), + tenant=dict(type="str"), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "absent", ["name", "tenant"]], + ["state", "present", ["name", "tenant"]], + ], + ) + + name = module.params.get("name") + description = module.params.get("description") + state = module.params.get("state") + tenant = module.params.get("tenant") + admin_state = module.params.get("admin_state") + detection_multiplier = module.params.get("detection_multiplier") + if detection_multiplier is not None and detection_multiplier not in range(1, 50): + module.fail_json(msg='The "detection_multiplier" must be a value between 1 and 50') + min_transmit_interval = module.params.get("min_transmit_interval") + if min_transmit_interval is not None and min_transmit_interval not in range(250, 999): + module.fail_json(msg='The "min_transmit_interval" must be a value between 250 and 999') + min_receive_interval = module.params.get("min_receive_interval") + if min_receive_interval is not None and min_receive_interval not in range(250, 999): + module.fail_json(msg='The "min_receive_interval" must be a value between 250 and 999') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class="fvTenant", + aci_rn="tn-{0}".format(tenant), + module_object=tenant, + target_filter={"name": tenant}, + ), + subclass_1=dict( + aci_class="bfdMhIfPol", + aci_rn="bfdMhIfPol-{0}".format(name), + module_object=name, + target_filter={"name": name}, + ), + ) + + aci.get_existing() + + if state == "present": + aci.payload( + aci_class="bfdMhIfPol", + class_config=dict( + name=name, + descr=description, + adminSt=admin_state, + detectMult=detection_multiplier, + minTxIntvl=min_transmit_interval, + minRxIntvl=min_receive_interval), + ) + + aci.get_diff(aci_class="bfdMhIfPol") + + aci.post_config() + + elif state == "absent": + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/aci_bfd_multihop_interface_policy/aliases b/tests/integration/targets/aci_bfd_multihop_interface_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_bfd_multihop_interface_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_bfd_multihop_interface_policy/tasks/main.yml b/tests/integration/targets/aci_bfd_multihop_interface_policy/tasks/main.yml new file mode 100644 index 000000000..4d97fe404 --- /dev/null +++ b/tests/integration/targets/aci_bfd_multihop_interface_policy/tasks/main.yml @@ -0,0 +1,181 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Anvitha Jain (@anvjain) + +# 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: + 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 + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Query system information + cisco.aci.aci_system: + <<: *aci_info + id: 1 + state: query + register: version + +- name: Execute tasks only for non-cloud sites + when: version.current.0.topSystem.attributes.version is version('5.2', '>=') # This condition will execute only when APIC version >= 5.2 + block: # block specifies execution of tasks within, based on conditions + + # CLEAN ENVIRONMENT + - name: Remove the ansible_tenant + aci_tenant: + <<: *aci_info + tenant: ansible_tenant + state: absent + + - name: Add a new tenant + aci_tenant: + <<: *aci_info + tenant: ansible_tenant + description: Ansible tenant + state: present + + # CREATE BFD Multihop Interface policy + - name: Add a new BFD Multihop Interface policy - check mode + cisco.aci.aci_bfd_multihop_interface_policy: &add_bfd_multihop_interface_pol + <<: *aci_info + tenant: ansible_tenant + name: ansible_bfd_multihop_interface_policy + description: Ansible BFD Multihop Interface Policy + state: present + check_mode: true + register: cm_add_bfd_multihop_interface_pol + + - name: Add a new BFD Multihop Interface policy - normal mode + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *add_bfd_multihop_interface_pol + state: present + register: nm_add_bfd_multihop_interface_pol + + - name: Verify BFD Multihop Interface Policy creation + assert: + that: + - cm_add_bfd_multihop_interface_pol is changed + - nm_add_bfd_multihop_interface_pol is changed + - cm_add_bfd_multihop_interface_pol.previous == nm_add_bfd_multihop_interface_pol.previous == [] + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.dn == "uni/tn-ansible_tenant/bfdMhIfPol-ansible_bfd_multihop_interface_policy" + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.name == "ansible_bfd_multihop_interface_policy" + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.descr == "Ansible BFD Multihop Interface Policy" + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.adminSt == "enabled" + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.detectMult == "3" + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.minRxIntvl == "250" + - nm_add_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.minTxIntvl == "250" + + - name: Add a new BFD Multihop Interface policy again - idempotency + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *add_bfd_multihop_interface_pol + state: present + register: add_bfd_multihop_interface_pol_again + + - name: Verify BFD Multihop Interface Policy creation again - idempotency + assert: + that: + - add_bfd_multihop_interface_pol_again is not changed + - add_bfd_multihop_interface_pol_again.previous != [] + - add_bfd_multihop_interface_pol_again.current | length == 1 + - add_bfd_multihop_interface_pol_again.previous | length == 1 + + - name: Modify a BFD Multihop Interface policy + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *add_bfd_multihop_interface_pol + admin_state: disabled + detection_multiplier: 5 + min_transmit_interval: 270 + min_receive_interval: 500 + state: present + register: update_bfd_multihop_interface_pol + + - name: Verify modifying BFD Multihop Interface Policy + assert: + that: + - update_bfd_multihop_interface_pol is changed + - update_bfd_multihop_interface_pol.previous != update_bfd_multihop_interface_pol.current + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.dn == "uni/tn-ansible_tenant/bfdMhIfPol-ansible_bfd_multihop_interface_policy" + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.name == "ansible_bfd_multihop_interface_policy" + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.descr == "Ansible BFD Multihop Interface Policy" + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.adminSt == "disabled" + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.detectMult == "5" + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.minRxIntvl == "500" + - update_bfd_multihop_interface_pol.current.0.bfdMhIfPol.attributes.minTxIntvl == "270" + + # Added another BFD Multihop Interface policy + - name: Add a new BFD Multihop Interface policy - normal mode + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *add_bfd_multihop_interface_pol + name: ansible_bfd_multihop_interface_policy_2 + state: present + register: add_bfd_multihop_interface_pol_2 + + - name: Verify BFD Multihop Interface Policy creation + assert: + that: + - add_bfd_multihop_interface_pol_2 is changed + - add_bfd_multihop_interface_pol_2.previous == [] + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.dn == "uni/tn-ansible_tenant/bfdMhIfPol-ansible_bfd_multihop_interface_policy_2" + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.name == "ansible_bfd_multihop_interface_policy_2" + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.descr == "Ansible BFD Multihop Interface Policy" + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.adminSt == "enabled" + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.detectMult == "3" + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.minRxIntvl == "250" + - add_bfd_multihop_interface_pol_2.current.0.bfdMhIfPol.attributes.minTxIntvl == "250" + + - name: Query all BFD Multihop Interface policies in a specific tenant + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *aci_info + tenant: ansible_tenant + state: query + register: query_all_result + + - name: Verify querying all BFD Multihop Interface Policies + assert: + that: + - query_all_result is not changed + - query_all_result.current.0.fvTenant.children | length == 2 + - query_all_result.current.0.fvTenant.children[0].bfdMhIfPol.attributes.name == "ansible_bfd_multihop_interface_policy_2" + - query_all_result.current.0.fvTenant.children[1].bfdMhIfPol.attributes.name == "ansible_bfd_multihop_interface_policy" + + - name: Query 'ansible_bfd_multihop_interface_policy' BFD Multihop Interface policies in a specific tenant + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *aci_info + tenant: ansible_tenant + name: ansible_bfd_multihop_interface_policy + state: query + register: query_result + + - name: Verify querying'ansible_bfd_multihop_interface_policy BFD' Multihop Interface Policy + assert: + that: + - query_result is not changed + - query_result.current.0.bfdMhIfPol.attributes.dn == "uni/tn-ansible_tenant/bfdMhIfPol-ansible_bfd_multihop_interface_policy" + - query_result.current.0.bfdMhIfPol.attributes.name == "ansible_bfd_multihop_interface_policy" + + - name: Remove a BFD Multihop Interface policy + cisco.aci.aci_bfd_multihop_interface_policy: + <<: *aci_info + tenant: ansible_tenant + name: ansible_bfd_multihop_interface_policy + state: absent + register: remove_bfd_multihop_interface_pol + + - name: Verifyremoving BFD Multihop Interface Policies + assert: + that: + - remove_bfd_multihop_interface_pol is changed + - remove_bfd_multihop_interface_pol.previous != [] + - remove_bfd_multihop_interface_pol.current == [] + +