From 460e912078aeced25296a177defe0cc42698535d Mon Sep 17 00:00:00 2001 From: samitab Date: Thu, 1 Feb 2024 19:57:30 +1000 Subject: [PATCH 1/3] [minor change] 1. Added modules and tests for 1-N Relationships for BD. - bd_to_netflow_monitor_policy - bd_rogue_exception_mac 2. Fixed missing clean-up in bd_to_l3out tests. --- plugins/modules/aci_bd_rogue_exception_mac.py | 322 ++++++++++++++++++ .../aci_bd_to_netflow_monitor_policy.py | 299 ++++++++++++++++ .../aci_bd_rogue_exception_mac/aliases | 2 + .../aci_bd_rogue_exception_mac/tasks/main.yml | 180 ++++++++++ .../targets/aci_bd_to_l3out/tasks/main.yml | 10 + .../aci_bd_to_netflow_monitor_policy/aliases | 2 + .../tasks/main.yml | 202 +++++++++++ 7 files changed, 1017 insertions(+) create mode 100644 plugins/modules/aci_bd_rogue_exception_mac.py create mode 100644 plugins/modules/aci_bd_to_netflow_monitor_policy.py create mode 100644 tests/integration/targets/aci_bd_rogue_exception_mac/aliases create mode 100644 tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml create mode 100644 tests/integration/targets/aci_bd_to_netflow_monitor_policy/aliases create mode 100644 tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml diff --git a/plugins/modules/aci_bd_rogue_exception_mac.py b/plugins/modules/aci_bd_rogue_exception_mac.py new file mode 100644 index 000000000..6713d1c4c --- /dev/null +++ b/plugins/modules/aci_bd_rogue_exception_mac.py @@ -0,0 +1,322 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2024, Samita Bhattacharjee (@samitab) +# 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": "certified"} + +DOCUMENTATION = r""" +--- +module: aci_bd_rogue_exception_mac +short_description: Manage Rogue Exception MAC (fv:RogueExceptionMac) +description: +- Manage Rogue Exception MACs in BD's on Cisco ACI fabrics. +- Only available in APIC version 5.2 or later. +options: + bd: + description: + - The name of the Bridge Domain. + type: str + aliases: [ bd_name, bridge_domain ] + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + mac: + description: + - MAC address to except from Rogue processing. + type: str + description: + description: + - The description for the Rogue Exception MAC. + type: str + aliases: [ descr ] + 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) and C(bd) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module and M(cisco.aci.aci_bd) can be used for these. +seealso: +- module: cisco.aci.aci_bd +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:RogueExceptionMac). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Samita Bhattacharjee (@samitab) +""" + +EXAMPLES = r""" +- name: Create a tenant + cisco.aci.aci_tenant: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: present + delegate_to: localhost + +- name: Create a bridge domain + cisco.aci.aci_bd: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + state: present + delegate_to: localhost + +- name: Create a subnet + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + state: present + delegate_to: localhost + +- name: Get all subnets + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + +- name: Get all subnets of specific gateway in specified tenant + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + gateway: 10.1.1.1 + mask: 24 + state: query + delegate_to: localhost + register: query_result + +- name: Get specific subnet + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + state: query + delegate_to: localhost + register: query_result + +- name: Delete a subnet + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + state: absent + delegate_to: localhost +""" + +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( + bd=dict(type="str", aliases=["bd_name", "bridge_domain"]), # Not required for querying all objects + tenant=dict(type="str", aliases=["tenant_name"]), # Not required for querying all objects + mac=dict(type="str"), # Not required for querying all objects + description=dict(type="str", aliases=["descr"]), + state=dict(type="str", default="present", choices=["absent", "present", "query"]), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "present", ["bd", "mac", "tenant"]], + ["state", "absent", ["bd", "mac", "tenant"]], + ], + ) + + aci = ACIModule(module) + + description = module.params.get("description") + tenant = module.params.get("tenant") + bd = module.params.get("bd") + mac = module.params.get("mac") + state = module.params.get("state") + + 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="fvBD", + aci_rn="BD-{0}".format(bd), + module_object=bd, + target_filter={"name": bd}, + ), + subclass_2=dict( + aci_class="fvRogueExceptionMac", + aci_rn="rgexpmac-{0}".format(mac), + module_object=mac, + target_filter={"mac": mac}, + ), + ) + + aci.get_existing() + + if state == "present": + aci.payload( + aci_class="fvRogueExceptionMac", + class_config=dict( + descr=description, + mac=mac, + ), + ) + + aci.get_diff(aci_class="fvRogueExceptionMac") + + aci.post_config() + + elif state == "absent": + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/aci_bd_to_netflow_monitor_policy.py b/plugins/modules/aci_bd_to_netflow_monitor_policy.py new file mode 100644 index 000000000..2184083b4 --- /dev/null +++ b/plugins/modules/aci_bd_to_netflow_monitor_policy.py @@ -0,0 +1,299 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2024, Samita Bhattacharjee (@samitab) +# 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": "certified"} + +DOCUMENTATION = r""" +--- +module: aci_bd_to_netflow_monitor_policy +short_description: Bind Bridge Domain to Netflow Monitor Policy (fv:RsBDToNetflowMonitorPol) +description: +- Bind Bridge Domain to Netflow Monitor Policy on Cisco ACI fabrics. +options: + bd: + description: + - The name of the Bridge Domain. + type: str + aliases: [ bd_name, bridge_domain ] + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + netflow_monitor_policy: + description: + - The name of the Netflow Monitor Policy. + type: str + aliases: [ name, policy, monitor_pol] + filter_type: + description: + - Choice of filter type while setting NetFlow Monitor Policies. + type: str + choices: [ce, ipv4, ipv6, unspecified] + aliases: [ filter, type ] + 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(bd) and C(netflow_monitor_policy) parameters should exist before using this module. + The M(cisco.aci.aci_bd) and C(aci_netflow_monitor_policy) can be used for this. +seealso: +- module: cisco.aci.aci_bd +- module: cisco.aci.aci_netflow_monitor_policy +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:RsBDToNetflowMonitorPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Samita Bhattacharjee (@samitab) +""" + +EXAMPLES = r""" +- name: Bind Bridge Domain to Netflow Monitor Policy + cisco.aci.aci_bd_to_netflow_monitor_policy: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: false + bd: web_servers + netflow_monitor_policy: prod_netflow_monitor_policy + tenant: prod + filter_type: ipv4 + state: present + delegate_to: localhost + +- name: Query all Bridge Domains bound to Netflow Monitor Policy + cisco.aci.aci_bd_to_netflow_monitor_policy: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: true + state: query + delegate_to: localhost + register: query_result + +- name: Query specific Bridge Domain(s) bound to an Netflow Monitor Policy + cisco.aci.aci_bd_to_netflow_monitor_policy: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: true + bd: web_servers + netflow_monitor_policy: prod_netflow_monitor_policy + tenant: prod + state: query + delegate_to: localhost + register: query_result + +- name: Unbind Bridge Domain from Netflow Monitor Policy + cisco.aci.aci_bd_to_netflow_monitor_policy: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: true + bd: web_servers + netflow_monitor_policy: prod_netflow_monitor_policy + tenant: prod + filter_type: ipv4 + state: absent + delegate_to: localhost +""" + +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 + +SUBNET_CONTROL_MAPPING = dict( + nd_ra="nd", + no_gw="no-default-gateway", + querier_ip="querier", + unspecified="", +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update(aci_annotation_spec()) + argument_spec.update( + bd=dict(type="str", aliases=["bd_name", "bridge_domain"]), # Not required for querying all objects + netflow_monitor_policy=dict(type="str", aliases=["name", "policy", "monitor_pol"]), # Not required for querying all objects + filter_type=dict(type="str", choices=["ce", "ipv4", "ipv6", "unspecified"], aliases=["filter", "type"]), # Not required for querying all objects + tenant=dict(type="str", aliases=["tenant_name"]), # Not required for querying all objects + state=dict(type="str", default="present", choices=["absent", "present", "query"]), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "present", ["bd", "netflow_monitor_policy", "tenant", "filter_type"]], + ["state", "absent", ["bd", "netflow_monitor_policy", "tenant", "filter_type"]], + ], + ) + + bd = module.params.get("bd") + netflow_monitor_policy = module.params.get("netflow_monitor_policy") + filter_type = module.params.get("filter_type") + state = module.params.get("state") + tenant = module.params.get("tenant") + + 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="fvBD", + aci_rn="BD-{0}".format(bd), + module_object=bd, + target_filter={"name": bd}, + ), + subclass_2=dict( + aci_class="fvRsBDToNetflowMonitorPol", + aci_rn="rsBDToNetflowMonitorPol-[{0}]-{1}".format(netflow_monitor_policy, filter_type), + module_object=netflow_monitor_policy, + target_filter={"tnNetflowMonitorPolName": netflow_monitor_policy}, + ), + ) + + aci.get_existing() + + if state == "present": + aci.payload( + aci_class="fvRsBDToNetflowMonitorPol", + class_config=dict(tnNetflowMonitorPolName=netflow_monitor_policy, fltType=filter_type), + ) + + aci.get_diff(aci_class="fvRsBDToNetflowMonitorPol") + + aci.post_config() + + elif state == "absent": + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/aci_bd_rogue_exception_mac/aliases b/tests/integration/targets/aci_bd_rogue_exception_mac/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_bd_rogue_exception_mac/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml b/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml new file mode 100644 index 000000000..336ccdde1 --- /dev/null +++ b/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml @@ -0,0 +1,180 @@ +# Test code for the ACI modules +# Copyright: (c) 2024, Samita Bhattacharjee (@samitab) + +# 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 + 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 + +- name: Set vars + ansible.builtin.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 + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: &aci_tenant_absent + <<: *aci_info + state: absent + tenant: ansible_test + +- name: Verify Cloud and Non-Cloud Sites in use. + ansible.builtin.include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites and APIC version >= 5.2 + when: query_cloud.current == [] and version.current.0.topSystem.attributes.version is version('5.2', '>=') + block: + - name: Create tenant + cisco.aci.aci_tenant: &aci_tenant_present + <<: *aci_tenant_absent + state: present + register: tenant_present + + - name: ensure bd exists for tests to kick off + cisco.aci.aci_bd: &aci_bd_present + <<: *aci_tenant_present + bd: anstest + register: bd_present + + - name: ensure rogue exception mac does not exist for tests to kick off + cisco.aci.aci_bd_rogue_exception_mac: &aci_rogue_exception_mac_absent + <<: *aci_bd_present + state: absent + mac: "AA:BB:CC:DD:EE:11" + description: 1st MAC + + - name: ensure second rogue exception mac does not exist for tests to kick off + cisco.aci.aci_bd_rogue_exception_mac: &aci_rogue_exception_mac_absent_2 + <<: *aci_rogue_exception_mac_absent + mac: "AA-BB-CC-DD-EE-22" + description: 2nd MAC + + + - name: create first rogue exception mac in bd (check_mode) + cisco.aci.aci_bd_rogue_exception_mac: &aci_bd_rogue_exception_mac_present + <<: *aci_rogue_exception_mac_absent + state: present + check_mode: true + register: cm_bd_rogue_exception_mac + + - name: create first rogue exception mac in bd (normal_mode) + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present + register: nm_bd_rogue_exception_mac + + - name: create first rogue exception mac in bd again - testing idempotency + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present + register: bd_rogue_exception_mac_idempotency + + - name: create second rogue exception mac in bd + cisco.aci.aci_bd_rogue_exception_mac: &aci_bd_rogue_exception_mac_present_2 + <<: *aci_rogue_exception_mac_absent_2 + state: present + register: nm_bd_rogue_exception_mac_2 + + - name: asserts for creation tasks + ansible.builtin.assert: + that: + - cm_bd_rogue_exception_mac is changed + - cm_bd_rogue_exception_mac.previous == [] + - cm_bd_rogue_exception_mac.current == [] + - nm_bd_rogue_exception_mac is changed + - nm_bd_rogue_exception_mac.current.0.fvRogueExceptionMac.attributes.dn == "uni/tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:11" + - nm_bd_rogue_exception_mac.current.0.fvRogueExceptionMac.attributes.mac == "AA:BB:CC:DD:EE:11" + - nm_bd_rogue_exception_mac.current.0.fvRogueExceptionMac.attributes.descr == "1st MAC" + - bd_rogue_exception_mac_idempotency is not changed + - nm_bd_rogue_exception_mac_2 is changed + - nm_bd_rogue_exception_mac_2.current.0.fvRogueExceptionMac.attributes.dn == "uni/tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:22" + - nm_bd_rogue_exception_mac_2.current.0.fvRogueExceptionMac.attributes.mac == "AA:BB:CC:DD:EE:22" + - nm_bd_rogue_exception_mac_2.current.0.fvRogueExceptionMac.attributes.descr == "2nd MAC" + + - name: Query all bds bound to rogue exception mac + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_tenant_present + state: query + register: query_all_bd_to_rogue_exception_mac + + - name: Query first bd with first rogue exception mac + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present + state: query + register: query_first_bd_to_rogue_exception_mac + + - name: asserts query tasks + ansible.builtin.assert: + that: + - query_all_bd_to_rogue_exception_mac is not changed + - '"fvRogueExceptionMac" in query_all_bd_to_rogue_exception_mac.filter_string' + - query_all_bd_to_rogue_exception_mac.current.0.fvTenant.children.0.fvBD.children | length == 2 + - query_all_bd_to_rogue_exception_mac.current.0.fvTenant.children.0.fvBD.attributes.name == "anstest" + - query_all_bd_to_rogue_exception_mac.current.0.fvTenant.children.0.fvBD.children.0.fvRogueExceptionMac.attributes.rn == "rgexpmac-AA:BB:CC:DD:EE:22" + - query_all_bd_to_rogue_exception_mac.current.0.fvTenant.children.0.fvBD.children.1.fvRogueExceptionMac.attributes.rn == "rgexpmac-AA:BB:CC:DD:EE:11" + - query_first_bd_to_rogue_exception_mac is not changed + - '"tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:11.json" in query_first_bd_to_rogue_exception_mac.url' + + - name: delete first rogue exception mac (check_mode) + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present + state: absent + check_mode: true + register: cm_unbind_bd_to_rogue_exception_mac + + - name: delete first rogue exception mac (normal_mode) + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present + state: absent + register: nm_unbind_bd_to_rogue_exception_mac + + - name: delete first rogue exception mac again - testing idempotency + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present + state: absent + register: unbind_bd_to_rogue_exception_mac_idempotency + + - name: delete second rogue exception mac + cisco.aci.aci_bd_rogue_exception_mac: + <<: *aci_bd_rogue_exception_mac_present_2 + state: absent + register: nm_unbind_bd_to_rogue_exception_mac_2 + + - name: asserts for deletion tasks + ansible.builtin.assert: + that: + - cm_unbind_bd_to_rogue_exception_mac is changed + - cm_unbind_bd_to_rogue_exception_mac.proposed == {} + - nm_unbind_bd_to_rogue_exception_mac is changed + - nm_unbind_bd_to_rogue_exception_mac.previous != [] + - nm_unbind_bd_to_rogue_exception_mac.method == "DELETE" + - unbind_bd_to_rogue_exception_mac_idempotency is not changed + - unbind_bd_to_rogue_exception_mac_idempotency.previous == [] + - nm_unbind_bd_to_rogue_exception_mac_2 is changed + - nm_unbind_bd_to_rogue_exception_mac_2.previous != [] + - nm_unbind_bd_to_rogue_exception_mac_2.method == "DELETE" + + - name: delete bd - cleanup before ending tests + cisco.aci.aci_bd: + <<: *aci_bd_present + state: absent + when: bd_present is changed + + - name: delete tenant - cleanup before ending tests + cisco.aci.aci_tenant: + <<: *aci_tenant_present + state: absent + when: tenant_present is changed diff --git a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml index 34222eace..94e7b6db4 100644 --- a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml +++ b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml @@ -186,11 +186,21 @@ <<: *aci_bd_present state: absent + - name: delete bd_2 - cleanup before ending tests + cisco.aci.aci_bd: + <<: *aci_bd_present_2 + state: absent + - name: delete l3out - cleanup before ending tests cisco.aci.aci_l3out: <<: *aci_l3_out_present state: absent + - name: delete l3out_2 - cleanup before ending tests + cisco.aci.aci_l3out: + <<: *aci_l3_out_present_2 + state: absent + - name: delete vrf - cleanup before ending tests cisco.aci.aci_vrf: <<: *aci_vrf_present diff --git a/tests/integration/targets/aci_bd_to_netflow_monitor_policy/aliases b/tests/integration/targets/aci_bd_to_netflow_monitor_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_bd_to_netflow_monitor_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml b/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml new file mode 100644 index 000000000..d1d5f2d93 --- /dev/null +++ b/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml @@ -0,0 +1,202 @@ +# Test code for the ACI modules +# Copyright: (c) 2024, Samita Bhattacharjee (@samitab) + +# 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 + 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 + +- name: Set vars + ansible.builtin.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 + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: &aci_tenant_absent + <<: *aci_info + state: absent + tenant: ansible_test + +- name: Verify Cloud and Non-Cloud Sites in use. + ansible.builtin.include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + - name: Create tenant + cisco.aci.aci_tenant: &aci_tenant_present + <<: *aci_tenant_absent + state: present + + - name: Create first netflow monitor policy + cisco.aci.aci_netflow_monitor_policy: &aci_netflow_monitor_policy_present + <<: *aci_tenant_absent + netflow_monitor_policy: ansible_netflow_monitor_policy + state: present + + - name: Create second netflow monitor policy + cisco.aci.aci_netflow_monitor_policy: &aci_netflow_monitor_policy_present_2 + <<: *aci_tenant_absent + netflow_monitor_policy: ansible_netflow_monitor_policy_2 + state: present + + - name: Create first bd + cisco.aci.aci_bd: &aci_bd_present + <<: *aci_tenant_present + bd: anstest + + - name: Create second bd + cisco.aci.aci_bd: &aci_bd_present_2 + <<: *aci_tenant_present + bd: anstest_2 + + - name: Ensure first binding bd to netflow monitor policy does not exist + cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_absent + <<: *aci_tenant_present + bd: anstest + netflow_monitor_policy: ansible_netflow_monitor_policy + filter_type: ipv4 + state: absent + + - name: Ensure second binding bd to netflow monitor policy does not exist + cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_absent_2 + <<: *aci_tenant_present + bd: anstest_2 + netflow_monitor_policy: ansible_netflow_monitor_policy_2 + filter_type: ipv6 + state: absent + + - name: bind bd to netflow monitor policy - first binding (check_mode) + cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_present + <<: *aci_bd_to_netflow_monitor_policy_absent + state: present + check_mode: true + register: cm_bd_to_netflow_monitor_policy + + - name: bind bd to netflow monitor policy - first binding (normal_mode) + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present + register: nm_bd_to_netflow_monitor_policy + + - name: bind bd to netflow monitor policy again - testing idempotency + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present + register: bd_to_netflow_monitor_policy_idempotency + + - name: bind bd to netflow monitor policy again - second binding + cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_present_2 + <<: *aci_bd_to_netflow_monitor_policy_absent_2 + state: present + register: nm_bd_to_netflow_monitor_policy_2 + + - name: asserts for creation tasks + ansible.builtin.assert: + that: + - cm_bd_to_netflow_monitor_policy is changed + - cm_bd_to_netflow_monitor_policy.previous == [] + - cm_bd_to_netflow_monitor_policy.current == [] + - nm_bd_to_netflow_monitor_policy is changed + - nm_bd_to_netflow_monitor_policy.current.0.fvRsBDToNetflowMonitorPol.attributes.dn == "uni/tn-ansible_test/BD-anstest/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy]-ipv4" + - nm_bd_to_netflow_monitor_policy.current.0.fvRsBDToNetflowMonitorPol.attributes.tnNetflowMonitorPolName == "ansible_netflow_monitor_policy" + - bd_to_netflow_monitor_policy_idempotency is not changed + - nm_bd_to_netflow_monitor_policy_2 is changed + - nm_bd_to_netflow_monitor_policy_2.current.0.fvRsBDToNetflowMonitorPol.attributes.dn == "uni/tn-ansible_test/BD-anstest_2/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy_2]-ipv6" + - nm_bd_to_netflow_monitor_policy_2.current.0.fvRsBDToNetflowMonitorPol.attributes.tnNetflowMonitorPolName == "ansible_netflow_monitor_policy_2" + + - name: Query all bds bound to netflow monitor policies + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_tenant_present + state: query + register: query_all_bd_to_netflow_monitor_policy + + - name: Query first bd bound to first netflow monitor policy + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present + state: query + register: query_first_bd_to_netflow_monitor_policy + + - name: asserts query tasks + ansible.builtin.assert: + that: + - query_all_bd_to_netflow_monitor_policy is not changed + - '"fvRsBDToNetflowMonitorPol" in query_all_bd_to_netflow_monitor_policy.filter_string' + - query_all_bd_to_netflow_monitor_policy.current.0.fvTenant.children | length >= 2 + - query_all_bd_to_netflow_monitor_policy.current.0.fvTenant.children.0.fvBD.attributes.name == "anstest_2" + - query_all_bd_to_netflow_monitor_policy.current.0.fvTenant.children.0.fvBD.children.0.fvRsBDToNetflowMonitorPol.attributes.tRn == "monitorpol-ansible_netflow_monitor_policy_2" + - query_all_bd_to_netflow_monitor_policy.current.0.fvTenant.children.1.fvBD.attributes.name == "anstest" + - query_all_bd_to_netflow_monitor_policy.current.0.fvTenant.children.1.fvBD.children.0.fvRsBDToNetflowMonitorPol.attributes.tRn == "monitorpol-ansible_netflow_monitor_policy" + - query_first_bd_to_netflow_monitor_policy is not changed + - '"tn-ansible_test/BD-anstest/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy]-ipv4.json" in query_first_bd_to_netflow_monitor_policy.url' + + - name: unbind bd to netflow monitor policy - first binding (check_mode) + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present + state: absent + check_mode: true + register: cm_unbind_bd_to_netflow_monitor_policy + + - name: unbind bd to netflow_monitor_policy - first binding (normal_mode) + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present + state: absent + register: nm_unbind_bd_to_netflow_monitor_policy + + - name: unbind bd to netflow_monitor_policy again - testing idempotency + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present + state: absent + register: unbind_bd_to_netflow_monitor_policy_idempotency + + - name: unbind bd to netflow_monitor_policy - second binding + cisco.aci.aci_bd_to_netflow_monitor_policy: + <<: *aci_bd_to_netflow_monitor_policy_present_2 + state: absent + register: nm_unbind_bd_to_netflow_monitor_policy_2 + + - name: asserts for deletion tasks + ansible.builtin.assert: + that: + - cm_unbind_bd_to_netflow_monitor_policy is changed + - cm_unbind_bd_to_netflow_monitor_policy.proposed == {} + - nm_unbind_bd_to_netflow_monitor_policy is changed + - nm_unbind_bd_to_netflow_monitor_policy.previous != [] + - nm_unbind_bd_to_netflow_monitor_policy.method == "DELETE" + - unbind_bd_to_netflow_monitor_policy_idempotency is not changed + - unbind_bd_to_netflow_monitor_policy_idempotency.previous == [] + - nm_unbind_bd_to_netflow_monitor_policy_2 is changed + - nm_unbind_bd_to_netflow_monitor_policy_2.previous != [] + - nm_unbind_bd_to_netflow_monitor_policy_2.method == "DELETE" + + - name: delete bd - cleanup before ending tests + cisco.aci.aci_bd: + <<: *aci_bd_present + state: absent + + - name: delete bd_2 - cleanup before ending tests + cisco.aci.aci_bd: + <<: *aci_bd_present_2 + state: absent + + - name: delete netflow monitor policy - cleanup before ending tests + cisco.aci.aci_netflow_monitor_policy: + <<: *aci_netflow_monitor_policy_present + state: absent + + - name: delete netflow monitor policy 2 - cleanup before ending tests + cisco.aci.aci_netflow_monitor_policy: + <<: *aci_netflow_monitor_policy_present_2 + state: absent + + - name: delete tenant - cleanup before ending tests + cisco.aci.aci_tenant: + <<: *aci_tenant_present + state: absent From 7dc4f247b5bb558da42dbb6e4b2e11dfd0553485 Mon Sep 17 00:00:00 2001 From: samitab Date: Wed, 21 Feb 2024 09:30:51 +1000 Subject: [PATCH 2/3] [Ignore] Fixed bd_child_modules based on PR comments --- plugins/modules/aci_bd_rogue_exception_mac.py | 51 ++++--------- .../aci_bd_to_netflow_monitor_policy.py | 31 ++++---- .../aci_bd_rogue_exception_mac/tasks/main.yml | 54 +++++++------- .../tasks/main.yml | 71 ++++++++----------- 4 files changed, 86 insertions(+), 121 deletions(-) diff --git a/plugins/modules/aci_bd_rogue_exception_mac.py b/plugins/modules/aci_bd_rogue_exception_mac.py index 6713d1c4c..8174f00db 100644 --- a/plugins/modules/aci_bd_rogue_exception_mac.py +++ b/plugins/modules/aci_bd_rogue_exception_mac.py @@ -62,79 +62,56 @@ """ EXAMPLES = r""" -- name: Create a tenant - cisco.aci.aci_tenant: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - state: present - delegate_to: localhost - -- name: Create a bridge domain - cisco.aci.aci_bd: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - bd: database - state: present - delegate_to: localhost - -- name: Create a subnet - cisco.aci.aci_bd_subnet: +- name: Create a Rogue Exception MAC + cisco.aci.aci_bd_rogue_exception_mac: host: apic username: admin password: SomeSecretPassword tenant: production bd: database - gateway: 10.1.1.1 - mask: 24 + mac: "AA:BB:CC:DD:EE:11" + description: 1st MAC state: present delegate_to: localhost -- name: Get all subnets - cisco.aci.aci_bd_subnet: +- name: Get all Rogue Exception MACs + cisco.aci.aci_bd_rogue_exception_mac: host: apic username: admin password: SomeSecretPassword state: query delegate_to: localhost -- name: Get all subnets of specific gateway in specified tenant - cisco.aci.aci_bd_subnet: +- name: Get all Rogue Exception MACs in specified Tenant + cisco.aci.aci_bd_rogue_exception_mac: host: apic username: admin password: SomeSecretPassword tenant: production - gateway: 10.1.1.1 - mask: 24 state: query delegate_to: localhost register: query_result -- name: Get specific subnet - cisco.aci.aci_bd_subnet: +- name: Get specific Rogue Exception MAC + cisco.aci.aci_bd_rogue_exception_mac: host: apic username: admin password: SomeSecretPassword tenant: production bd: database - gateway: 10.1.1.1 - mask: 24 + mac: "AA:BB:CC:DD:EE:11" state: query delegate_to: localhost register: query_result -- name: Delete a subnet - cisco.aci.aci_bd_subnet: +- name: Remove a Rogue Exception MAC from a Bridge Domain + cisco.aci.aci_bd_rogue_exception_mac: host: apic username: admin password: SomeSecretPassword tenant: production bd: database - gateway: 10.1.1.1 - mask: 24 + mac: "AA:BB:CC:DD:EE:11" state: absent delegate_to: localhost """ diff --git a/plugins/modules/aci_bd_to_netflow_monitor_policy.py b/plugins/modules/aci_bd_to_netflow_monitor_policy.py index 2184083b4..4bd51a7a3 100644 --- a/plugins/modules/aci_bd_to_netflow_monitor_policy.py +++ b/plugins/modules/aci_bd_to_netflow_monitor_policy.py @@ -65,9 +65,9 @@ EXAMPLES = r""" - name: Bind Bridge Domain to Netflow Monitor Policy cisco.aci.aci_bd_to_netflow_monitor_policy: - host: "{{ inventory_hostname }}" - username: "{{ username }}" - password: "{{ password }}" + host: apic + username: admin + password: SomeSecretPassword validate_certs: false bd: web_servers netflow_monitor_policy: prod_netflow_monitor_policy @@ -78,9 +78,9 @@ - name: Query all Bridge Domains bound to Netflow Monitor Policy cisco.aci.aci_bd_to_netflow_monitor_policy: - host: "{{ inventory_hostname }}" - username: "{{ username }}" - password: "{{ password }}" + host: apic + username: admin + password: SomeSecretPassword validate_certs: true state: query delegate_to: localhost @@ -88,9 +88,9 @@ - name: Query specific Bridge Domain(s) bound to an Netflow Monitor Policy cisco.aci.aci_bd_to_netflow_monitor_policy: - host: "{{ inventory_hostname }}" - username: "{{ username }}" - password: "{{ password }}" + host: apic + username: admin + password: SomeSecretPassword validate_certs: true bd: web_servers netflow_monitor_policy: prod_netflow_monitor_policy @@ -101,9 +101,9 @@ - name: Unbind Bridge Domain from Netflow Monitor Policy cisco.aci.aci_bd_to_netflow_monitor_policy: - host: "{{ inventory_hostname }}" - username: "{{ username }}" - password: "{{ password }}" + host: apic + username: admin + password: SomeSecretPassword validate_certs: true bd: web_servers netflow_monitor_policy: prod_netflow_monitor_policy @@ -221,13 +221,6 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec -SUBNET_CONTROL_MAPPING = dict( - nd_ra="nd", - no_gw="no-default-gateway", - querier_ip="querier", - unspecified="", -) - def main(): argument_spec = aci_argument_spec() diff --git a/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml b/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml index 336ccdde1..7aebbb44d 100644 --- a/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml +++ b/tests/integration/targets/aci_bd_rogue_exception_mac/tasks/main.yml @@ -17,7 +17,7 @@ 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") }}' - name: Query system information cisco.aci.aci_system: @@ -45,60 +45,65 @@ state: present register: tenant_present - - name: ensure bd exists for tests to kick off + - name: Ensure bd exists for tests to kick off cisco.aci.aci_bd: &aci_bd_present <<: *aci_tenant_present bd: anstest register: bd_present - - name: ensure rogue exception mac does not exist for tests to kick off + - name: Ensure rogue exception mac does not exist for tests to kick off cisco.aci.aci_bd_rogue_exception_mac: &aci_rogue_exception_mac_absent <<: *aci_bd_present state: absent mac: "AA:BB:CC:DD:EE:11" description: 1st MAC - - name: ensure second rogue exception mac does not exist for tests to kick off + - name: Ensure second rogue exception mac does not exist for tests to kick off cisco.aci.aci_bd_rogue_exception_mac: &aci_rogue_exception_mac_absent_2 <<: *aci_rogue_exception_mac_absent mac: "AA-BB-CC-DD-EE-22" description: 2nd MAC - - name: create first rogue exception mac in bd (check_mode) + - name: Create first rogue exception mac in bd (check_mode) cisco.aci.aci_bd_rogue_exception_mac: &aci_bd_rogue_exception_mac_present <<: *aci_rogue_exception_mac_absent state: present check_mode: true register: cm_bd_rogue_exception_mac - - name: create first rogue exception mac in bd (normal_mode) + - name: Create first rogue exception mac in bd (normal_mode) cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present register: nm_bd_rogue_exception_mac - - name: create first rogue exception mac in bd again - testing idempotency + - name: Create first rogue exception mac in bd again - testing idempotency cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present register: bd_rogue_exception_mac_idempotency - - name: create second rogue exception mac in bd + - name: Create second rogue exception mac in bd cisco.aci.aci_bd_rogue_exception_mac: &aci_bd_rogue_exception_mac_present_2 <<: *aci_rogue_exception_mac_absent_2 state: present register: nm_bd_rogue_exception_mac_2 - - name: asserts for creation tasks + - name: Asserts for creation tasks ansible.builtin.assert: that: - cm_bd_rogue_exception_mac is changed - cm_bd_rogue_exception_mac.previous == [] - cm_bd_rogue_exception_mac.current == [] + - cm_bd_rogue_exception_mac.proposed.fvRogueExceptionMac.attributes.dn == "uni/tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:11" + - cm_bd_rogue_exception_mac.proposed.fvRogueExceptionMac.attributes.mac == "AA:BB:CC:DD:EE:11" + - cm_bd_rogue_exception_mac.proposed.fvRogueExceptionMac.attributes.descr == "1st MAC" - nm_bd_rogue_exception_mac is changed - nm_bd_rogue_exception_mac.current.0.fvRogueExceptionMac.attributes.dn == "uni/tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:11" - nm_bd_rogue_exception_mac.current.0.fvRogueExceptionMac.attributes.mac == "AA:BB:CC:DD:EE:11" - nm_bd_rogue_exception_mac.current.0.fvRogueExceptionMac.attributes.descr == "1st MAC" - bd_rogue_exception_mac_idempotency is not changed + - bd_rogue_exception_mac_idempotency.current == bd_rogue_exception_mac_idempotency.previous + - bd_rogue_exception_mac_idempotency.sent == {} - nm_bd_rogue_exception_mac_2 is changed - nm_bd_rogue_exception_mac_2.current.0.fvRogueExceptionMac.attributes.dn == "uni/tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:22" - nm_bd_rogue_exception_mac_2.current.0.fvRogueExceptionMac.attributes.mac == "AA:BB:CC:DD:EE:22" @@ -108,15 +113,17 @@ cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_tenant_present state: query + output_level: debug register: query_all_bd_to_rogue_exception_mac - name: Query first bd with first rogue exception mac cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present state: query + output_level: debug register: query_first_bd_to_rogue_exception_mac - - name: asserts query tasks + - name: Asserts query tasks ansible.builtin.assert: that: - query_all_bd_to_rogue_exception_mac is not changed @@ -128,52 +135,51 @@ - query_first_bd_to_rogue_exception_mac is not changed - '"tn-ansible_test/BD-anstest/rgexpmac-AA:BB:CC:DD:EE:11.json" in query_first_bd_to_rogue_exception_mac.url' - - name: delete first rogue exception mac (check_mode) + - name: Delete first rogue exception mac (check_mode) cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present state: absent check_mode: true register: cm_unbind_bd_to_rogue_exception_mac - - name: delete first rogue exception mac (normal_mode) + - name: Delete first rogue exception mac (normal_mode) cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present state: absent register: nm_unbind_bd_to_rogue_exception_mac - - name: delete first rogue exception mac again - testing idempotency + - name: Delete first rogue exception mac again - testing idempotency cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present state: absent register: unbind_bd_to_rogue_exception_mac_idempotency - - name: delete second rogue exception mac + - name: Delete second rogue exception mac cisco.aci.aci_bd_rogue_exception_mac: <<: *aci_bd_rogue_exception_mac_present_2 state: absent register: nm_unbind_bd_to_rogue_exception_mac_2 - - name: asserts for deletion tasks + - name: Asserts for deletion tasks ansible.builtin.assert: that: - cm_unbind_bd_to_rogue_exception_mac is changed + - cm_unbind_bd_to_rogue_exception_mac.current == cm_unbind_bd_to_rogue_exception_mac.previous - cm_unbind_bd_to_rogue_exception_mac.proposed == {} - nm_unbind_bd_to_rogue_exception_mac is changed - nm_unbind_bd_to_rogue_exception_mac.previous != [] - - nm_unbind_bd_to_rogue_exception_mac.method == "DELETE" + - nm_unbind_bd_to_rogue_exception_mac.proposed == {} + - nm_unbind_bd_to_rogue_exception_mac.current == [] + - nm_unbind_bd_to_rogue_exception_mac.previous == cm_unbind_bd_to_rogue_exception_mac.current - unbind_bd_to_rogue_exception_mac_idempotency is not changed - unbind_bd_to_rogue_exception_mac_idempotency.previous == [] + - unbind_bd_to_rogue_exception_mac_idempotency.current == [] + - unbind_bd_to_rogue_exception_mac_idempotency.previous == [] - nm_unbind_bd_to_rogue_exception_mac_2 is changed - nm_unbind_bd_to_rogue_exception_mac_2.previous != [] - - nm_unbind_bd_to_rogue_exception_mac_2.method == "DELETE" - - - name: delete bd - cleanup before ending tests - cisco.aci.aci_bd: - <<: *aci_bd_present - state: absent - when: bd_present is changed + - nm_unbind_bd_to_rogue_exception_mac_2.current == [] - - name: delete tenant - cleanup before ending tests + - name: Delete tenant - cleanup before ending tests cisco.aci.aci_tenant: <<: *aci_tenant_present state: absent diff --git a/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml b/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml index d1d5f2d93..9a7a44d16 100644 --- a/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml +++ b/tests/integration/targets/aci_bd_to_netflow_monitor_policy/tasks/main.yml @@ -17,7 +17,7 @@ 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 the ansible_tenant @@ -38,13 +38,13 @@ state: present - name: Create first netflow monitor policy - cisco.aci.aci_netflow_monitor_policy: &aci_netflow_monitor_policy_present + cisco.aci.aci_netflow_monitor_policy: <<: *aci_tenant_absent netflow_monitor_policy: ansible_netflow_monitor_policy state: present - name: Create second netflow monitor policy - cisco.aci.aci_netflow_monitor_policy: &aci_netflow_monitor_policy_present_2 + cisco.aci.aci_netflow_monitor_policy: <<: *aci_tenant_absent netflow_monitor_policy: ansible_netflow_monitor_policy_2 state: present @@ -61,53 +61,55 @@ - name: Ensure first binding bd to netflow monitor policy does not exist cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_absent - <<: *aci_tenant_present - bd: anstest + <<: *aci_bd_present netflow_monitor_policy: ansible_netflow_monitor_policy filter_type: ipv4 state: absent - name: Ensure second binding bd to netflow monitor policy does not exist cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_absent_2 - <<: *aci_tenant_present - bd: anstest_2 + <<: *aci_bd_present_2 netflow_monitor_policy: ansible_netflow_monitor_policy_2 filter_type: ipv6 state: absent - - name: bind bd to netflow monitor policy - first binding (check_mode) + - name: Bind bd to netflow monitor policy - first binding (check_mode) cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_present <<: *aci_bd_to_netflow_monitor_policy_absent state: present check_mode: true register: cm_bd_to_netflow_monitor_policy - - name: bind bd to netflow monitor policy - first binding (normal_mode) + - name: Bind bd to netflow monitor policy - first binding (normal_mode) cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present register: nm_bd_to_netflow_monitor_policy - - name: bind bd to netflow monitor policy again - testing idempotency + - name: Bind bd to netflow monitor policy again - testing idempotency cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present register: bd_to_netflow_monitor_policy_idempotency - - name: bind bd to netflow monitor policy again - second binding + - name: Bind bd to netflow monitor policy again - second binding cisco.aci.aci_bd_to_netflow_monitor_policy: &aci_bd_to_netflow_monitor_policy_present_2 <<: *aci_bd_to_netflow_monitor_policy_absent_2 state: present register: nm_bd_to_netflow_monitor_policy_2 - - name: asserts for creation tasks + - name: Asserts for creation tasks ansible.builtin.assert: that: - cm_bd_to_netflow_monitor_policy is changed - cm_bd_to_netflow_monitor_policy.previous == [] - cm_bd_to_netflow_monitor_policy.current == [] + - cm_bd_to_netflow_monitor_policy.proposed.fvRsBDToNetflowMonitorPol.attributes.dn == "uni/tn-ansible_test/BD-anstest/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy]-ipv4" + - cm_bd_to_netflow_monitor_policy.proposed.fvRsBDToNetflowMonitorPol.attributes.tnNetflowMonitorPolName == "ansible_netflow_monitor_policy" - nm_bd_to_netflow_monitor_policy is changed - nm_bd_to_netflow_monitor_policy.current.0.fvRsBDToNetflowMonitorPol.attributes.dn == "uni/tn-ansible_test/BD-anstest/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy]-ipv4" - nm_bd_to_netflow_monitor_policy.current.0.fvRsBDToNetflowMonitorPol.attributes.tnNetflowMonitorPolName == "ansible_netflow_monitor_policy" - bd_to_netflow_monitor_policy_idempotency is not changed + - bd_to_netflow_monitor_policy_idempotency.current == bd_to_netflow_monitor_policy_idempotency.previous + - bd_to_netflow_monitor_policy_idempotency.sent == {} - nm_bd_to_netflow_monitor_policy_2 is changed - nm_bd_to_netflow_monitor_policy_2.current.0.fvRsBDToNetflowMonitorPol.attributes.dn == "uni/tn-ansible_test/BD-anstest_2/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy_2]-ipv6" - nm_bd_to_netflow_monitor_policy_2.current.0.fvRsBDToNetflowMonitorPol.attributes.tnNetflowMonitorPolName == "ansible_netflow_monitor_policy_2" @@ -116,15 +118,17 @@ cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_tenant_present state: query + output_level: debug register: query_all_bd_to_netflow_monitor_policy - name: Query first bd bound to first netflow monitor policy cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present state: query + output_level: debug register: query_first_bd_to_netflow_monitor_policy - - name: asserts query tasks + - name: Asserts query tasks ansible.builtin.assert: that: - query_all_bd_to_netflow_monitor_policy is not changed @@ -137,66 +141,51 @@ - query_first_bd_to_netflow_monitor_policy is not changed - '"tn-ansible_test/BD-anstest/rsBDToNetflowMonitorPol-[ansible_netflow_monitor_policy]-ipv4.json" in query_first_bd_to_netflow_monitor_policy.url' - - name: unbind bd to netflow monitor policy - first binding (check_mode) + - name: Unbind bd to netflow monitor policy - first binding (check_mode) cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present state: absent check_mode: true register: cm_unbind_bd_to_netflow_monitor_policy - - name: unbind bd to netflow_monitor_policy - first binding (normal_mode) + - name: Unbind bd to netflow_monitor_policy - first binding (normal_mode) cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present state: absent register: nm_unbind_bd_to_netflow_monitor_policy - - name: unbind bd to netflow_monitor_policy again - testing idempotency + - name: Unbind bd to netflow_monitor_policy again - testing idempotency cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present state: absent register: unbind_bd_to_netflow_monitor_policy_idempotency - - name: unbind bd to netflow_monitor_policy - second binding + - name: Unbind bd to netflow_monitor_policy - second binding cisco.aci.aci_bd_to_netflow_monitor_policy: <<: *aci_bd_to_netflow_monitor_policy_present_2 state: absent register: nm_unbind_bd_to_netflow_monitor_policy_2 - - name: asserts for deletion tasks + - name: Asserts for deletion tasks ansible.builtin.assert: that: - cm_unbind_bd_to_netflow_monitor_policy is changed + - cm_unbind_bd_to_netflow_monitor_policy.current == cm_unbind_bd_to_netflow_monitor_policy.previous - cm_unbind_bd_to_netflow_monitor_policy.proposed == {} - nm_unbind_bd_to_netflow_monitor_policy is changed - nm_unbind_bd_to_netflow_monitor_policy.previous != [] - - nm_unbind_bd_to_netflow_monitor_policy.method == "DELETE" + - nm_unbind_bd_to_netflow_monitor_policy.proposed == {} + - nm_unbind_bd_to_netflow_monitor_policy.current == [] + - nm_unbind_bd_to_netflow_monitor_policy.previous == cm_unbind_bd_to_netflow_monitor_policy.current - unbind_bd_to_netflow_monitor_policy_idempotency is not changed + - unbind_bd_to_netflow_monitor_policy_idempotency.proposed == {} + - unbind_bd_to_netflow_monitor_policy_idempotency.current == [] - unbind_bd_to_netflow_monitor_policy_idempotency.previous == [] - nm_unbind_bd_to_netflow_monitor_policy_2 is changed - nm_unbind_bd_to_netflow_monitor_policy_2.previous != [] - - nm_unbind_bd_to_netflow_monitor_policy_2.method == "DELETE" - - - name: delete bd - cleanup before ending tests - cisco.aci.aci_bd: - <<: *aci_bd_present - state: absent - - - name: delete bd_2 - cleanup before ending tests - cisco.aci.aci_bd: - <<: *aci_bd_present_2 - state: absent - - - name: delete netflow monitor policy - cleanup before ending tests - cisco.aci.aci_netflow_monitor_policy: - <<: *aci_netflow_monitor_policy_present - state: absent - - - name: delete netflow monitor policy 2 - cleanup before ending tests - cisco.aci.aci_netflow_monitor_policy: - <<: *aci_netflow_monitor_policy_present_2 - state: absent + - nm_unbind_bd_to_netflow_monitor_policy_2.current == [] - - name: delete tenant - cleanup before ending tests + - name: Delete tenant - cleanup before ending tests cisco.aci.aci_tenant: <<: *aci_tenant_present state: absent From a7c0d973706ed20c3fac18c3eba898045755ce32 Mon Sep 17 00:00:00 2001 From: samitab Date: Tue, 27 Feb 2024 08:06:39 +1000 Subject: [PATCH 3/3] [Ignore] Changed aliases for bd_child_modules. --- plugins/modules/aci_bd_to_netflow_monitor_policy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/aci_bd_to_netflow_monitor_policy.py b/plugins/modules/aci_bd_to_netflow_monitor_policy.py index 4bd51a7a3..5e79a072c 100644 --- a/plugins/modules/aci_bd_to_netflow_monitor_policy.py +++ b/plugins/modules/aci_bd_to_netflow_monitor_policy.py @@ -31,7 +31,7 @@ description: - The name of the Netflow Monitor Policy. type: str - aliases: [ name, policy, monitor_pol] + aliases: [ netflow_monitor, netflow_monitor_name, name ] filter_type: description: - Choice of filter type while setting NetFlow Monitor Policies. @@ -227,7 +227,7 @@ def main(): argument_spec.update(aci_annotation_spec()) argument_spec.update( bd=dict(type="str", aliases=["bd_name", "bridge_domain"]), # Not required for querying all objects - netflow_monitor_policy=dict(type="str", aliases=["name", "policy", "monitor_pol"]), # Not required for querying all objects + netflow_monitor_policy=dict(type="str", aliases=["netflow_monitor", "netflow_monitor_name", "name"]), # Not required for querying all objects filter_type=dict(type="str", choices=["ce", "ipv4", "ipv6", "unspecified"], aliases=["filter", "type"]), # Not required for querying all objects tenant=dict(type="str", aliases=["tenant_name"]), # Not required for querying all objects state=dict(type="str", default="present", choices=["absent", "present", "query"]),