From 4c70cc36be118baa7fcc575bb0966a6fde5c3638 Mon Sep 17 00:00:00 2001 From: devsinh Date: Tue, 20 May 2025 15:14:40 -0700 Subject: [PATCH 01/14] [minor_change] Added support for description to aci_syslog_group module. --- plugins/modules/aci_syslog_group.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/modules/aci_syslog_group.py b/plugins/modules/aci_syslog_group.py index 205c3593b..4831b7a23 100644 --- a/plugins/modules/aci_syslog_group.py +++ b/plugins/modules/aci_syslog_group.py @@ -59,6 +59,11 @@ - Name of the syslog group type: str aliases: [ syslog_group, syslog_group_name ] + description: + description: + - Description for the syslog group. + type: str + aliases: [ descr ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -257,6 +262,7 @@ def main(): include_ms=dict(type="bool"), include_time_zone=dict(type="bool"), state=dict(type="str", default="present", choices=["absent", "present", "query"]), + description=dict(type="str", aliases=["descr"]), ) module = AnsibleModule( @@ -280,6 +286,7 @@ def main(): include_ms = aci.boolean(module.params.get("include_ms")) include_time_zone = aci.boolean(module.params.get("include_time_zone")) state = module.params.get("state") + description = module.params.get("description") aci.construct_url( root_class=dict( @@ -297,6 +304,7 @@ def main(): class_config = dict( name=name, format=format, + descr=description, includeMilliSeconds=include_ms, ) if include_time_zone is not None: From 1551ff6428d8a755bf9e8ec33e9417a330dfb485 Mon Sep 17 00:00:00 2001 From: devsinh Date: Wed, 21 May 2025 15:33:32 -0700 Subject: [PATCH 02/14] [ignore] Updated Test file for aci_syslog_group --- plugins/modules/aci_syslog_group.py | 3 + .../targets/aci_syslog_group/tasks/main.yml | 76 +++++++++++++++++-- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/plugins/modules/aci_syslog_group.py b/plugins/modules/aci_syslog_group.py index 4831b7a23..c6d702545 100644 --- a/plugins/modules/aci_syslog_group.py +++ b/plugins/modules/aci_syslog_group.py @@ -1,6 +1,8 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2021, Tim Cragg (@timcragg) +# Copyright: (c) 2025, Dev Sinha (@DevSinha13) # 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 @@ -81,6 +83,7 @@ link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Tim Cragg (@timcragg) +- Dev Sinha (@DevSinha13) """ EXAMPLES = r""" diff --git a/tests/integration/targets/aci_syslog_group/tasks/main.yml b/tests/integration/targets/aci_syslog_group/tasks/main.yml index 34a2ddf63..0eee95c11 100644 --- a/tests/integration/targets/aci_syslog_group/tasks/main.yml +++ b/tests/integration/targets/aci_syslog_group/tasks/main.yml @@ -1,5 +1,6 @@ # Test code for the ACI modules # Copyright: (c) 2021, Tim Cragg (@timcragg) +# Copyright: (c) 2025, Dev Sinha (@DevSinha13) # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -34,8 +35,8 @@ name: ansible_syslog_group state: absent -# ADD syslog group -- name: Add syslog group (version >= 4) +# ADD syslog group(Check mode) +- name: Add syslog group (version >= 4) - (Check mode) cisco.aci.aci_syslog_group: &aci_syslog_present <<: *aci_info name: ansible_syslog_group @@ -47,11 +48,20 @@ console_log_severity: critical include_ms: true include_time_zone: true + description: Description for the syslog group state: present + check_mode: true + register: add_syslog_group_cm + when: version.current.0.topSystem.attributes.version is version('4', '>=') + +#ADD syslog group +- name: Add syslog group (version >= 4) - (No check mode) + cisco.aci.aci_syslog_group: + <<: *aci_syslog_present register: add_syslog_group when: version.current.0.topSystem.attributes.version is version('4', '>=') -- name: Add syslog group (version < 4) +- name: Add syslog group (version < 4) - (Check mode) cisco.aci.aci_syslog_group: &aci_syslog_present_32 <<: *aci_info name: ansible_syslog_group @@ -62,29 +72,68 @@ console_logging: enabled console_log_severity: critical include_ms: true + description: Description for the syslog group state: present + check_mode: true + register: add_syslog_group_32_cm + when: version.current.0.topSystem.attributes.version is version('4', '<') + +- name: Add syslog group (version < 4) - No Check mode + cisco.aci.aci_syslog_group: + <<: *aci_syslog_present_32 register: add_syslog_group_32 when: version.current.0.topSystem.attributes.version is version('4', '<') + +- name: Verify that ansible_syslog_group has been created with correct attributes in check mode(version >= 4) + ansible.builtin.assert: + that: + - add_syslog_group_cm is changed + - add_syslog_group_cm.proposed.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" + - add_syslog_group_cm.proposed.syslogGroup.attributes.name == "ansible_syslog_group" + - add_syslog_group_cm.proposed.syslogGroup.attributes.format == "aci" + - add_syslog_group_cm.proposed.syslogGroup.attributes.includeMilliSeconds == "yes" + - add_syslog_group_cm.proposed.syslogGroup.attributes.includeTimeZone == "yes" + - add_syslog_group_cm.proposed.syslogGroup.attributes.annotation == 'orchestrator:ansible' + - add_syslog_group_cm.proposed.syslogGroup.attributes.descr == 'Description for the syslog group' + when: version.current.0.topSystem.attributes.version is version('4', '>=') + + - name: Verify that ansible_syslog_group has been created with correct attributes (version > 4) ansible.builtin.assert: that: + - add_syslog_group is changed - add_syslog_group.current.0.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - add_syslog_group.current.0.syslogGroup.attributes.name == "ansible_syslog_group" - add_syslog_group.current.0.syslogGroup.attributes.format == "aci" - add_syslog_group.current.0.syslogGroup.attributes.includeMilliSeconds == "yes" - add_syslog_group.current.0.syslogGroup.attributes.includeTimeZone == "yes" - add_syslog_group.current.0.syslogGroup.attributes.annotation == 'orchestrator:ansible' + - add_syslog_group.current.0.syslogGroup.attributes.descr == 'Description for the syslog group' when: version.current.0.topSystem.attributes.version is version('4', '>=') +- name: Verify that ansible_syslog_group has been created with correct attributes in check mode (version < 4) + ansible.builtin.assert: + that: + - add_syslog_group_32_cm is changed + - add_syslog_group_32_cm.proposed.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" + - add_syslog_group_32_cm.proposed.syslogGroup.attributes.name == "ansible_syslog_group" + - add_syslog_group_32_cm.proposed.syslogGroup.attributes.format == "aci" + - add_syslog_group_32_cm.proposed.syslogGroup.attributes.includeMilliSeconds == "yes" + - add_syslog_group_32_cm.proposed.syslogGroup.attributes.annotation == 'orchestrator:ansible' + - add_syslog_group_32_cm.proposed.syslogGroup.attributes.descr == 'Description for the syslog group' + when: version.current.0.topSystem.attributes.version is version('4', '<') + - name: Verify that ansible_syslog_group has been created with correct attributes (version < 4) ansible.builtin.assert: that: + - add_syslog_group_32 is changed - add_syslog_group_32.current.0.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - add_syslog_group_32.current.0.syslogGroup.attributes.name == "ansible_syslog_group" - add_syslog_group_32.current.0.syslogGroup.attributes.format == "aci" - add_syslog_group_32.current.0.syslogGroup.attributes.includeMilliSeconds == "yes" - add_syslog_group_32.current.0.syslogGroup.attributes.annotation == 'orchestrator:ansible' + - add_syslog_group_32.current.0.syslogGroup.attributes.descr == 'Description for the syslog group' when: version.current.0.topSystem.attributes.version is version('4', '<') - name: Verify that ansible_syslog_group children have correct attributes (version >= 4) @@ -145,6 +194,7 @@ console_log_severity: emergencies include_ms: false include_time_zone: false + description: Updated syslog group state: present register: update_syslog_group when: version.current.0.topSystem.attributes.version is version('4', '>=') @@ -160,6 +210,7 @@ console_logging: disabled console_log_severity: emergencies include_ms: false + description: Updated syslog_group_32 state: present register: update_syslog_group_32 when: version.current.0.topSystem.attributes.version is version('4', '<') @@ -172,6 +223,7 @@ - update_syslog_group.current.0.syslogGroup.attributes.format == "nxos" - update_syslog_group.current.0.syslogGroup.attributes.includeMilliSeconds == "no" - update_syslog_group.current.0.syslogGroup.attributes.includeTimeZone == "no" + - update_syslog_group.current.0.syslogGroup.attributes.descr == "Updated syslog group" when: version.current.0.topSystem.attributes.version is version('4', '>=') - name: Verify that ansible_syslog_group has been updated with correct attributes (version < 4) @@ -181,6 +233,7 @@ - update_syslog_group_32.current.0.syslogGroup.attributes.name == "ansible_syslog_group" - update_syslog_group_32.current.0.syslogGroup.attributes.format == "nxos" - update_syslog_group_32.current.0.syslogGroup.attributes.includeMilliSeconds == "no" + - update_syslog_group_32.current.0.syslogGroup.attributes.descr == "Updated syslog_group_32" when: version.current.0.topSystem.attributes.version is version('4', '<') - name: Verify that ansible_syslog_group children have correct attributes (version >= 4) @@ -229,8 +282,17 @@ that: - query_syslog_group_all is not changed -# DELETE syslog group -- name: Remove the syslog group +# DELETE syslog group(check mode) +- name: Remove the syslog group (check mode) + cisco.aci.aci_syslog_group: + <<: *aci_info + name: ansible_syslog_group + state: absent + check_mode: true + register: remove_syslog_group_cm + +# Delete syslog group +- name: Remove the syslog group cisco.aci.aci_syslog_group: <<: *aci_info name: ansible_syslog_group @@ -240,6 +302,10 @@ - name: Verify remove_syslog_group ansible.builtin.assert: that: + - remove_syslog_group_cm is changed + - remove_syslog_group_cm.proposed == {} + - remove_syslog_group_cm.previous == remove_syslog_group.previous + - remove_syslog_group.current == [] - remove_syslog_group is changed - remove_syslog_group.previous.0.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - remove_syslog_group.previous.0.syslogGroup.attributes.name == "ansible_syslog_group" From 29c003ddd1b6989fd524ab6bef2af1331bda455a Mon Sep 17 00:00:00 2001 From: devsinh Date: Tue, 27 May 2025 10:51:41 -0700 Subject: [PATCH 03/14] Missing explaination but tests are passing now. --- plugins/module_utils/aci.py | 4 +- .../modules/aci_vmm_enhanced_lag_policy.py | 210 ++++++++++++++++ tests/integration/inventory.networking | 12 +- .../aci_vmm_enhanced_lag_policy/aliases | 2 + .../tasks/main.yml | 238 ++++++++++++++++++ 5 files changed, 458 insertions(+), 8 deletions(-) create mode 100644 plugins/modules/aci_vmm_enhanced_lag_policy.py create mode 100644 tests/integration/targets/aci_vmm_enhanced_lag_policy/aliases create mode 100644 tests/integration/targets/aci_vmm_enhanced_lag_policy/tasks/main.yml diff --git a/plugins/module_utils/aci.py b/plugins/module_utils/aci.py index 21740e9bb..929b04a62 100644 --- a/plugins/module_utils/aci.py +++ b/plugins/module_utils/aci.py @@ -162,9 +162,9 @@ def aci_owner_spec(): ) -def enhanced_lag_spec(): +def enhanced_lag_spec(name_is_required=True): return dict( - name=dict(type="str", required=True), + name=dict(type="str", required=name_is_required), lacp_mode=dict(type="str", choices=["active", "passive"]), load_balancing_mode=dict( type="str", diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py new file mode 100644 index 000000000..205316a09 --- /dev/null +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -0,0 +1,210 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +# TODO in the documentation section mention the default values for lacp_mode, load_balancing_mode, number_uplinks +ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} + +DOCUMENTATION = r""" +--- +module: aci_vmm_enhanced_lag_policy +short_description: Manage Enhanced LACP Policy for Virtual Machine Manager (VMM) in Cisco ACI +description: +- Manage Enhanced LACP Policy (lacpEnhancedLagPol) for VMM domains on Cisco ACI fabrics. +- The Enhanced LACP Policy allows you to configure advanced Link Aggregation Control Protocol (LACP) settings for virtual switches in VMM domains. +- This policy is a child of the C(vmmVSwitchPolicyCont) class. + +options: + name: + description: + - The name of the Enhanced LACP Policy. + type: str + required: true + domain: + description: + - The name of the virtual domain profile where the Enhanced LACP Policy is applied. + type: str + required: true + aliases: [ domain_name, domain_profile ] + vm_provider: + description: + - The virtualization platform provider for the VMM domain. + type: str + required: true + lacp_mode: + description: + - The LACP mode for the policy. + - Determines whether the policy initiates or responds to LACP negotiations. + type: str + choices: [ active, passive ] + default: active + load_balancing_mode: + description: + - The load balancing algorithm for distributing traffic across links in the port channel. + - See the APIC Management Information Model reference for more details. + type: str + choices: + - dst-ip + - dst-ip-l4port + - dst-ip-vlan + - dst-ip-l4port-vlan + - dst-mac + - dst-l4port + - src-ip + - src-ip-l4port + - src-ip-vlan + - src-ip-l4port-vlan + - src-mac + - src-l4port + - src-dst-ip + - src-dst-ip-l4port + - src-dst-ip-vlan + - src-dst-ip-l4port-vlan + - src-dst-mac + - src-dst-l4port + - src-port-id + - vlan + default: src-dst-ip + number_uplinks: + description: + - The minimum number of uplinks required for the port channel. + - Must be a value between 2 and 8. + type: int + default: 2 + state: + description: + - The desired state of the Enhanced LACP Policy. + - Use C(present) to create or update the policy. + - Use C(absent) to delete the policy. + - Use C(query) to retrieve information about the policy. + type: str + choices: [ absent, present, query ] + default: present + +extends_documentation_fragment: +- cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner + +seealso: +- module: cisco.aci.aci_domain +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(lacp:EnhancedLagPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dev Sinha (@DevSinha13) +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ( + ACIModule, + aci_argument_spec, + enhanced_lag_spec, + netflow_spec, +) +from ansible_collections.cisco.aci.plugins.module_utils.aci import ( + aci_annotation_spec, + aci_owner_spec, +) + +VM_PROVIDER_MAPPING = dict( + cloudfoundry="CloudFoundry", + kubernetes="Kubernetes", + microsoft="Microsoft", + openshift="OpenShift", + openstack="OpenStack", + redhat="Redhat", + vmware="VMware", +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update(aci_annotation_spec()) + argument_spec.update(aci_owner_spec()) + argument_spec.update( + #FIXME The problem could be that the argument is not recognized but if that is the case then how is the function not throwing an error. + #1.)Try keeping the original function and changing the value here to false + #2.)Dont unpack the dictionary + #3.)Do what was done in vmm_vswitch_policy + **enhanced_lag_spec(name_is_required=False), + domain=dict(type="str", aliases=["domain_name", "domain_profile"]), + state=dict(type="str", default="present", choices=["absent", "present", "query"]), + vm_provider=dict(type="str", choices=list(VM_PROVIDER_MAPPING.keys())), + # TODO Ensure that number of uplinks is added adequately + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "absent", ["name", "domain", "vm_provider"]], + ["state", "present", ["name", "domain", "vm_provider"]], + ], + ) + + name = module.params.get("name") + lacp_mode = module.params.get("lacp_mode") + load_balancing_mode = module.params.get("load_balancing_mode") + number_uplinks = module.params.get("number_uplinks") + domain = module.params.get("domain") + state = module.params.get("state") + vm_provider = module.params.get("vm_provider") + + aci = ACIModule(module) + + aci.construct_url( + root_class=dict( + aci_class="vmmProvP", + aci_rn="vmmp-{0}".format(VM_PROVIDER_MAPPING.get(vm_provider)), + module_object=vm_provider, + target_filter={"name": vm_provider}, + ), + subclass_1=dict( + aci_class="vmmDomP", + aci_rn="dom-{0}".format(domain), + module_object=domain, + target_filter={"name": domain}, + ), + subclass_2=dict( + aci_class="vmmVSwitchPolicyCont", + aci_rn="vswitchpolcont", + module_object="vswitchpolcont", + target_filter={"name": "vswitchpolcont"}, + ), + subclass_3=dict( + aci_class="lacpEnhancedLagPol", + aci_rn="enlacplagp-{0}".format(name), + module_object=name, + target_filter={"name": name}, + ), + ) + + aci.get_existing() + + if state == "present": + aci.payload( + aci_class="lacpEnhancedLagPol", + class_config=dict( + name=name, + mode=lacp_mode, + lbmode=load_balancing_mode, + numLinks=number_uplinks, + ), + ) + + aci.get_diff(aci_class="lacpEnhancedLagPol") + + aci.post_config() + + elif state == "absent": + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tests/integration/inventory.networking b/tests/integration/inventory.networking index a7831a03f..2caab8885 100644 --- a/tests/integration/inventory.networking +++ b/tests/integration/inventory.networking @@ -1,14 +1,14 @@ [aci] -cn-dmz-apic-m1-02-v42 ansible_host=173.36.219.68 aci_hostname=173.36.219.68 -cn-dmz-apic-m1-03-v52 ansible_host=173.36.219.69 aci_hostname=173.36.219.69 -cn-dmz-apic-m1-04-v602h ansible_host=173.36.219.70 aci_hostname=173.36.219.70 +#cn-dmz-apic-m1-02-v42 ansible_host=173.36.219.68 aci_hostname=173.36.219.68 +#cn-dmz-apic-m1-03-v52 ansible_host=173.36.219.69 aci_hostname=173.36.219.69 +cn-dmz-apic-m1-04-v602h ansible_host=173.36.219.73 aci_hostname=173.36.219.73 # aws_cloud ansible_host=52.52.20.121 aci_hostname=52.52.20.121 cloud_type=aws region=us-east-1 region_2=us-west-1 availability_zone=us-west-1a -azure_cloud ansible_host=20.245.236.136 aci_hostname=20.245.236.136 cloud_type=azure region=westus region_2=westus2 vnet_gateway=true az_region=westus2 +#azure_cloud ansible_host=20.245.236.136 aci_hostname=20.245.236.136 cloud_type=azure region=westus region_2=westus2 vnet_gateway=true az_region=westus2 [aci:vars] -aci_username=ansible_github_ci +aci_username=ansible_to_TF aci_remote_username="apic:test\\r_ansible_github_ci" -aci_password="sJ94G92#8dq2hx*K4qh" +aci_password="ansible_to_TF!" ansible_network_os=cisco.aci.aci ansible_connection=local ansible_python_interpreter=/usr/bin/python3.9 diff --git a/tests/integration/targets/aci_vmm_enhanced_lag_policy/aliases b/tests/integration/targets/aci_vmm_enhanced_lag_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_vmm_enhanced_lag_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_vmm_enhanced_lag_policy/tasks/main.yml b/tests/integration/targets/aci_vmm_enhanced_lag_policy/tasks/main.yml new file mode 100644 index 000000000..25fb5a858 --- /dev/null +++ b/tests/integration/targets/aci_vmm_enhanced_lag_policy/tasks/main.yml @@ -0,0 +1,238 @@ +# Test code for the ACI modules +# Copyright: (c) 2025, Dev Sinha (@DevSinha13) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# CLEAN ENVIRONMENT +- 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: '{{ aci_output_level | default("debug") }}' + +- name: Query system information + cisco.aci.aci_system: + <<: *aci_info + id: 1 + state: query + register: version + +# Remove VMM domain +- name: Remove VMM domain (normal mode) + cisco.aci.aci_domain: + <<: *aci_info + domain: test_vmm_dom + domain_type: vmm + vm_provider: vmware + state: absent + +- 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 skip execution for cloud sites + block: + # ADD DOMAIN + - name: Add VMM domain + cisco.aci.aci_domain: + <<: *aci_info + domain: test_vmm_dom + domain_type: vmm + vm_provider: vmware + state: present + + - name: Add a vSwitch policy to vmware domain + cisco.aci.aci_vmm_vswitch_policy: &add_vmware_policies + <<: *aci_info + domain: test_vmm_dom + vm_provider: vmware + lldp_policy: LLDP_policy + cdp_policy: CDP_policy + port_channel_policy: PORT_Channel_policy + state: present + + - name: Create Enhanced LAG policy in check mode + cisco.aci.aci_vmm_enhanced_lag_policy: &enhanced_lag_policy_info + <<: *aci_info + name: test_lag + domain: test_vmm_dom + vm_provider: vmware + lacp_mode: active + load_balancing_mode: src-dst-ip + number_uplinks: 2 + state: present + check_mode: true + register: create_enhanced_lag_policy_cm + + - name: Verify Enhanced LAG policy creation in check mode + ansible.builtin.assert: + that: + - create_enhanced_lag_policy_cm is changed + - create_enhanced_lag_policy_cm.previous == [] + - create_enhanced_lag_policy_cm.proposed.lacpEnhancedLagPol.attributes.name == "test_lag" + - create_enhanced_lag_policy_cm.proposed.lacpEnhancedLagPol.attributes.mode == "active" + - create_enhanced_lag_policy_cm.proposed.lacpEnhancedLagPol.attributes.lbmode == "src-dst-ip" + - create_enhanced_lag_policy_cm.proposed.lacpEnhancedLagPol.attributes.numLinks == "2" + - create_enhanced_lag_policy_cm.proposed.lacpEnhancedLagPol.attributes.dn == "uni/vmmp-VMware/dom-test_vmm_dom/vswitchpolcont/enlacplagp-test_lag" + + - name: Create enhanced lag policy without check mode + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *enhanced_lag_policy_info + register: create_enhanced_lag_policy + + - name: Verify Enhanced LAG policy creation + ansible.builtin.assert: + that: + - create_enhanced_lag_policy is changed + - create_enhanced_lag_policy.previous == [] + - create_enhanced_lag_policy.current.0.lacpEnhancedLagPol.attributes.name == 'test_lag' + - create_enhanced_lag_policy.current.0.lacpEnhancedLagPol.attributes.mode == 'active' + - create_enhanced_lag_policy.current.0.lacpEnhancedLagPol.attributes.lbmode == 'src-dst-ip' + - create_enhanced_lag_policy.current.0.lacpEnhancedLagPol.attributes.numLinks == '2' + - create_enhanced_lag_policy.current.0.lacpEnhancedLagPol.attributes.dn == 'uni/vmmp-VMware/dom-test_vmm_dom/vswitchpolcont/enlacplagp-test_lag' + + - name: Create Enhanced LAG policy again (idempotency) + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *enhanced_lag_policy_info + register: create_enhanced_lag_policy_again + + - name: Verify Enhanced LAG policy idempotency + ansible.builtin.assert: + that: + - create_enhanced_lag_policy_again is not changed + - create_enhanced_lag_policy_again.current == create_enhanced_lag_policy.current == create_enhanced_lag_policy_again.previous + + - name: Update Enhanced LAG policy with different options + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *aci_info + name: test_lag + domain: test_vmm_dom + vm_provider: vmware + lacp_mode: passive + load_balancing_mode: src-dst-ip-l4port + number_uplinks: 4 + state: present + register: update_enhanced_lag + + - name: Assert Enhanced LAG policy update + ansible.builtin.assert: + that: + - update_enhanced_lag is changed + - update_enhanced_lag.previous.0.lacpEnhancedLagPol.attributes.name == 'test_lag' + - update_enhanced_lag.previous.0.lacpEnhancedLagPol.attributes.mode == 'active' + - update_enhanced_lag.previous.0.lacpEnhancedLagPol.attributes.lbmode == 'src-dst-ip' + - update_enhanced_lag.previous.0.lacpEnhancedLagPol.attributes.numLinks == '2' + - update_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.name == 'test_lag' + - update_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.mode == 'passive' + - update_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.lbmode == 'src-dst-ip-l4port' + - update_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.numLinks == '4' + + - name: Create second Enhanced LAG policy + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *aci_info + name: test_lag2 + domain: test_vmm_dom + vm_provider: vmware + lacp_mode: active + load_balancing_mode: src-ip + number_uplinks: 3 + state: present + register: create_second_enhanced_lag + + - name: Assert second Enhanced LAG policy creation + ansible.builtin.assert: + that: + - create_second_enhanced_lag is changed + - create_second_enhanced_lag.previous == [] + - create_second_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.name == 'test_lag2' + - create_second_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.mode == 'active' + - create_second_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.lbmode == 'src-ip' + - create_second_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.numLinks == '3' + + - name: Query first Enhanced LAG policy + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *aci_info + name: test_lag + domain: test_vmm_dom + vm_provider: vmware + state: query + register: query_first_enhanced_lag + + - name: Verify first Enhanced LAG policy query + ansible.builtin.assert: + that: + - query_first_enhanced_lag is not changed + - query_first_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.name == 'test_lag' + - query_first_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.mode == 'passive' + - query_first_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.lbmode == 'src-dst-ip-l4port' + - query_first_enhanced_lag.current.0.lacpEnhancedLagPol.attributes.numLinks == '4' + + - name: Query all Enhanced LAG policies + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *aci_info + state: query + register: query_all_enhanced_lag + + - name: Verify Query all Lag policy + ansible.builtin.assert: + that: + - query_all_enhanced_lag.current | length >= 2 + - query_all_enhanced_lag is not changed + - "'uni/vmmp-VMware/dom-test_vmm_dom/vswitchpolcont/enlacplagp-test_lag' in query_all_enhanced_lag.current | map(attribute='lacpEnhancedLagPol.attributes.dn') | list" + - "'uni/vmmp-VMware/dom-test_vmm_dom/vswitchpolcont/enlacplagp-test_lag2' in query_all_enhanced_lag.current | map(attribute='lacpEnhancedLagPol.attributes.dn') | list" + + - name: Remove first Enhanced LAG policy in check mode + cisco.aci.aci_vmm_enhanced_lag_policy: &delete_enhanced_lag_policy + <<: *aci_info + name: test_lag + domain: test_vmm_dom + vm_provider: vmware + state: absent + check_mode: true + register: remove_first_enhanced_lag_check + + - name: Verify first Enhanced LAG policy removal in check mode + ansible.builtin.assert: + that: + - remove_first_enhanced_lag_check is changed + - remove_first_enhanced_lag_check.previous.0.lacpEnhancedLagPol.attributes.name == 'test_lag' + - remove_first_enhanced_lag_check.previous.0.lacpEnhancedLagPol.attributes.mode == 'passive' + - remove_first_enhanced_lag_check.previous.0.lacpEnhancedLagPol.attributes.lbmode == 'src-dst-ip-l4port' + - remove_first_enhanced_lag_check.previous.0.lacpEnhancedLagPol.attributes.numLinks == '4' + - remove_first_enhanced_lag_check.proposed == {} + + - name: Remove first Enhanced LAG policy + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *delete_enhanced_lag_policy + register: remove_first_enhanced_lag + + - name: Verify first Enhanced LAG policy removal + ansible.builtin.assert: + that: + - remove_first_enhanced_lag is changed + - remove_first_enhanced_lag.previous == remove_first_enhanced_lag_check.previous + - remove_first_enhanced_lag.current == [] + + - name: Remove first Enhanced LAG policy again (idempotency) + cisco.aci.aci_vmm_enhanced_lag_policy: + <<: *delete_enhanced_lag_policy + register: remove_first_enhanced_lag_again + + - name: Verify first Enhanced LAG policy removal idempotency + ansible.builtin.assert: + that: + - remove_first_enhanced_lag_again is not changed + - remove_first_enhanced_lag_again.current == remove_first_enhanced_lag_again.previous == [] + + - name: Remove VMM domain again (clean slate) + cisco.aci.aci_domain: + <<: *aci_info + domain: test_vmm_dom + domain_type: vmm + vm_provider: vmware + state: absent From 10d54805c40bd7031918b87660911f8054ea0d02 Mon Sep 17 00:00:00 2001 From: devsinh Date: Thu, 29 May 2025 13:34:39 -0700 Subject: [PATCH 04/14] Added black formatting and documentation. --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index 205316a09..6384d4cf3 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -126,10 +126,10 @@ def main(): argument_spec.update(aci_annotation_spec()) argument_spec.update(aci_owner_spec()) argument_spec.update( - #FIXME The problem could be that the argument is not recognized but if that is the case then how is the function not throwing an error. - #1.)Try keeping the original function and changing the value here to false - #2.)Dont unpack the dictionary - #3.)Do what was done in vmm_vswitch_policy + # FIXME The problem could be that the argument is not recognized but if that is the case then how is the function not throwing an error. + # 1.)Try keeping the original function and changing the value here to false + # 2.)Dont unpack the dictionary + # 3.)Do what was done in vmm_vswitch_policy **enhanced_lag_spec(name_is_required=False), domain=dict(type="str", aliases=["domain_name", "domain_profile"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), @@ -207,4 +207,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() From 6cd9f92d9a643aed6fc0ff05c2e7c4bff292b64a Mon Sep 17 00:00:00 2001 From: devsinh Date: Fri, 30 May 2025 12:28:13 -0700 Subject: [PATCH 05/14] [ignore] Fixed documentation and fixed sanity issues --- plugins/modules/aci_syslog_group.py | 11 -- .../modules/aci_vmm_enhanced_lag_policy.py | 160 ++++++++++++++++-- tests/integration/inventory.networking | 12 +- .../targets/aci_syslog_group/tasks/main.yml | 76 +-------- 4 files changed, 156 insertions(+), 103 deletions(-) diff --git a/plugins/modules/aci_syslog_group.py b/plugins/modules/aci_syslog_group.py index c6d702545..205c3593b 100644 --- a/plugins/modules/aci_syslog_group.py +++ b/plugins/modules/aci_syslog_group.py @@ -1,8 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Tim Cragg (@timcragg) -# Copyright: (c) 2025, Dev Sinha (@DevSinha13) # 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 @@ -61,11 +59,6 @@ - Name of the syslog group type: str aliases: [ syslog_group, syslog_group_name ] - description: - description: - - Description for the syslog group. - type: str - aliases: [ descr ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -83,7 +76,6 @@ link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Tim Cragg (@timcragg) -- Dev Sinha (@DevSinha13) """ EXAMPLES = r""" @@ -265,7 +257,6 @@ def main(): include_ms=dict(type="bool"), include_time_zone=dict(type="bool"), state=dict(type="str", default="present", choices=["absent", "present", "query"]), - description=dict(type="str", aliases=["descr"]), ) module = AnsibleModule( @@ -289,7 +280,6 @@ def main(): include_ms = aci.boolean(module.params.get("include_ms")) include_time_zone = aci.boolean(module.params.get("include_time_zone")) state = module.params.get("state") - description = module.params.get("description") aci.construct_url( root_class=dict( @@ -307,7 +297,6 @@ def main(): class_config = dict( name=name, format=format, - descr=description, includeMilliSeconds=include_ms, ) if include_time_zone is not None: diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index 6384d4cf3..061e5152b 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -1,11 +1,12 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2025, Dev Sinha (@DevSinha13) +# 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 -# TODO in the documentation section mention the default values for lacp_mode, load_balancing_mode, number_uplinks ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} DOCUMENTATION = r""" @@ -22,25 +23,22 @@ description: - The name of the Enhanced LACP Policy. type: str - required: true domain: description: - The name of the virtual domain profile where the Enhanced LACP Policy is applied. type: str - required: true aliases: [ domain_name, domain_profile ] vm_provider: description: - The virtualization platform provider for the VMM domain. type: str - required: true + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] lacp_mode: description: - The LACP mode for the policy. - Determines whether the policy initiates or responds to LACP negotiations. type: str choices: [ active, passive ] - default: active load_balancing_mode: description: - The load balancing algorithm for distributing traffic across links in the port channel. @@ -67,13 +65,11 @@ - src-dst-l4port - src-port-id - vlan - default: src-dst-ip number_uplinks: description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. type: int - default: 2 state: description: - The desired state of the Enhanced LACP Policy. @@ -83,7 +79,6 @@ type: str choices: [ absent, present, query ] default: present - extends_documentation_fragment: - cisco.aci.aci - cisco.aci.annotation @@ -98,12 +93,152 @@ - Dev Sinha (@DevSinha13) """ +EXAMPLES = r""" +- name: Create an Enhanced LACP Policy + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + lacp_mode: active + load_balancing_mode: src-dst-ip + number_uplinks: 4 + state: present + +- name: Simulate creation of an Enhanced LACP Policy (Check Mode) + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + lacp_mode: active + load_balancing_mode: src-dst-ip + number_uplinks: 4 + state: present + check_mode: true + +- name: Update an existing Enhanced LACP Policy + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + lacp_mode: passive + load_balancing_mode: src-dst-ip-l4port + number_uplinks: 6 + state: present + +- name: Query a specific Enhanced LACP Policy + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + state: query + register: query_result + +- name: Query all Enhanced LACP Policies in a VMM domain + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + domain: my_vmm_domain + vm_provider: vmware + state: query + register: query_all_result + +- name: Ensure idempotency when creating an Enhanced LACP Policy + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + lacp_mode: active + load_balancing_mode: src-dst-ip + number_uplinks: 4 + state: present + +- name: Delete an Enhanced LACP Policy + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + state: absent + +- name: Simulate deletion of an Enhanced LACP Policy (Check Mode) + cisco.aci.aci_vmm_enhanced_lag_policy: + host: apic.example.com + username: admin + password: SomeSecretPassword + name: my_enhanced_lag_policy + domain: my_vmm_domain + vm_provider: vmware + state: absent + check_mode: true +""" +RETURN = r""" +current: + description: The existing configuration of the Enhanced LACP Policy from the APIC after the module has finished. + returned: success + type: list + sample: + [ + { + "lacpEnhancedLagPol": { + "attributes": { + "name": "test_enhanced_lag_policy", + "mode": "active", + "lbmode": "src-dst-ip", + "numLinks": "4", + "dn": "uni/vmmp-VMware/dom-test_vmm_dom/vswitchpolcont/enlacplagp-test_enhanced_lag_policy" + } + } + } + ] +error: + description: The error information as returned from the APIC. + returned: failure + type: dict + sample: + { + "code": "801", + "text": "property name of enlacplagp-test_enhanced_lag_policy failed validation" + } +proposed: + description: The configuration sent to the APIC. + returned: info + type: dict + sample: + { + "lacpEnhancedLagPol": { + "attributes": { + "name": "test_enhanced_lag_policy", + "mode": "active", + "lbmode": "src-dst-ip", + "numLinks": "4" + } + } + } +""" + from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.aci.plugins.module_utils.aci import ( ACIModule, aci_argument_spec, enhanced_lag_spec, - netflow_spec, ) from ansible_collections.cisco.aci.plugins.module_utils.aci import ( aci_annotation_spec, @@ -125,16 +260,11 @@ def main(): argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) argument_spec.update(aci_owner_spec()) + argument_spec.update(enhanced_lag_spec(name_is_required=False)) argument_spec.update( - # FIXME The problem could be that the argument is not recognized but if that is the case then how is the function not throwing an error. - # 1.)Try keeping the original function and changing the value here to false - # 2.)Dont unpack the dictionary - # 3.)Do what was done in vmm_vswitch_policy - **enhanced_lag_spec(name_is_required=False), domain=dict(type="str", aliases=["domain_name", "domain_profile"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), vm_provider=dict(type="str", choices=list(VM_PROVIDER_MAPPING.keys())), - # TODO Ensure that number of uplinks is added adequately ) module = AnsibleModule( diff --git a/tests/integration/inventory.networking b/tests/integration/inventory.networking index 2caab8885..a7831a03f 100644 --- a/tests/integration/inventory.networking +++ b/tests/integration/inventory.networking @@ -1,14 +1,14 @@ [aci] -#cn-dmz-apic-m1-02-v42 ansible_host=173.36.219.68 aci_hostname=173.36.219.68 -#cn-dmz-apic-m1-03-v52 ansible_host=173.36.219.69 aci_hostname=173.36.219.69 -cn-dmz-apic-m1-04-v602h ansible_host=173.36.219.73 aci_hostname=173.36.219.73 +cn-dmz-apic-m1-02-v42 ansible_host=173.36.219.68 aci_hostname=173.36.219.68 +cn-dmz-apic-m1-03-v52 ansible_host=173.36.219.69 aci_hostname=173.36.219.69 +cn-dmz-apic-m1-04-v602h ansible_host=173.36.219.70 aci_hostname=173.36.219.70 # aws_cloud ansible_host=52.52.20.121 aci_hostname=52.52.20.121 cloud_type=aws region=us-east-1 region_2=us-west-1 availability_zone=us-west-1a -#azure_cloud ansible_host=20.245.236.136 aci_hostname=20.245.236.136 cloud_type=azure region=westus region_2=westus2 vnet_gateway=true az_region=westus2 +azure_cloud ansible_host=20.245.236.136 aci_hostname=20.245.236.136 cloud_type=azure region=westus region_2=westus2 vnet_gateway=true az_region=westus2 [aci:vars] -aci_username=ansible_to_TF +aci_username=ansible_github_ci aci_remote_username="apic:test\\r_ansible_github_ci" -aci_password="ansible_to_TF!" +aci_password="sJ94G92#8dq2hx*K4qh" ansible_network_os=cisco.aci.aci ansible_connection=local ansible_python_interpreter=/usr/bin/python3.9 diff --git a/tests/integration/targets/aci_syslog_group/tasks/main.yml b/tests/integration/targets/aci_syslog_group/tasks/main.yml index 0eee95c11..34a2ddf63 100644 --- a/tests/integration/targets/aci_syslog_group/tasks/main.yml +++ b/tests/integration/targets/aci_syslog_group/tasks/main.yml @@ -1,6 +1,5 @@ # Test code for the ACI modules # Copyright: (c) 2021, Tim Cragg (@timcragg) -# Copyright: (c) 2025, Dev Sinha (@DevSinha13) # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -35,8 +34,8 @@ name: ansible_syslog_group state: absent -# ADD syslog group(Check mode) -- name: Add syslog group (version >= 4) - (Check mode) +# ADD syslog group +- name: Add syslog group (version >= 4) cisco.aci.aci_syslog_group: &aci_syslog_present <<: *aci_info name: ansible_syslog_group @@ -48,20 +47,11 @@ console_log_severity: critical include_ms: true include_time_zone: true - description: Description for the syslog group state: present - check_mode: true - register: add_syslog_group_cm - when: version.current.0.topSystem.attributes.version is version('4', '>=') - -#ADD syslog group -- name: Add syslog group (version >= 4) - (No check mode) - cisco.aci.aci_syslog_group: - <<: *aci_syslog_present register: add_syslog_group when: version.current.0.topSystem.attributes.version is version('4', '>=') -- name: Add syslog group (version < 4) - (Check mode) +- name: Add syslog group (version < 4) cisco.aci.aci_syslog_group: &aci_syslog_present_32 <<: *aci_info name: ansible_syslog_group @@ -72,68 +62,29 @@ console_logging: enabled console_log_severity: critical include_ms: true - description: Description for the syslog group state: present - check_mode: true - register: add_syslog_group_32_cm - when: version.current.0.topSystem.attributes.version is version('4', '<') - -- name: Add syslog group (version < 4) - No Check mode - cisco.aci.aci_syslog_group: - <<: *aci_syslog_present_32 register: add_syslog_group_32 when: version.current.0.topSystem.attributes.version is version('4', '<') - -- name: Verify that ansible_syslog_group has been created with correct attributes in check mode(version >= 4) - ansible.builtin.assert: - that: - - add_syslog_group_cm is changed - - add_syslog_group_cm.proposed.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - - add_syslog_group_cm.proposed.syslogGroup.attributes.name == "ansible_syslog_group" - - add_syslog_group_cm.proposed.syslogGroup.attributes.format == "aci" - - add_syslog_group_cm.proposed.syslogGroup.attributes.includeMilliSeconds == "yes" - - add_syslog_group_cm.proposed.syslogGroup.attributes.includeTimeZone == "yes" - - add_syslog_group_cm.proposed.syslogGroup.attributes.annotation == 'orchestrator:ansible' - - add_syslog_group_cm.proposed.syslogGroup.attributes.descr == 'Description for the syslog group' - when: version.current.0.topSystem.attributes.version is version('4', '>=') - - - name: Verify that ansible_syslog_group has been created with correct attributes (version > 4) ansible.builtin.assert: that: - - add_syslog_group is changed - add_syslog_group.current.0.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - add_syslog_group.current.0.syslogGroup.attributes.name == "ansible_syslog_group" - add_syslog_group.current.0.syslogGroup.attributes.format == "aci" - add_syslog_group.current.0.syslogGroup.attributes.includeMilliSeconds == "yes" - add_syslog_group.current.0.syslogGroup.attributes.includeTimeZone == "yes" - add_syslog_group.current.0.syslogGroup.attributes.annotation == 'orchestrator:ansible' - - add_syslog_group.current.0.syslogGroup.attributes.descr == 'Description for the syslog group' when: version.current.0.topSystem.attributes.version is version('4', '>=') -- name: Verify that ansible_syslog_group has been created with correct attributes in check mode (version < 4) - ansible.builtin.assert: - that: - - add_syslog_group_32_cm is changed - - add_syslog_group_32_cm.proposed.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - - add_syslog_group_32_cm.proposed.syslogGroup.attributes.name == "ansible_syslog_group" - - add_syslog_group_32_cm.proposed.syslogGroup.attributes.format == "aci" - - add_syslog_group_32_cm.proposed.syslogGroup.attributes.includeMilliSeconds == "yes" - - add_syslog_group_32_cm.proposed.syslogGroup.attributes.annotation == 'orchestrator:ansible' - - add_syslog_group_32_cm.proposed.syslogGroup.attributes.descr == 'Description for the syslog group' - when: version.current.0.topSystem.attributes.version is version('4', '<') - - name: Verify that ansible_syslog_group has been created with correct attributes (version < 4) ansible.builtin.assert: that: - - add_syslog_group_32 is changed - add_syslog_group_32.current.0.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - add_syslog_group_32.current.0.syslogGroup.attributes.name == "ansible_syslog_group" - add_syslog_group_32.current.0.syslogGroup.attributes.format == "aci" - add_syslog_group_32.current.0.syslogGroup.attributes.includeMilliSeconds == "yes" - add_syslog_group_32.current.0.syslogGroup.attributes.annotation == 'orchestrator:ansible' - - add_syslog_group_32.current.0.syslogGroup.attributes.descr == 'Description for the syslog group' when: version.current.0.topSystem.attributes.version is version('4', '<') - name: Verify that ansible_syslog_group children have correct attributes (version >= 4) @@ -194,7 +145,6 @@ console_log_severity: emergencies include_ms: false include_time_zone: false - description: Updated syslog group state: present register: update_syslog_group when: version.current.0.topSystem.attributes.version is version('4', '>=') @@ -210,7 +160,6 @@ console_logging: disabled console_log_severity: emergencies include_ms: false - description: Updated syslog_group_32 state: present register: update_syslog_group_32 when: version.current.0.topSystem.attributes.version is version('4', '<') @@ -223,7 +172,6 @@ - update_syslog_group.current.0.syslogGroup.attributes.format == "nxos" - update_syslog_group.current.0.syslogGroup.attributes.includeMilliSeconds == "no" - update_syslog_group.current.0.syslogGroup.attributes.includeTimeZone == "no" - - update_syslog_group.current.0.syslogGroup.attributes.descr == "Updated syslog group" when: version.current.0.topSystem.attributes.version is version('4', '>=') - name: Verify that ansible_syslog_group has been updated with correct attributes (version < 4) @@ -233,7 +181,6 @@ - update_syslog_group_32.current.0.syslogGroup.attributes.name == "ansible_syslog_group" - update_syslog_group_32.current.0.syslogGroup.attributes.format == "nxos" - update_syslog_group_32.current.0.syslogGroup.attributes.includeMilliSeconds == "no" - - update_syslog_group_32.current.0.syslogGroup.attributes.descr == "Updated syslog_group_32" when: version.current.0.topSystem.attributes.version is version('4', '<') - name: Verify that ansible_syslog_group children have correct attributes (version >= 4) @@ -282,17 +229,8 @@ that: - query_syslog_group_all is not changed -# DELETE syslog group(check mode) -- name: Remove the syslog group (check mode) - cisco.aci.aci_syslog_group: - <<: *aci_info - name: ansible_syslog_group - state: absent - check_mode: true - register: remove_syslog_group_cm - -# Delete syslog group -- name: Remove the syslog group +# DELETE syslog group +- name: Remove the syslog group cisco.aci.aci_syslog_group: <<: *aci_info name: ansible_syslog_group @@ -302,10 +240,6 @@ - name: Verify remove_syslog_group ansible.builtin.assert: that: - - remove_syslog_group_cm is changed - - remove_syslog_group_cm.proposed == {} - - remove_syslog_group_cm.previous == remove_syslog_group.previous - - remove_syslog_group.current == [] - remove_syslog_group is changed - remove_syslog_group.previous.0.syslogGroup.attributes.dn == "uni/fabric/slgroup-ansible_syslog_group" - remove_syslog_group.previous.0.syslogGroup.attributes.name == "ansible_syslog_group" From 61a2709beb3effad7b92299b56ae627144bcea98 Mon Sep 17 00:00:00 2001 From: devsinh Date: Wed, 4 Jun 2025 10:28:01 -0700 Subject: [PATCH 06/14] [ignore] Fixed documentation and examples as well as imported VM_PROVIDER_MAPPING --- .../modules/aci_vmm_enhanced_lag_policy.py | 39 +++---------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index 061e5152b..4619add33 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -39,6 +39,7 @@ - Determines whether the policy initiates or responds to LACP negotiations. type: str choices: [ active, passive ] + default: active load_balancing_mode: description: - The load balancing algorithm for distributing traffic across links in the port channel. @@ -65,11 +66,13 @@ - src-dst-l4port - src-port-id - vlan + default: src-dst-ip number_uplinks: description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. type: int + default: 2 state: description: - The desired state of the Enhanced LACP Policy. @@ -155,19 +158,6 @@ state: query register: query_all_result -- name: Ensure idempotency when creating an Enhanced LACP Policy - cisco.aci.aci_vmm_enhanced_lag_policy: - host: apic.example.com - username: admin - password: SomeSecretPassword - name: my_enhanced_lag_policy - domain: my_vmm_domain - vm_provider: vmware - lacp_mode: active - load_balancing_mode: src-dst-ip - number_uplinks: 4 - state: present - - name: Delete an Enhanced LACP Policy cisco.aci.aci_vmm_enhanced_lag_policy: host: apic.example.com @@ -177,17 +167,6 @@ domain: my_vmm_domain vm_provider: vmware state: absent - -- name: Simulate deletion of an Enhanced LACP Policy (Check Mode) - cisco.aci.aci_vmm_enhanced_lag_policy: - host: apic.example.com - username: admin - password: SomeSecretPassword - name: my_enhanced_lag_policy - domain: my_vmm_domain - vm_provider: vmware - state: absent - check_mode: true """ RETURN = r""" current: @@ -245,14 +224,8 @@ aci_owner_spec, ) -VM_PROVIDER_MAPPING = dict( - cloudfoundry="CloudFoundry", - kubernetes="Kubernetes", - microsoft="Microsoft", - openshift="OpenShift", - openstack="OpenStack", - redhat="Redhat", - vmware="VMware", +from ansible_collections.cisco.aci.plugins.module_utils.constants import ( + VM_PROVIDER_MAPPING, ) @@ -291,7 +264,7 @@ def main(): aci_class="vmmProvP", aci_rn="vmmp-{0}".format(VM_PROVIDER_MAPPING.get(vm_provider)), module_object=vm_provider, - target_filter={"name": vm_provider}, + target_filter={"vendor": vm_provider}, ), subclass_1=dict( aci_class="vmmDomP", From 187af5086a8023c8a157c203a0ffcb8486ddc78d Mon Sep 17 00:00:00 2001 From: devsinh Date: Wed, 4 Jun 2025 10:41:38 -0700 Subject: [PATCH 07/14] [minor change] Removed the .keys() call from the VM_PROVIDER_MAPPING and replaced names with vendor in target_filter --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index 4619add33..d0595c4fe 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -12,9 +12,9 @@ DOCUMENTATION = r""" --- module: aci_vmm_enhanced_lag_policy -short_description: Manage Enhanced LACP Policy for Virtual Machine Manager (VMM) in Cisco ACI +short_description: Manage Enhanced LACP Policy for Virtual Machine Manager (VMM) in Cisco ACI (lacp:EnhancedLagPol) description: -- Manage Enhanced LACP Policy (lacpEnhancedLagPol) for VMM domains on Cisco ACI fabrics. +- Manage Enhanced LACP Policy for VMM domains on Cisco ACI fabrics. - The Enhanced LACP Policy allows you to configure advanced Link Aggregation Control Protocol (LACP) settings for virtual switches in VMM domains. - This policy is a child of the C(vmmVSwitchPolicyCont) class. @@ -237,7 +237,7 @@ def main(): argument_spec.update( domain=dict(type="str", aliases=["domain_name", "domain_profile"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), - vm_provider=dict(type="str", choices=list(VM_PROVIDER_MAPPING.keys())), + vm_provider=dict(type="str", choices=list(VM_PROVIDER_MAPPING)), ) module = AnsibleModule( From 146ad7f94ef748039dc74906fdb63b918cac0155 Mon Sep 17 00:00:00 2001 From: DevSinha13 <119488392+DevSinha13@users.noreply.github.com> Date: Wed, 4 Jun 2025 11:05:56 -0700 Subject: [PATCH 08/14] Update plugins/modules/aci_vmm_enhanced_lag_policy.py Co-authored-by: Akini Ross --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index d0595c4fe..82260337c 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -37,9 +37,9 @@ description: - The LACP mode for the policy. - Determines whether the policy initiates or responds to LACP negotiations. + - The APIC defaults to C(active) when unset during creation. type: str choices: [ active, passive ] - default: active load_balancing_mode: description: - The load balancing algorithm for distributing traffic across links in the port channel. From e9a8ccea1a6a39f843b188f947f1b6afd2e49251 Mon Sep 17 00:00:00 2001 From: devsinh Date: Wed, 4 Jun 2025 14:01:15 -0700 Subject: [PATCH 09/14] [ignore] fixed sanity issues for default values --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index 82260337c..fee4a289b 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -44,6 +44,7 @@ description: - The load balancing algorithm for distributing traffic across links in the port channel. - See the APIC Management Information Model reference for more details. + - The APIC defaults to C(src-dst-ip) when unset during creation type: str choices: - dst-ip @@ -66,13 +67,12 @@ - src-dst-l4port - src-port-id - vlan - default: src-dst-ip number_uplinks: description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. + - The APIC defaults to 2 when unset during creation type: int - default: 2 state: description: - The desired state of the Enhanced LACP Policy. From b2a58b84af9347dcd7f52c9ec9b7d3be49d31a84 Mon Sep 17 00:00:00 2001 From: devsinh Date: Mon, 9 Jun 2025 10:51:41 -0700 Subject: [PATCH 10/14] [ignore] Added a note for the prior configuration required before you can use this module in a playbook --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index fee4a289b..bf0d25116 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -71,7 +71,7 @@ description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. - - The APIC defaults to 2 when unset during creation + - The APIC defaults to 2 when unset during creation type: int state: description: @@ -87,6 +87,8 @@ - cisco.aci.annotation - cisco.aci.owner +notes: +- The I(vmm_domain) and I(vSwitch_policy) must exist before using this module in a playbook. seealso: - module: cisco.aci.aci_domain - name: APIC Management Information Model reference From 992c92f63d7246f1fe82f02247ae093da5c1ef5b Mon Sep 17 00:00:00 2001 From: devsinh Date: Mon, 9 Jun 2025 11:11:41 -0700 Subject: [PATCH 11/14] [ignore] Fixed sanity issues --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index bf0d25116..b50ae280f 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -71,7 +71,7 @@ description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. - - The APIC defaults to 2 when unset during creation + - The APIC defaults to 2 when unset during creation type: int state: description: From 493411e2dc856d5f85bbd60a33db3c529c4dd64b Mon Sep 17 00:00:00 2001 From: devsinh Date: Tue, 10 Jun 2025 09:44:06 -0700 Subject: [PATCH 12/14] [ignore] fixed documentation issues with examples and description --- .../modules/aci_vmm_enhanced_lag_policy.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index b50ae280f..adaf4fd58 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -15,8 +15,7 @@ short_description: Manage Enhanced LACP Policy for Virtual Machine Manager (VMM) in Cisco ACI (lacp:EnhancedLagPol) description: - Manage Enhanced LACP Policy for VMM domains on Cisco ACI fabrics. -- The Enhanced LACP Policy allows you to configure advanced Link Aggregation Control Protocol (LACP) settings for virtual switches in VMM domains. -- This policy is a child of the C(vmmVSwitchPolicyCont) class. +- The Enhanced LACP Policy allows you to configure advanced Link Aggregation Control Protocol settings for virtual switches in VMM domains. options: name: @@ -71,7 +70,7 @@ description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. - - The APIC defaults to 2 when unset during creation + - The APIC defaults to 2 when unset during creation type: int state: description: @@ -112,20 +111,6 @@ number_uplinks: 4 state: present -- name: Simulate creation of an Enhanced LACP Policy (Check Mode) - cisco.aci.aci_vmm_enhanced_lag_policy: - host: apic.example.com - username: admin - password: SomeSecretPassword - name: my_enhanced_lag_policy - domain: my_vmm_domain - vm_provider: vmware - lacp_mode: active - load_balancing_mode: src-dst-ip - number_uplinks: 4 - state: present - check_mode: true - - name: Update an existing Enhanced LACP Policy cisco.aci.aci_vmm_enhanced_lag_policy: host: apic.example.com From f918f35eedfb0da72f2a9c00f1613fbab0dba021 Mon Sep 17 00:00:00 2001 From: devsinh Date: Tue, 10 Jun 2025 10:19:23 -0700 Subject: [PATCH 13/14] [ignore] fixed notes for prior configuration --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index adaf4fd58..082b554b3 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -70,7 +70,7 @@ description: - The minimum number of uplinks required for the port channel. - Must be a value between 2 and 8. - - The APIC defaults to 2 when unset during creation + - The APIC defaults to 2 when unset during creation type: int state: description: @@ -88,6 +88,7 @@ notes: - The I(vmm_domain) and I(vSwitch_policy) must exist before using this module in a playbook. +- The modules M(cisco.aci.aci_domain) and M(cisco.aci.aci_vmm_vswitch_policy) can be used for this. seealso: - module: cisco.aci.aci_domain - name: APIC Management Information Model reference From bc2bc36cdc0d1de6aa2023d1ad3606a3eb96bec7 Mon Sep 17 00:00:00 2001 From: devsinh Date: Wed, 11 Jun 2025 11:29:04 -0700 Subject: [PATCH 14/14] [minor change] removed target filter for vmmVSwitchPolicy and fixed documentation --- plugins/modules/aci_vmm_enhanced_lag_policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/aci_vmm_enhanced_lag_policy.py b/plugins/modules/aci_vmm_enhanced_lag_policy.py index 082b554b3..7ea30c97a 100644 --- a/plugins/modules/aci_vmm_enhanced_lag_policy.py +++ b/plugins/modules/aci_vmm_enhanced_lag_policy.py @@ -91,6 +91,7 @@ - The modules M(cisco.aci.aci_domain) and M(cisco.aci.aci_vmm_vswitch_policy) can be used for this. seealso: - module: cisco.aci.aci_domain +- module: cisco.aci.aci_vmm_vswitch_policy - name: APIC Management Information Model reference description: More information about the internal APIC classes B(lacp:EnhancedLagPol). link: https://developer.cisco.com/docs/apic-mim-ref/ @@ -264,7 +265,6 @@ def main(): aci_class="vmmVSwitchPolicyCont", aci_rn="vswitchpolcont", module_object="vswitchpolcont", - target_filter={"name": "vswitchpolcont"}, ), subclass_3=dict( aci_class="lacpEnhancedLagPol",