From 1f6ad264e4e8af406e921e1f9a6e534b7eae77ab Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Thu, 23 Feb 2023 14:12:21 +0000 Subject: [PATCH 1/7] feat: Add IGMP interface policy module --- plugins/modules/aci_igmp_interface_policy.py | 367 ++++++++++++++++++ .../targets/aci_igmp_interface_policy/aliases | 2 + .../aci_igmp_interface_policy/tasks/main.yml | 215 ++++++++++ 3 files changed, 584 insertions(+) create mode 100644 plugins/modules/aci_igmp_interface_policy.py create mode 100644 tests/integration/targets/aci_igmp_interface_policy/aliases create mode 100644 tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml diff --git a/plugins/modules/aci_igmp_interface_policy.py b/plugins/modules/aci_igmp_interface_policy.py new file mode 100644 index 000000000..963e33ada --- /dev/null +++ b/plugins/modules/aci_igmp_interface_policy.py @@ -0,0 +1,367 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2023, Tim Cragg (@timcragg) +# 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_igmp_interface_policy +short_description: Manage IGMP Interface Policies (igmp:IfPol) +description: +- Manage IGMP Interface Policies on Cisco ACI fabrics. +options: + name: + description: + - The name of the IGMP Interface Policy + type: str + tenant: + description: + - Tenant to build the IGMP Interface Policy under. Defaults to common + type: str + default: common + description: + description: + - Description of the IGMP Interface Policy + type: str + group_timeout: + description: + - IGMP group timeout in seconds. APIC defaults to 260 + type: int + query_interval: + description: + - IGMP query interval in seconds. APIC defaults to 125 + type: int + query_response_interval: + description: + - IGMP query response interval in seconds. APIC defaults to 10 + type: int + last_member_count: + description: + - Last member query count. APIC defaults to 2 + type: int + last_member_response: + description: + - Last member response time in seconds. APIC defaults to 1 + type: int + startup_query_count: + description: + - Startup Query Count. APIC defaults to 2 + type: int + startup_query_interval: + description: + - Startup query interval in seconds. APIC defaults to 31 + type: int + querier_timeout: + description: + - Querier timeout in seconds. APIC defaults to 255 + type: int + robustness_variable: + description: + - Robustness factor. APIC defaults to 2 + type: int + igmp_version: + description: + - IGMP version to run. This defaults to v2 on the APIC + type: str + choices: [ v2, v3 ] + allow_v3_asm: + description: + - Enable the Allow v3 ASM option. Defaults to False on the APIC + - If this parameter is set, fast_leave and report_link_local_groups must also be set + type: bool + fast_leave: + description: + - Enable the Fast Leave option. Defaults to False on the APIC + - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set + type: bool + report_link_local_groups: + description: + - Enable the Report Link Local Groups option. Defaults to False on the APIC + - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set + type: bool + 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 + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(igmp:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ + +author: +- Tim Cragg (@timcragg) +""" + +EXAMPLES = r""" +- name: Add an IGMP Interface Policy + cisco.aci.aci_igmp_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + name: ans_igmp_intf_pol + query_interval: 200 + state: present + delegate_to: localhost + +- name: Query an IGMP Interface Policy + cisco.aci.aci_igmp_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + name: ans_igmp_intf_pol + state: query + delegate_to: localhost + +- name: Query all IGMP Interface Policies + cisco.aci.aci_igmp_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + +- name: Remove an IGMP Interface Policy + cisco.aci.aci_igmp_interface_policy: + host: apic + username: admin + password: SomeSecretPassword + name: ans_igmp_intf_pol + 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 + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type="str"), + tenant=dict(type="str", default="common"), + description=dict(type="str"), + group_timeout=dict(type="int"), + query_interval=dict(type="int"), + query_response_interval=dict(type="int"), + last_member_count=dict(type="int"), + last_member_response=dict(type="int"), + startup_query_count=dict(type="int"), + startup_query_interval=dict(type="int"), + querier_timeout=dict(type="int"), + robustness_variable=dict(type="int"), + igmp_version=dict(type="str", choices=["v2", "v3"]), + allow_v3_asm=dict(type="bool"), + fast_leave=dict(type="bool"), + report_link_local_groups=dict(type="bool"), + state=dict(type="str", default="present", choices=["absent", "present", "query"]), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "present", ["name"]], + ["state", "absent", ["name"]], + ], + required_together=[ + ["allow_v3_asm", "fast_leave", "report_link_local_groups"], + ], + ) + + aci = ACIModule(module) + + name = module.params.get("name") + tenant = module.params.get("tenant") + description = module.params.get("description") + group_timeout = module.params.get("group_timeout") + query_interval = module.params.get("query_interval") + query_response_interval = module.params.get("query_response_interval") + last_member_count = module.params.get("last_member_count") + last_member_response = module.params.get("last_member_response") + startup_query_count = module.params.get("startup_query_count") + startup_query_interval = module.params.get("startup_query_interval") + querier_timeout = module.params.get("querier_timeout") + robustness_variable = module.params.get("robustness_variable") + igmp_version = module.params.get("igmp_version") + allow_v3_asm = module.params.get("allow_v3_asm") + fast_leave = module.params.get("fast_leave") + report_link_local_groups = module.params.get("report_link_local_groups") + 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='igmpIfPol', + aci_rn='igmpIfPol-{0}'.format(name), + module_object=name, + target_filter={'name': name}, + ), + ) + aci.get_existing() + + if state == "present": + if allow_v3_asm is not None: + if_ctrl_list = [] + if allow_v3_asm: + if_ctrl_list.append("allow-v3-asm") + if fast_leave: + if_ctrl_list.append("fast-leave") + if report_link_local_groups: + if_ctrl_list.append("rep-ll") + if_ctrl = ",".join(if_ctrl_list) + else: + if_ctrl = None + + aci.payload( + aci_class="igmpIfPol", + class_config=dict( + name=name, + descr=description, + grpTimeout=group_timeout, + ifCtrl=if_ctrl, + lastMbrCnt=last_member_count, + lastMbrRespTime=last_member_response, + querierTimeout=querier_timeout, + queryIntvl=query_interval, + robustFac=robustness_variable, + rspIntvl=query_response_interval, + startQueryCnt=startup_query_count, + startQueryIntvl=startup_query_interval, + ver=igmp_version, + ), + ) + + aci.get_diff(aci_class="igmpIfPol") + aci.post_config() + + elif state == "absent": + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/aci_igmp_interface_policy/aliases b/tests/integration/targets/aci_igmp_interface_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_igmp_interface_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml new file mode 100644 index 000000000..f8d80b65c --- /dev/null +++ b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml @@ -0,0 +1,215 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Tim Cragg (@timcragg) + +# 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: '{{ aci_output_level | default("info") }}' + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + name: ansible_tenant + state: absent + +# CREATE IGMP INTERFACE POLICY +- name: Create the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + name: ansible_tenant + state: present + +- name: Create an IGMP interface policy (check mode) + cisco.aci.aci_igmp_interface_policy: &aci_igmp + <<: *aci_info + name: ansible_igmp_intf_policy + tenant: ansible_tenant + description: Test IGMP Interface Policy + group_timeout: 300 + query_interval: 100 + query_response_interval: 8 + last_member_count: 3 + last_member_response: 5 + startup_query_count: 3 + startup_query_interval: 5 + querier_timeout: 200 + robustness_variable: 3 + igmp_version: v3 + allow_v3_asm: true + fast_leave: true + report_link_local_groups: false + check_mode: yes + register: cm_create_igmp_intf_policy + +- name: Create an IGMP interface policy + cisco.aci.aci_igmp_interface_policy: + <<: *aci_igmp + register: nm_create_igmp_intf_policy + +- name: Create IGMP interface policy again to test idempotence + cisco.aci.aci_igmp_interface_policy: + <<: *aci_igmp + register: nm_create_igmp_intf_policy_again + +- name: Verify creation of IGMP interface policy + ansible.builtin.assert: + that: + - cm_create_igmp_intf_policy is changed + - nm_create_igmp_intf_policy is changed + - nm_create_igmp_intf_policy_again is not changed + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.dn == "uni/tn-ansible_tenant/igmpIfPol-ansible_igmp_intf_policy" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.descr == "Test IGMP Interface Policy" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.name == "ansible_igmp_intf_policy" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.grpTimeout == "300" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.queryIntvl == "100" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.rspIntvl == "8" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.lastMbrCnt == "3" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.lastMbrRespTime == "5" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.startQueryCnt == "3" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.startQueryIntvl == "5" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.querierTimeout == "200" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.robustFac == "3" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.ver == "v3" + - nm_create_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,fast-leave" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.dn == "uni/tn-ansible_tenant/igmpIfPol-ansible_igmp_intf_policy" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.descr == "Test IGMP Interface Policy" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.name == "ansible_igmp_intf_policy" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.grpTimeout == "300" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.queryIntvl == "100" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.rspIntvl == "8" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.lastMbrCnt == "3" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.lastMbrRespTime == "5" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.startQueryCnt == "3" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.startQueryIntvl == "5" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.querierTimeout == "200" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.robustFac == "3" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.ver == "v3" + - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,fast-leave" + +# UPDATE IGMP INTERFACE POLICY +- name: Update IGMP Interface Policy + cisco.aci.aci_igmp_interface_policy: + <<: *aci_igmp + description: Updated IGMP Interface Policy + group_timeout: 250 + query_interval: 150 + query_response_interval: 7 + last_member_count: 4 + last_member_response: 6 + startup_query_count: 4 + startup_query_interval: 6 + querier_timeout: 180 + robustness_variable: 5 + igmp_version: v2 + allow_v3_asm: true + fast_leave: false + report_link_local_groups: false + register: update_igmp_intf_policy + +- name: Update IGMP Interface Policy without ifCtrl options + cisco.aci.aci_igmp_interface_policy: + <<: *aci_info + name: ansible_igmp_intf_policy + tenant: ansible_tenant + igmp_version: v3 + register: update_igmp_no_ifctrl + +- name: Verify update of IGMP Interface Policy + ansible.builtin.assert: + that: + - update_igmp_intf_policy is changed + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.dn == "uni/tn-ansible_tenant/igmpIfPol-ansible_igmp_intf_policy" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.descr == "Updated IGMP Interface Policy" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.name == "ansible_igmp_intf_policy" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.grpTimeout == "250" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.queryIntvl == "150" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.rspIntvl == "7" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.lastMbrCnt == "4" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.lastMbrRespTime == "6" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.startQueryCnt == "4" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.startQueryIntvl == "6" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.querierTimeout == "180" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.robustFac == "5" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ver == "v2" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" + +- name: Verify an update without ifCtrl options present leaves existing ifCtrl in place + ansible.builtin.assert: + that: + - update_igmp_no_ifctrl is changed + - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ver == "v3" + - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" + +# QUERY IGMP INTERFACE POLICY +- name: Query an IGMP Interface Policy + cisco.aci.aci_igmp_interface_policy: + <<: *aci_igmp + state: query + register: query_one + +- name: Query all IGMP Interface Policies + cisco.aci.aci_igmp_interface_policy: + <<: *aci_info + state: query + register: query_all + +- name: Verify IGMP Interface Policy queries + ansible.builtin.assert: + that: + - query_one is not changed + - query_one.current.0.igmpIfPol.attributes.dn == "uni/tn-ansible_tenant/igmpIfPol-ansible_igmp_intf_policy" + - query_one.current.0.igmpIfPol.attributes.descr == "Updated IGMP Interface Policy" + - query_one.current.0.igmpIfPol.attributes.name == "ansible_igmp_intf_policy" + - query_one.current.0.igmpIfPol.attributes.grpTimeout == "250" + - query_one.current.0.igmpIfPol.attributes.queryIntvl == "150" + - query_one.current.0.igmpIfPol.attributes.rspIntvl == "7" + - query_one.current.0.igmpIfPol.attributes.lastMbrCnt == "4" + - query_one.current.0.igmpIfPol.attributes.lastMbrRespTime == "6" + - query_one.current.0.igmpIfPol.attributes.startQueryCnt == "4" + - query_one.current.0.igmpIfPol.attributes.startQueryIntvl == "6" + - query_one.current.0.igmpIfPol.attributes.querierTimeout == "180" + - query_one.current.0.igmpIfPol.attributes.robustFac == "5" + - query_one.current.0.igmpIfPol.attributes.ver == "v3" + - query_one.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" + - query_all is not changed + +# REMOVE IGMP INTERFACE POLICY +- name: Delete an IGMP Interface Policy + cisco.aci.aci_igmp_interface_policy: + <<: *aci_igmp + state: absent + register: delete + +- name: Delete IGMP Interface Policy again + cisco.aci.aci_igmp_interface_policy: + <<: *aci_igmp + state: absent + register: delete_again + +- name: Verify deletion of IGMP Interface Policy + ansible.builtin.assert: + that: + - delete is changed + - delete_again is not changed + - delete.current == [] + +# CLEAN UP +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + name: ansible_tenant + state: absent \ No newline at end of file From f33a3764b6874a9d711313fc9cbad831923892ff Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Thu, 23 Feb 2023 14:50:03 +0000 Subject: [PATCH 2/7] fix: Sanity fix --- plugins/modules/aci_igmp_interface_policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/aci_igmp_interface_policy.py b/plugins/modules/aci_igmp_interface_policy.py index 963e33ada..be1f935b5 100644 --- a/plugins/modules/aci_igmp_interface_policy.py +++ b/plugins/modules/aci_igmp_interface_policy.py @@ -334,7 +334,7 @@ def main(): if_ctrl = ",".join(if_ctrl_list) else: if_ctrl = None - + aci.payload( aci_class="igmpIfPol", class_config=dict( From d43ce272b308cbe40d4d906de283f194894f7095 Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Wed, 15 Mar 2023 15:54:57 +0000 Subject: [PATCH 3/7] fix: Update docs and tests --- plugins/modules/aci_igmp_interface_policy.py | 60 ++++++++++++------- .../aci_igmp_interface_policy/tasks/main.yml | 23 +++++++ 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/plugins/modules/aci_igmp_interface_policy.py b/plugins/modules/aci_igmp_interface_policy.py index be1f935b5..a04cd8dd4 100644 --- a/plugins/modules/aci_igmp_interface_policy.py +++ b/plugins/modules/aci_igmp_interface_policy.py @@ -19,72 +19,84 @@ options: name: description: - - The name of the IGMP Interface Policy + - The name of the IGMP Interface Policy. type: str tenant: description: - - Tenant to build the IGMP Interface Policy under. Defaults to common + - The tenant to build the IGMP Interface Policy under. type: str - default: common description: description: - - Description of the IGMP Interface Policy + - The description of the IGMP Interface Policy. type: str group_timeout: description: - - IGMP group timeout in seconds. APIC defaults to 260 + - The IGMP group timeout in seconds. + - The APIC defaults to 260 when unset during creation. type: int query_interval: description: - - IGMP query interval in seconds. APIC defaults to 125 + - The IGMP query interval in seconds. + - The APIC defaults to 125 when unset during creation. type: int query_response_interval: description: - - IGMP query response interval in seconds. APIC defaults to 10 + - The IGMP query response interval in seconds. + - The APIC defaults to 10 when unset during creation. type: int last_member_count: description: - - Last member query count. APIC defaults to 2 + - The last member query count. + - The APIC defaults to 2 when unset during creation. type: int last_member_response: description: - - Last member response time in seconds. APIC defaults to 1 + - The last member response time in seconds. + - The APIC defaults to 1 when unset during creation. type: int startup_query_count: description: - - Startup Query Count. APIC defaults to 2 + - The Startup Query Count. + - The APIC defaults to 2 when unset during creation. type: int startup_query_interval: description: - - Startup query interval in seconds. APIC defaults to 31 + - The startup query interval in seconds. + - The APIC defaults to 31 when unset during creation. type: int querier_timeout: description: - - Querier timeout in seconds. APIC defaults to 255 + - The querier timeout in seconds. + - The APIC defaults to 255 when unset during creation. type: int robustness_variable: description: - - Robustness factor. APIC defaults to 2 + - The robustness factor. + - The APIC defaults to 2 when unset during creation. type: int igmp_version: description: - - IGMP version to run. This defaults to v2 on the APIC + - The IGMP version to run. + - The APIC defaults to v2 when unset during creation. type: str choices: [ v2, v3 ] allow_v3_asm: description: - - Enable the Allow v3 ASM option. Defaults to False on the APIC - - If this parameter is set, fast_leave and report_link_local_groups must also be set + - Enable the Allow v3 ASM option. + - The APIC defaults to False when unset during creation. + - If this parameter is set, fast_leave and report_link_local_groups must also be set. type: bool fast_leave: description: - - Enable the Fast Leave option. Defaults to False on the APIC - - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set + - Enable the Fast Leave option. + - The APIC defaults to False when unset during creation. + - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set. type: bool report_link_local_groups: description: - - Enable the Report Link Local Groups option. Defaults to False on the APIC - - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set + - Enable the Report Link Local Groups option. + - The APIC defaults to False when unset during creation. + - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set. type: bool state: description: @@ -95,6 +107,8 @@ default: present extends_documentation_fragment: - cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner seealso: - name: APIC Management Information Model reference @@ -249,14 +263,16 @@ """ from ansible.module_utils.basic import AnsibleModule -from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec def main(): argument_spec = aci_argument_spec() + argument_spec.update(aci_annotation_spec()) + argument_spec.update(aci_owner_spec()) argument_spec.update( name=dict(type="str"), - tenant=dict(type="str", default="common"), + tenant=dict(type="str"), description=dict(type="str"), group_timeout=dict(type="int"), query_interval=dict(type="int"), diff --git a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml index f8d80b65c..25d6d6b12 100644 --- a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml +++ b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml @@ -65,6 +65,13 @@ <<: *aci_igmp register: nm_create_igmp_intf_policy_again +- name: Create IGMP interface policy with default parameters + cisco.aci.aci_igmp_interface_policy: + <<: *aci_info + name: ansible_igmp_dflt_intf_policy + tenant: ansible_tenant + register: default_igmp_intf_policy + - name: Verify creation of IGMP interface policy ansible.builtin.assert: that: @@ -100,6 +107,21 @@ - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.ver == "v3" - nm_create_igmp_intf_policy_again.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,fast-leave" +- name: Verify default values + ansible.builtin.assert: + that: + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.grpTimeout == "260" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.queryIntvl == "125" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.rspIntvl == "10" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.lastMbrCnt == "2" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.lastMbrRespTime == "1" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.startQueryCnt == "2" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.startQueryIntvl == "31" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.querierTimeout == "255" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.robustFac == "2" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.ver == "v2" + - default_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "" + # UPDATE IGMP INTERFACE POLICY - name: Update IGMP Interface Policy cisco.aci.aci_igmp_interface_policy: @@ -186,6 +208,7 @@ - query_one.current.0.igmpIfPol.attributes.ver == "v3" - query_one.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" - query_all is not changed + - query_all.current | length > 1 # REMOVE IGMP INTERFACE POLICY - name: Delete an IGMP Interface Policy From 55c36b076592a257fbea3d1db21dd6cff9d6badc Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Wed, 15 Mar 2023 16:00:22 +0000 Subject: [PATCH 4/7] fix: Sanity fix --- plugins/modules/aci_igmp_interface_policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/aci_igmp_interface_policy.py b/plugins/modules/aci_igmp_interface_policy.py index a04cd8dd4..827cf9f8a 100644 --- a/plugins/modules/aci_igmp_interface_policy.py +++ b/plugins/modules/aci_igmp_interface_policy.py @@ -56,7 +56,7 @@ type: int startup_query_count: description: - - The Startup Query Count. + - The Startup Query Count. - The APIC defaults to 2 when unset during creation. type: int startup_query_interval: From bfb8518975a1ef20f961079b7e45b78d97bbd26e Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Fri, 17 Mar 2023 09:42:39 +0000 Subject: [PATCH 5/7] chore: Update tests and docs --- plugins/modules/aci_igmp_interface_policy.py | 8 ++++---- .../targets/aci_igmp_interface_policy/tasks/main.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/modules/aci_igmp_interface_policy.py b/plugins/modules/aci_igmp_interface_policy.py index 827cf9f8a..7f537871a 100644 --- a/plugins/modules/aci_igmp_interface_policy.py +++ b/plugins/modules/aci_igmp_interface_policy.py @@ -96,7 +96,7 @@ description: - Enable the Report Link Local Groups option. - The APIC defaults to False when unset during creation. - - If this parameter is set, allow_v3_asm and report_link_local_groups must also be set. + - If this parameter is set, allow_v3_asm and fast_leave must also be set. type: bool state: description: @@ -330,10 +330,10 @@ def main(): target_filter={"name": tenant}, ), subclass_1=dict( - aci_class='igmpIfPol', - aci_rn='igmpIfPol-{0}'.format(name), + aci_class="igmpIfPol", + aci_rn="igmpIfPol-{0}".format(name), module_object=name, - target_filter={'name': name}, + target_filter={"name": name}, ), ) aci.get_existing() diff --git a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml index 25d6d6b12..92df580a9 100644 --- a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml +++ b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml @@ -139,7 +139,7 @@ igmp_version: v2 allow_v3_asm: true fast_leave: false - report_link_local_groups: false + report_link_local_groups: true register: update_igmp_intf_policy - name: Update IGMP Interface Policy without ifCtrl options @@ -167,14 +167,14 @@ - update_igmp_intf_policy.current.0.igmpIfPol.attributes.querierTimeout == "180" - update_igmp_intf_policy.current.0.igmpIfPol.attributes.robustFac == "5" - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ver == "v2" - - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,rep-ll" - name: Verify an update without ifCtrl options present leaves existing ifCtrl in place ansible.builtin.assert: that: - update_igmp_no_ifctrl is changed - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ver == "v3" - - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" + - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,rep-ll" # QUERY IGMP INTERFACE POLICY - name: Query an IGMP Interface Policy @@ -206,7 +206,7 @@ - query_one.current.0.igmpIfPol.attributes.querierTimeout == "180" - query_one.current.0.igmpIfPol.attributes.robustFac == "5" - query_one.current.0.igmpIfPol.attributes.ver == "v3" - - query_one.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm" + - query_one.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,rep-ll" - query_all is not changed - query_all.current | length > 1 From 404992f82f0a43a034eedb679732b3104d65a3ec Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Fri, 17 Mar 2023 11:08:59 +0000 Subject: [PATCH 6/7] chore: fixes --- .../integration/targets/aci_igmp_interface_policy/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml index 92df580a9..65b6a17a2 100644 --- a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml +++ b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml @@ -12,6 +12,7 @@ set_fact: aci_info: &aci_info host: "{{ aci_hostname }}" + port: "{{ aci_port | default(omit) }}" username: "{{ aci_username }}" password: "{{ aci_password }}" validate_certs: '{{ aci_validate_certs | default(false) }}' From 1338d466d9415e921f4f952aa6165c9a0cd6d74c Mon Sep 17 00:00:00 2001 From: "tcragg@cisco.com" Date: Mon, 3 Apr 2023 14:50:06 +0100 Subject: [PATCH 7/7] fix: update integration test --- .../targets/aci_igmp_interface_policy/tasks/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml index 65b6a17a2..eac9daf6b 100644 --- a/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml +++ b/tests/integration/targets/aci_igmp_interface_policy/tasks/main.yml @@ -138,7 +138,7 @@ querier_timeout: 180 robustness_variable: 5 igmp_version: v2 - allow_v3_asm: true + allow_v3_asm: false fast_leave: false report_link_local_groups: true register: update_igmp_intf_policy @@ -168,14 +168,14 @@ - update_igmp_intf_policy.current.0.igmpIfPol.attributes.querierTimeout == "180" - update_igmp_intf_policy.current.0.igmpIfPol.attributes.robustFac == "5" - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ver == "v2" - - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,rep-ll" + - update_igmp_intf_policy.current.0.igmpIfPol.attributes.ifCtrl == "rep-ll" - name: Verify an update without ifCtrl options present leaves existing ifCtrl in place ansible.builtin.assert: that: - update_igmp_no_ifctrl is changed - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ver == "v3" - - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,rep-ll" + - update_igmp_no_ifctrl.current.0.igmpIfPol.attributes.ifCtrl == "rep-ll" # QUERY IGMP INTERFACE POLICY - name: Query an IGMP Interface Policy @@ -207,7 +207,7 @@ - query_one.current.0.igmpIfPol.attributes.querierTimeout == "180" - query_one.current.0.igmpIfPol.attributes.robustFac == "5" - query_one.current.0.igmpIfPol.attributes.ver == "v3" - - query_one.current.0.igmpIfPol.attributes.ifCtrl == "allow-v3-asm,rep-ll" + - query_one.current.0.igmpIfPol.attributes.ifCtrl == "rep-ll" - query_all is not changed - query_all.current | length > 1