From 1495893157e2087c69321248b3c75a04e11aa2a2 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Fri, 30 Jun 2023 17:00:12 -0400 Subject: [PATCH 01/31] [minor_change] Add missing test cases for existing modules. --- .../targets/aci_bd_to_l3out/aliases | 2 + .../targets/aci_bd_to_l3out/tasks/main.yml | 202 ++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 tests/integration/targets/aci_bd_to_l3out/aliases create mode 100644 tests/integration/targets/aci_bd_to_l3out/tasks/main.yml diff --git a/tests/integration/targets/aci_bd_to_l3out/aliases b/tests/integration/targets/aci_bd_to_l3out/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_bd_to_l3out/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml new file mode 100644 index 000000000..012d88eaf --- /dev/null +++ b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml @@ -0,0 +1,202 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: &aci_tenant_absent + <<: *aci_info + state: absent + tenant: ansible_test + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + - name: ensure tenant exists for tests to kick off + cisco.aci.aci_tenant: &aci_tenant_present + <<: *aci_tenant_absent + state: present + + - name: ensure vrf exists for tests to kick off + cisco.aci.aci_vrf: &aci_vrf_present + <<: *aci_tenant_present + vrf: anstest + + - name: ensure first L3out exists for tests to kick off + cisco.aci.aci_l3out: &aci_l3_out_present + <<: *aci_vrf_present + l3out: ansible_l3out + domain: ansible_dom + state: present + + - name: ensure second L3out exists for tests to kick off + cisco.aci.aci_l3out: &aci_l3_out_present_2 + <<: *aci_vrf_present + l3out: ansible_l3out_2 + domain: ansible_dom + state: present + + - name: ensure first bd exists for tests to kick off + cisco.aci.aci_bd: &aci_bd_present + <<: *aci_tenant_present + bd: anstest + + - name: ensure second bd exists for tests to kick off + cisco.aci.aci_bd: &aci_bd_present_2 + <<: *aci_tenant_present + bd: anstest_2 + + - name: Remove first binding bd_to_l3out for tests to kick off + cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_absent + <<: *aci_tenant_present + bd: anstest + l3out: ansible_l3out + state: absent + + - name: Remove second binding bd_to_l3out for tests to kick off + cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_absent_2 + <<: *aci_tenant_present + bd: anstest_2 + l3out: ansible_l3out_2 + state: absent + + - name: bind bd to L3out - first binding (check_mode) + cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_present + <<: *aci_bd_to_l3out_absent + state: present + check_mode: true + register: cm_bd_to_l3out + + - name: bind bd to L3out - first binding (normal_mode) + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present + register: nm_bd_to_l3out + + - name: bind bd to L3out again - testing idempotency + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present + register: bd_to_l3out_idempotency + + - name: bind bd to L3out - second binding + cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_present_2 + <<: *aci_bd_to_l3out_absent_2 + state: present + register: nm_bd_to_l3out_2 + + - name: asserts for creation tasks + assert: + that: + - cm_bd_to_l3out is changed + - cm_bd_to_l3out.previous == [] + - cm_bd_to_l3out.current == [] + - nm_bd_to_l3out is changed + - nm_bd_to_l3out.current.0.fvRsBDToOut.attributes.dn == "uni/tn-ansible_test/BD-anstest/rsBDToOut-ansible_l3out" + - nm_bd_to_l3out.current.0.fvRsBDToOut.attributes.tnL3extOutName == "ansible_l3out" + - bd_to_l3out_idempotency is not changed + - nm_bd_to_l3out_2 is changed + - nm_bd_to_l3out_2.current.0.fvRsBDToOut.attributes.dn == "uni/tn-ansible_test/BD-anstest_2/rsBDToOut-ansible_l3out_2" + - nm_bd_to_l3out_2.current.0.fvRsBDToOut.attributes.tnL3extOutName == "ansible_l3out_2" + + - name: Query all bds bound to l3outs + cisco.aci.aci_bd_to_l3out: + <<: *aci_tenant_present + state: query + register: query_all_bd_to_l3out + + - name: Query first bd bound to first l3out + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present + state: query + register: query_first_bd_to_l3out + + - name: asserts query tasks + assert: + that: + - query_all_bd_to_l3out is not changed + - '"fvRsBDToOut" in query_all_bd_to_l3out.filter_string' + - query_all_bd_to_l3out.current.0.fvTenant.children | length >= 2 + - query_all_bd_to_l3out.current.0.fvTenant.children.0.fvBD.attributes.name == "anstest_2" + - query_all_bd_to_l3out.current.0.fvTenant.children.0.fvBD.children.0.fvRsBDToOut.attributes.tRn == "out-ansible_l3out_2" + - query_all_bd_to_l3out.current.0.fvTenant.children.1.fvBD.attributes.name == "anstest" + - query_all_bd_to_l3out.current.0.fvTenant.children.1.fvBD.children.0.fvRsBDToOut.attributes.tRn == "out-ansible_l3out" + - query_first_bd_to_l3out is not changed + - '"tn-ansible_test/BD-anstest/rsBDToOut-ansible_l3out.json" in query_first_bd_to_l3out.url' + + - name: unbind bd to l3out - first binding (check_mode) + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present + state: absent + check_mode: true + register: cm_unbind_bd_to_l3out + + - name: unbind bd to l3out - first binding (normal_mode) + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present + state: absent + register: nm_unbind_bd_to_l3out + + - name: unbind bd to l3out again - testing idempotency + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present + state: absent + register: unbind_bd_to_l3out_idempotency + + - name: unbind bd to l3out - second binding + cisco.aci.aci_bd_to_l3out: + <<: *aci_bd_to_l3out_present_2 + state: absent + register: nm_unbind_bd_to_l3out_2 + + - name: asserts for deletion tasks + assert: + that: + - cm_unbind_bd_to_l3out is changed + - cm_unbind_bd_to_l3out.proposed == {} + - nm_unbind_bd_to_l3out is changed + - nm_unbind_bd_to_l3out.previous != [] + - nm_unbind_bd_to_l3out.method == "DELETE" + - unbind_bd_to_l3out_idempotency is not changed + - unbind_bd_to_l3out_idempotency.previous == [] + - nm_unbind_bd_to_l3out_2 is changed + - nm_unbind_bd_to_l3out_2.previous != [] + - nm_unbind_bd_to_l3out_2.method == "DELETE" + + - name: delete bd - cleanup before ending tests + cisco.aci.aci_bd: + <<: *aci_bd_present + state: absent + + - name: delete l3out - cleanup before ending tests + cisco.aci.aci_l3out: + <<: *aci_l3_out_present + state: absent + + - name: delete vrf - cleanup before ending tests + cisco.aci.aci_vrf: + <<: *aci_vrf_present + state: absent + + - name: delete tenant - cleanup before ending tests + cisco.aci.aci_tenant: + <<: *aci_tenant_present + state: absent From 57d7c9b53a7f26102be8c8b5b5c1a517b3e0f4c9 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Fri, 30 Jun 2023 18:51:21 -0400 Subject: [PATCH 02/31] [ignore] Add test case for aci_l3out_route_tag_policy. --- .../aci_l3out_route_tag_policy/aliases | 2 + .../aci_l3out_route_tag_policy/tasks/main.yml | 149 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 tests/integration/targets/aci_l3out_route_tag_policy/aliases create mode 100644 tests/integration/targets/aci_l3out_route_tag_policy/tasks/main.yml diff --git a/tests/integration/targets/aci_l3out_route_tag_policy/aliases b/tests/integration/targets/aci_l3out_route_tag_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_l3out_route_tag_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_l3out_route_tag_policy/tasks/main.yml b/tests/integration/targets/aci_l3out_route_tag_policy/tasks/main.yml new file mode 100644 index 000000000..d7ad61c6d --- /dev/null +++ b/tests/integration/targets/aci_l3out_route_tag_policy/tasks/main.yml @@ -0,0 +1,149 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# 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: info + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + tenant: ansible_tenant + state: absent + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + - name: Create tenant for tests + cisco.aci.aci_tenant: &aci_tenant_present + <<: *aci_info + state: present + tenant: ansible_tenant + + - name: Create first l3out route tag policy (check_mode) + cisco.aci.aci_l3out_route_tag_policy: &aci_rtp_present + <<: *aci_tenant_present + rtp: anstest + description: rtp test + tag: 1000 + state: present + check_mode: true + register: cm_add_rtp + + - name: Create first l3out route tag policy (normal_mode) + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present + register: nm_add_rtp + + - name: Create first l3out route tag policy again - testing idempotency + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present + register: add_rtp_idempotency + + - name: Create second l3out route tag policy + cisco.aci.aci_l3out_route_tag_policy: &aci_rtp_present_2 + <<: *aci_tenant_present + rtp: anstest_2 + state: present + register: nm_add_rtp_2 + + - name: asserts for creation tasks + assert: + that: + - cm_add_rtp is changed + - cm_add_rtp.previous == [] + - cm_add_rtp.current == [] + - nm_add_rtp is changed + - nm_add_rtp.current.0.l3extRouteTagPol.attributes.name == "anstest" + - nm_add_rtp.current.0.l3extRouteTagPol.attributes.descr == "rtp test" + - nm_add_rtp.current.0.l3extRouteTagPol.attributes.tag == "1000" + - add_rtp_idempotency is not changed + - nm_add_rtp_2 is changed + - nm_add_rtp_2.current.0.l3extRouteTagPol.attributes.name == "anstest_2" + - nm_add_rtp_2.current.0.l3extRouteTagPol.attributes.tag == "4294967295" + + - name: Query all l3out route tag policies + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_tenant_present + state: query + register: query_all_rtp + + - name: Query first l3out route tag policy + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present + state: query + register: query_first_rtp + + - name: asserts query tasks + assert: + that: + - query_all_rtp is not changed + - query_all_rtp.current.0.fvTenant.children | length >= 2 + - query_all_rtp.current.0.fvTenant.children.0.l3extRouteTagPol.attributes.name == "anstest_2" + - query_all_rtp.current.0.fvTenant.children.1.l3extRouteTagPol.attributes.name == "anstest" + - query_first_rtp is not changed + - query_first_rtp.current.0.l3extRouteTagPol.attributes.name == "anstest" + - query_first_rtp.current.0.l3extRouteTagPol.attributes.descr == "rtp test" + - query_first_rtp.current.0.l3extRouteTagPol.attributes.tag == "1000" + + - name: Delete first l3out route tag policy (check_mode) + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present + state: absent + check_mode: true + register: cm_delete_rtp + + - name: Delete first l3out route tag policy (normal_mode) + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present + state: absent + register: nm_delete_rtp + + - name: Delete first l3out route tag policy agaim - testing idempotency + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present + state: absent + register: delete_rtp_idempotency + + - name: Delete second l3out route tag policy + cisco.aci.aci_l3out_route_tag_policy: + <<: *aci_rtp_present_2 + state: absent + register: nm_delete_rtp_2 + + - name: asserts for deletion tasks + assert: + that: + - cm_delete_rtp is changed + - cm_delete_rtp.proposed == {} + - nm_delete_rtp is changed + - nm_delete_rtp.previous != [] + - nm_delete_rtp.current == [] + - delete_rtp_idempotency is not changed + - delete_rtp_idempotency.previous == [] + - nm_delete_rtp_2 is changed + - nm_delete_rtp_2.previous != [] + - nm_delete_rtp_2.current == [] + + - name: Remove ansible_tenant - cleanup before ending tests + cisco.aci.aci_tenant: + <<: *aci_tenant_present + state: absent From 767d9335dea721344a4037ede5c3f624eb08b3bf Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Mon, 17 Jul 2023 22:46:35 -0400 Subject: [PATCH 03/31] [ignore] Add test cases for aci firmware policy/group/node and aci maintenance policy/group/node --- plugins/modules/aci_fabric_scheduler.py | 6 + .../targets/aci_fabric_scheduler/aliases | 2 + .../aci_fabric_scheduler/tasks/main.yml | 158 +++++++++++++++++ .../targets/aci_firmware_group/aliases | 2 + .../targets/aci_firmware_group/tasks/main.yml | 153 ++++++++++++++++ .../targets/aci_firmware_group_node/aliases | 2 + .../aci_firmware_group_node/tasks/main.yml | 164 +++++++++++++++++ .../targets/aci_firmware_policy/aliases | 2 + .../aci_firmware_policy/tasks/main.yml | 143 +++++++++++++++ .../targets/aci_maintenance_group/aliases | 2 + .../aci_maintenance_group/tasks/main.yml | 166 +++++++++++++++++ .../aci_maintenance_group_node/aliases | 2 + .../aci_maintenance_group_node/tasks/main.yml | 167 ++++++++++++++++++ .../targets/aci_maintenance_policy/aliases | 2 + .../aci_maintenance_policy/tasks/main.yml | 167 ++++++++++++++++++ 15 files changed, 1138 insertions(+) create mode 100644 tests/integration/targets/aci_fabric_scheduler/aliases create mode 100644 tests/integration/targets/aci_fabric_scheduler/tasks/main.yml create mode 100644 tests/integration/targets/aci_firmware_group/aliases create mode 100644 tests/integration/targets/aci_firmware_group/tasks/main.yml create mode 100644 tests/integration/targets/aci_firmware_group_node/aliases create mode 100644 tests/integration/targets/aci_firmware_group_node/tasks/main.yml create mode 100644 tests/integration/targets/aci_firmware_policy/aliases create mode 100644 tests/integration/targets/aci_firmware_policy/tasks/main.yml create mode 100644 tests/integration/targets/aci_maintenance_group/aliases create mode 100644 tests/integration/targets/aci_maintenance_group/tasks/main.yml create mode 100644 tests/integration/targets/aci_maintenance_group_node/aliases create mode 100644 tests/integration/targets/aci_maintenance_group_node/tasks/main.yml create mode 100644 tests/integration/targets/aci_maintenance_policy/aliases create mode 100644 tests/integration/targets/aci_maintenance_policy/tasks/main.yml diff --git a/plugins/modules/aci_fabric_scheduler.py b/plugins/modules/aci_fabric_scheduler.py index c0297d846..6ed30a771 100644 --- a/plugins/modules/aci_fabric_scheduler.py +++ b/plugins/modules/aci_fabric_scheduler.py @@ -285,6 +285,11 @@ def main(): description = module.params.get("description") name_alias = module.params.get("name_alias") + child_classes = [ + "trigRecurrWindowP", + "trigAbsWindowP", + ] + if recurring: child_configs = [ dict( @@ -324,6 +329,7 @@ def main(): target_filter={"name": name}, module_object=name, ), + child_classes=child_classes, ) aci.get_existing() diff --git a/tests/integration/targets/aci_fabric_scheduler/aliases b/tests/integration/targets/aci_fabric_scheduler/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_fabric_scheduler/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_fabric_scheduler/tasks/main.yml b/tests/integration/targets/aci_fabric_scheduler/tasks/main.yml new file mode 100644 index 000000000..daf5e8956 --- /dev/null +++ b/tests/integration/targets/aci_fabric_scheduler/tasks/main.yml @@ -0,0 +1,158 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first scheduler does not exist + aci_fabric_scheduler: &aci_fabric_scheduler_absent + <<: *aci_info + name: anstest_scheduler_reccuring + description: ACI scheduler test + windowname: Recurring + recurring: True + concurCap: 20 + hour: 13 + minute: 30 + day: Tuesday + state: absent + + - name: Ensure second scheduler does not exist + aci_fabric_scheduler: &aci_fabric_scheduler_2_absent + <<: *aci_info + name: anstest_scheduler_oneTime + windowname: OneTime + recurring: False + concurCap: 20 + date: "2023-11-20T24:00:00" + state: absent + + - name: Create first scheduler (check_mode) + aci_fabric_scheduler: &aci_fabric_scheduler_present + <<: *aci_fabric_scheduler_absent + state: present + check_mode: true + register: cm_add_fabric_scheduler_1 + + - name: Create first scheduler (normal_mode) + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + register: nm_add_fabric_scheduler_1 + + - name: Create first scheduler again - testing idempotency + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + register: idempotency_add_fabric_scheduler_1 + + - name: Create second scheduler + aci_fabric_scheduler: &aci_fabric_scheduler_2_present + <<: *aci_fabric_scheduler_2_absent + state: present + register: nm_add_fabric_scheduler_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_fabric_scheduler_1 is changed + - cm_add_fabric_scheduler_1.previous == [] + - cm_add_fabric_scheduler_1.current == [] + - nm_add_fabric_scheduler_1 is changed + - nm_add_fabric_scheduler_1.current.0.trigSchedP.attributes.name == "anstest_scheduler_reccuring" + - nm_add_fabric_scheduler_1.current.0.trigSchedP.attributes.descr == "ACI scheduler test" + - nm_add_fabric_scheduler_1.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.concurCap == "20" + - nm_add_fabric_scheduler_1.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.day == "Tuesday" + - nm_add_fabric_scheduler_1.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.hour == "13" + - nm_add_fabric_scheduler_1.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.minute == "30" + - idempotency_add_fabric_scheduler_1 is not changed + - nm_add_fabric_scheduler_2 is changed + - nm_add_fabric_scheduler_2.current.0.trigSchedP.attributes.name == "anstest_scheduler_oneTime" + - nm_add_fabric_scheduler_2.current.0.trigSchedP.children.0.trigAbsWindowP.attributes.concurCap == "20" + - nm_add_fabric_scheduler_2.current.0.trigSchedP.children.0.trigAbsWindowP.attributes.date == "2023-11-21T00:00:00.000+00:00" + + - name: Query all scheduler + aci_fabric_scheduler: + <<: *aci_info + state: query + register: query_all_fabric_scheduler + + - name: Query first scheduler + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: query + register: query_first_fabric_scheduler + + - name: Asserts for query tasks + assert: + that: + - query_all_fabric_scheduler is not changed + - query_all_fabric_scheduler.current | length >= 2 + - '"trigAbsWindowP,trigRecurrWindowP" in query_all_fabric_scheduler.filter_string' + - '"class/trigSchedP.json" in query_all_fabric_scheduler.url' + - query_first_fabric_scheduler is not changed + - query_first_fabric_scheduler.current.0.trigSchedP.attributes.name == "anstest_scheduler_reccuring" + - query_first_fabric_scheduler.current.0.trigSchedP.attributes.descr == "ACI scheduler test" + - query_first_fabric_scheduler.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.concurCap == "20" + - query_first_fabric_scheduler.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.day == "Tuesday" + - query_first_fabric_scheduler.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.hour == "13" + - query_first_fabric_scheduler.current.0.trigSchedP.children.0.trigRecurrWindowP.attributes.minute == "30" + + - name: Delete first scheduler (check_mode) + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: absent + check_mode: true + register: cm_delete_fabric_scheduler_1 + + - name: Delete first scheduler (normal_mode) + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: absent + register: nm_delete_fabric_scheduler_1 + + - name: Delete first scheduler again - testing idempotency + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: absent + register: idempotency_delete_maintenance_group_1 + + - name: Delete second scheduler (normal_mode) + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_2_present + state: absent + register: nm_delete_fabric_scheduler_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_fabric_scheduler_1 is changed + - cm_delete_fabric_scheduler_1.proposed == {} + - nm_delete_fabric_scheduler_1 is changed + - nm_delete_fabric_scheduler_1.previous != [] + - nm_delete_fabric_scheduler_1.current == [] + - idempotency_delete_maintenance_group_1 is not changed + - idempotency_delete_maintenance_group_1.previous == [] + - nm_delete_fabric_scheduler_2 is changed + - nm_delete_fabric_scheduler_2.previous != [] + - nm_delete_fabric_scheduler_2.current == [] diff --git a/tests/integration/targets/aci_firmware_group/aliases b/tests/integration/targets/aci_firmware_group/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_firmware_group/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_firmware_group/tasks/main.yml b/tests/integration/targets/aci_firmware_group/tasks/main.yml new file mode 100644 index 000000000..e060f3d03 --- /dev/null +++ b/tests/integration/targets/aci_firmware_group/tasks/main.yml @@ -0,0 +1,153 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure firmware policy exists + aci_firmware_policy: &aci_firmware_policy_present + <<: *aci_info + name: anstest_policy + version: n9000-15.2(7) + state: present + + - name: Ensure first firmware group does not exist + aci_firmware_group: &aci_firmware_group_absent + <<: *aci_info + group: anstest_group + firmwarepol: anstest_policy + state: absent + + - name: Ensure second firmware group does not exist + aci_firmware_group: &aci_firmware_group_2_absent + <<: *aci_info + group: anstest_group_2 + firmwarepol: anstest_policy + state: absent + + - name: Create first firmware group (check_mode) + aci_firmware_group: &aci_firmware_group_present + <<: *aci_firmware_group_absent + state: present + check_mode: true + register: cm_add_firmware_group_1 + + - name: Create first firmware group (normal_mode) + aci_firmware_group: + <<: *aci_firmware_group_present + register: nm_add_firmware_group_1 + + - name: Create first firmware group again - testing idempotency + aci_firmware_group: + <<: *aci_firmware_group_present + register: idempotency_add_firmware_group_1 + + - name: Create second firmware group + aci_firmware_group: &aci_firmware_group_2_present + <<: *aci_firmware_group_2_absent + state: present + register: nm_add_firmware_group_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_firmware_group_1 is changed + - cm_add_firmware_group_1.previous == [] + - cm_add_firmware_group_1.current == [] + - nm_add_firmware_group_1 is changed + - nm_add_firmware_group_1.current.0.firmwareFwGrp.attributes.name == "anstest_group" + - nm_add_firmware_group_1.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" + - idempotency_add_firmware_group_1 is not changed + - nm_add_firmware_group_2 is changed + - nm_add_firmware_group_2.current.0.firmwareFwGrp.attributes.name == "anstest_group_2" + - nm_add_firmware_group_2.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" + + + - name: Query all firmware groups + aci_firmware_group: + <<: *aci_info + state: query + register: query_all_firmware_group + + - name: Query first firmware group + aci_firmware_group: + <<: *aci_firmware_group_present + state: query + register: query_first_firmware_group + + - name: Asserts for query tasks + assert: + that: + - query_all_firmware_group is not changed + - query_all_firmware_group.current | length >= 2 + - '"firmwareRsFwgrpp" in query_all_firmware_group.filter_string' + - '"class/firmwareFwGrp.json" in query_all_firmware_group.url' + - query_first_firmware_group is not changed + - query_first_firmware_group.current.0.firmwareFwGrp.attributes.name == "anstest_group" + - query_first_firmware_group.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" + + - name: Delete first firmware group (check_mode) + aci_firmware_group: + <<: *aci_firmware_group_present + state: absent + check_mode: true + register: cm_delete_firmware_group_1 + + - name: Delete first firmware group (normal_mode) + aci_firmware_group: + <<: *aci_firmware_group_present + state: absent + register: nm_delete_firmware_group_1 + + - name: Delete first firmware group again - testing idempotency + aci_firmware_group: + <<: *aci_firmware_group_present + state: absent + register: idempotency_delete_firmware_group_1 + + - name: Delete second firmware group (normal_mode) + aci_firmware_group: + <<: *aci_firmware_group_2_present + state: absent + register: nm_delete_firmware_group_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_firmware_group_1 is changed + - cm_delete_firmware_group_1.proposed == {} + - nm_delete_firmware_group_1 is changed + - nm_delete_firmware_group_1.previous != [] + - nm_delete_firmware_group_1.current == [] + - idempotency_delete_firmware_group_1 is not changed + - idempotency_delete_firmware_group_1.previous == [] + - nm_delete_firmware_group_2 is changed + - nm_delete_firmware_group_2.previous != [] + - nm_delete_firmware_group_2.current == [] + + - name: Delete firmware policy - clean up the environment + aci_firmware_policy: + <<: *aci_firmware_policy_present + state: absent diff --git a/tests/integration/targets/aci_firmware_group_node/aliases b/tests/integration/targets/aci_firmware_group_node/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_firmware_group_node/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_firmware_group_node/tasks/main.yml b/tests/integration/targets/aci_firmware_group_node/tasks/main.yml new file mode 100644 index 000000000..7c9d1f31f --- /dev/null +++ b/tests/integration/targets/aci_firmware_group_node/tasks/main.yml @@ -0,0 +1,164 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure firmware policy exists + aci_firmware_policy: &aci_firmware_policy_present + <<: *aci_info + name: anstest_policy + version: n9000-15.2(7) + state: present + + - name: Ensure first firmware group does not exist + aci_firmware_group: &aci_firmware_group_present + <<: *aci_info + group: anstest_group + firmwarepol: anstest_policy + state: present + + - name: Ensure first firmware group node does not exist + aci_firmware_group_node: &aci_firmware_group_node_absent + <<: *aci_info + group: anstest_group + node: 1001 + state: absent + + - name: Ensure second firmware group node does not exist + aci_firmware_group_node: &aci_firmware_group_node_2_absent + <<: *aci_info + group: anstest_group + node: 1002 + state: absent + + - name: Create first firmware group node (check_mode) + aci_firmware_group_node: &aci_firmware_group_node_present + <<: *aci_firmware_group_node_absent + state: present + check_mode: true + register: cm_add_firmware_group_node_1 + + - name: Create first firmware group node (normal_mode) + aci_firmware_group_node: + <<: *aci_firmware_group_node_present + register: nm_add_firmware_group_node_1 + + - name: Create first firmware group node again - testing idempotency + aci_firmware_group_node: + <<: *aci_firmware_group_node_present + register: idempotency_add_firmware_group_node_1 + + - name: Create second firmware group node + aci_firmware_group_node: &aci_firmware_group_node_2_present + <<: *aci_firmware_group_node_2_absent + state: present + register: nm_add_firmware_group_node_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_firmware_group_node_1 is changed + - cm_add_firmware_group_node_1.previous == [] + - cm_add_firmware_group_node_1.current == [] + - nm_add_firmware_group_node_1 is changed + - nm_add_firmware_group_node_1.current.0.fabricNodeBlk.attributes.from_ == "1001" + - nm_add_firmware_group_node_1.current.0.fabricNodeBlk.attributes.to_ == "1001" + - idempotency_add_firmware_group_node_1 is not changed + - nm_add_firmware_group_node_2 is changed + - nm_add_firmware_group_node_2.current.0.fabricNodeBlk.attributes.from_ == "1002" + - nm_add_firmware_group_node_2.current.0.fabricNodeBlk.attributes.to_ == "1002" + + + - name: Query all firmware group nodes + aci_firmware_group_node: + <<: *aci_info + state: query + register: query_all_firmware_group_node + + - name: Query first firmware group nnode + aci_firmware_group_node: + <<: *aci_firmware_group_node_present + state: query + register: query_first_firmware_group_node + + - name: Asserts for query tasks + assert: + that: + - query_all_firmware_group_node is not changed + - query_all_firmware_group_node.current | length >= 2 + - '"class/fabricNodeBlk.json" in query_all_firmware_group_node.url' + - query_first_firmware_group_node is not changed + - query_first_firmware_group_node.current.0.fabricNodeBlk.attributes.from_ == "1001" + - query_first_firmware_group_node.current.0.fabricNodeBlk.attributes.to_ == "1001" + + - name: Delete first firmware group (check_mode) + aci_firmware_group_node: + <<: *aci_firmware_group_node_present + state: absent + check_mode: true + register: cm_delete_firmware_group_node_1 + + - name: Delete first firmware group (normal_mode) + aci_firmware_group_node: + <<: *aci_firmware_group_node_present + state: absent + register: nm_delete_firmware_group_node_1 + + - name: Delete first firmware group again - testing idempotency + aci_firmware_group_node: + <<: *aci_firmware_group_node_present + state: absent + register: idempotency_delete_firmware_group_1 + + - name: Delete second firmware group (normal_mode) + aci_firmware_group_node: + <<: *aci_firmware_group_node_2_present + state: absent + register: nm_delete_firmware_group_node_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_firmware_group_node_1 is changed + - cm_delete_firmware_group_node_1.proposed == {} + - nm_delete_firmware_group_node_1 is changed + - nm_delete_firmware_group_node_1.previous != [] + - nm_delete_firmware_group_node_1.current == [] + - idempotency_delete_firmware_group_1 is not changed + - idempotency_delete_firmware_group_1.previous == [] + - nm_delete_firmware_group_node_2 is changed + - nm_delete_firmware_group_node_2.previous != [] + - nm_delete_firmware_group_node_2.current == [] + + - name: Delete firmware group - clean up the environment + aci_firmware_group: + <<: *aci_firmware_group_present + state: absent + + - name: Delete firmware policy - clean up the environment + aci_firmware_policy: + <<: *aci_firmware_policy_present + state: absent diff --git a/tests/integration/targets/aci_firmware_policy/aliases b/tests/integration/targets/aci_firmware_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_firmware_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_firmware_policy/tasks/main.yml b/tests/integration/targets/aci_firmware_policy/tasks/main.yml new file mode 100644 index 000000000..7f872a767 --- /dev/null +++ b/tests/integration/targets/aci_firmware_policy/tasks/main.yml @@ -0,0 +1,143 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first firmware policy does not exist + aci_firmware_policy: &aci_firmware_policy_absent + <<: *aci_info + name: anstest_policy + version: n9000-15.2(7) + ignoreCompat: True + state: absent + + - name: Ensure second firmware policy does not exist + aci_firmware_policy: &aci_firmware_policy_2_absent + <<: *aci_info + name: anstest_policy_2 + version: n9000-16.0(1) + state: absent + + - name: Create first firmware policy (check_mode) + aci_firmware_policy: &aci_firmware_policy_present + <<: *aci_firmware_policy_absent + state: present + check_mode: true + register: cm_add_firmware_policy_1 + + - name: Create first firmware policy (normal_mode) + aci_firmware_policy: + <<: *aci_firmware_policy_present + register: nm_add_firmware_policy_1 + + - name: Create first firmware policy again - testing idempotency + aci_firmware_policy: + <<: *aci_firmware_policy_present + register: idempotency_add_firmware_policy_1 + + - name: Create second firmware policy + aci_firmware_policy: &aci_firmware_policy_2_present + <<: *aci_firmware_policy_2_absent + state: present + register: nm_add_firmware_policy_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_firmware_policy_1 is changed + - cm_add_firmware_policy_1.previous == [] + - cm_add_firmware_policy_1.current == [] + - nm_add_firmware_policy_1 is changed + - nm_add_firmware_policy_1.current.0.firmwareFwP.attributes.name == "anstest_policy" + - nm_add_firmware_policy_1.current.0.firmwareFwP.attributes.ignoreCompat == "yes" + - nm_add_firmware_policy_1.current.0.firmwareFwP.attributes.version == "n9000-15.2(7)" + - idempotency_add_firmware_policy_1 is not changed + - nm_add_firmware_policy_2 is changed + - nm_add_firmware_policy_2.current.0.firmwareFwP.attributes.name == "anstest_policy_2" + - nm_add_firmware_policy_2.current.0.firmwareFwP.attributes.ignoreCompat == "no" + - nm_add_firmware_policy_2.current.0.firmwareFwP.attributes.version == "n9000-16.0(1)" + + - name: Query all firmware policies + aci_firmware_policy: + <<: *aci_info + state: query + register: query_all_firmware_policy + + - name: Query first firmware policy + aci_firmware_policy: + <<: *aci_firmware_policy_present + state: query + register: query_first_firmware_policy + + - name: Asserts for query tasks + assert: + that: + - query_all_firmware_policy is not changed + - query_all_firmware_policy.current | length >= 2 + - '"class/firmwareFwP.json" in query_all_firmware_policy.url' + - query_first_firmware_policy is not changed + - query_first_firmware_policy.current.0.firmwareFwP.attributes.name == "anstest_policy" + - query_first_firmware_policy.current.0.firmwareFwP.attributes.ignoreCompat == "yes" + - query_first_firmware_policy.current.0.firmwareFwP.attributes.version == "n9000-15.2(7)" + + - name: Delete first firmware policy (check_mode) + aci_firmware_policy: + <<: *aci_firmware_policy_present + state: absent + check_mode: true + register: cm_delete_firmware_policy_1 + + - name: Delete first firmware policy (normal_mode) + aci_firmware_policy: + <<: *aci_firmware_policy_present + state: absent + register: nm_delete_firmware_policy_1 + + - name: Delete first firmware policy again - testing idempotency + aci_firmware_policy: + <<: *aci_firmware_policy_present + state: absent + register: idempotency_delete_firmware_policy_1 + + - name: Delete second firmware policy (normal_mode) + aci_firmware_policy: + <<: *aci_firmware_policy_2_present + state: absent + register: nm_delete_firmware_policy_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_firmware_policy_1 is changed + - cm_delete_firmware_policy_1.proposed == {} + - nm_delete_firmware_policy_1 is changed + - nm_delete_firmware_policy_1.previous != [] + - nm_delete_firmware_policy_1.current == [] + - idempotency_delete_firmware_policy_1 is not changed + - idempotency_delete_firmware_policy_1.previous == [] + - nm_delete_firmware_policy_2 is changed + - nm_delete_firmware_policy_2.previous != [] + - nm_delete_firmware_policy_2.current == [] diff --git a/tests/integration/targets/aci_maintenance_group/aliases b/tests/integration/targets/aci_maintenance_group/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_group/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_maintenance_group/tasks/main.yml b/tests/integration/targets/aci_maintenance_group/tasks/main.yml new file mode 100644 index 000000000..f538b2043 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_group/tasks/main.yml @@ -0,0 +1,166 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure Scheduler exists + aci_fabric_scheduler: &aci_fabric_scheduler_present + <<: *aci_info + name: anstest_scheduler + state: present + + - name: Ensure maintenance policy exists + aci_maintenance_policy: &aci_maintenance_policy_present + <<: *aci_info + name: anstest_policy + scheduler: anstest_scheduler + state: present + + - name: Ensure first maintenance group does not exist + aci_maintenance_group: &aci_maintenance_group_absent + <<: *aci_info + group: anstest_group + policy: anstest_policy + state: absent + + - name: Ensure second maintenance group does not exist + aci_maintenance_group: &aci_maintenance_group_2_absent + <<: *aci_info + group: anstest_group_2 + policy: anstest_policy_2 + state: absent + + - name: Create first maintenance group (check_mode) + aci_maintenance_group: &aci_maintenance_group_present + <<: *aci_maintenance_group_absent + state: present + check_mode: true + register: cm_add_maintenance_group_1 + + - name: Create first maintenance group (normal_mode) + aci_maintenance_group: + <<: *aci_maintenance_group_present + register: nm_add_maintenance_group_1 + + - name: Create first maintenance group again - testing idempotency + aci_maintenance_group: + <<: *aci_maintenance_group_present + register: idempotency_add_maintenance_group_1 + + - name: Create second maintenance group + aci_maintenance_group: &aci_maintenance_group_2_present + <<: *aci_maintenance_group_2_absent + state: present + register: nm_add_maintenance_group_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_maintenance_group_1 is changed + - cm_add_maintenance_group_1.previous == [] + - cm_add_maintenance_group_1.current == [] + - nm_add_maintenance_group_1 is changed + - nm_add_maintenance_group_1.current.0.maintMaintGrp.attributes.name == "anstest_group" + - nm_add_maintenance_group_1.current.0.maintMaintGrp.children.0.maintRsMgrpp.attributes.tnMaintMaintPName == "anstest_policy" + - idempotency_add_maintenance_group_1 is not changed + - nm_add_maintenance_group_2 is changed + - nm_add_maintenance_group_2.current.0.maintMaintGrp.attributes.name == "anstest_group_2" + - nm_add_maintenance_group_2.current.0.maintMaintGrp.children.0.maintRsMgrpp.attributes.tnMaintMaintPName == "anstest_policy_2" + + + - name: Query all maintenance groups + aci_maintenance_group: + <<: *aci_info + state: query + register: query_all_maintenance_group + + - name: Query first maintenance group + aci_maintenance_group: + <<: *aci_maintenance_group_present + state: query + register: query_first_maintenance_group + + - name: Asserts for query tasks + assert: + that: + - query_all_maintenance_group is not changed + - query_all_maintenance_group.current | length >= 2 + - '"maintRsMgrpp" in query_all_maintenance_group.filter_string' + - '"class/maintMaintGrp.json" in query_all_maintenance_group.url' + - query_all_maintenance_group.current.0.maintMaintGrp.attributes.name == "anstest_group" + - query_all_maintenance_group.current.1.maintMaintGrp.attributes.name == "anstest_group_2" + - query_first_maintenance_group is not changed + - query_first_maintenance_group.current.0.maintMaintGrp.attributes.name == "anstest_group" + - query_first_maintenance_group.current.0.maintMaintGrp.children.0.maintRsMgrpp.attributes.tnMaintMaintPName == "anstest_policy" + + - name: Delete first maintenance group (check_mode) + aci_maintenance_group: + <<: *aci_maintenance_group_present + state: absent + check_mode: true + register: cm_delete_maintenance_group_1 + + - name: Delete first maintenance group (normal_mode) + aci_maintenance_group: + <<: *aci_maintenance_group_present + state: absent + register: nm_delete_maintenance_group_1 + + - name: Delete first maintenance group again - testing idempotency + aci_maintenance_group: + <<: *aci_maintenance_group_present + state: absent + register: idempotency_delete_maintenance_group_1 + + - name: Delete second maintenance group (normal_mode) + aci_maintenance_group: + <<: *aci_maintenance_group_2_present + state: absent + register: nm_delete_maintenance_group_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_maintenance_group_1 is changed + - cm_delete_maintenance_group_1.proposed == {} + - nm_delete_maintenance_group_1 is changed + - nm_delete_maintenance_group_1.previous != [] + - nm_delete_maintenance_group_1.current == [] + - idempotency_delete_maintenance_group_1 is not changed + - idempotency_delete_maintenance_group_1.previous == [] + - nm_delete_maintenance_group_2 is changed + - nm_delete_maintenance_group_2.previous != [] + - nm_delete_maintenance_group_2.current == [] + + - name: Delete maintenance policy - clean up the environment + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + state: absent + + - name: Delete scheduler - clean up the environment + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: absent diff --git a/tests/integration/targets/aci_maintenance_group_node/aliases b/tests/integration/targets/aci_maintenance_group_node/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_group_node/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml b/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml new file mode 100644 index 000000000..472f59c4d --- /dev/null +++ b/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml @@ -0,0 +1,167 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure Scheduler exists + aci_fabric_scheduler: &aci_fabric_scheduler_present + <<: *aci_info + name: anstest_scheduler + state: present + + - name: Ensure maintenance policy exists + aci_maintenance_policy: &aci_maintenance_policy_present + <<: *aci_info + name: anstest_policy + scheduler: anstest_scheduler + state: present + + - name: Ensure first maintenance groupe exists + aci_maintenance_group: &aci_maintenance_group_present + <<: *aci_info + group: anstest_group + policy: anstest_policy + state: present + + - name: Ensure first maintenance group node does not exist + aci_maintenance_group_node: &aci_maintenance_group_node_absent + <<: *aci_info + group: anstest_group + node: 1001 + state: absent + + - name: Ensure second maintenance group node does not exist + aci_maintenance_group_node: &aci_maintenance_group_node_2_absent + <<: *aci_info + group: anstest_group + node: 1002 + state: absent + + - name: Create first maintenance group node (check_mode) + aci_maintenance_group_node: &aci_maintenance_group_node_present + <<: *aci_maintenance_group_node_absent + state: present + check_mode: true + register: cm_add_maintenance_group_node_1 + + - name: Create first maintenance group node (normal_mode) + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_present + register: nm_add_maintenance_group_node_1 + + - name: Create first maintenance group node again - testing idempotency + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_present + register: idempotency_add_maintenance_group_node_1 + + - name: Create second maintenance group node + aci_maintenance_group_node: &aci_maintenance_group_node_2_present + <<: *aci_maintenance_group_node_2_absent + state: present + register: nm_add_maintenance_group_node_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_maintenance_group_node_1 is changed + - cm_add_maintenance_group_node_1.previous == [] + - cm_add_maintenance_group_node_1.current == [] + - nm_add_maintenance_group_node_1 is changed + - idempotency_add_maintenance_group_node_1 is not changed + - nm_add_maintenance_group_node_2 is changed + + + - name: Query all maintenance group nodes + aci_maintenance_group_node: + <<: *aci_info + state: query + register: query_all_maintenance_group_node + + - name: Query first maintenance group nnode + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_present + state: query + register: query_first_maintenance_group_node + + - name: Asserts for query tasks + assert: + that: + - query_all_maintenance_group_node is not changed + - query_first_maintenance_group_node is not changed + + - name: Delete first maintenance group (check_mode) + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_present + state: absent + check_mode: true + register: cm_delete_maintenance_group_node_1 + + - name: Delete first maintenance group (normal_mode) + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_present + state: absent + register: nm_delete_maintenance_group_node_1 + + - name: Delete first maintenance group again - testing idempotency + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_present + state: absent + register: idempotency_delete_maintenance_group_1 + + - name: Delete second maintenance group (normal_mode) + aci_maintenance_group_node: + <<: *aci_maintenance_group_node_2_present + state: absent + register: nm_delete_maintenance_group_node_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_maintenance_group_node_1 is changed + - cm_delete_maintenance_group_node_1.proposed == {} + - nm_delete_maintenance_group_node_1 is changed + - nm_delete_maintenance_group_node_1.previous != [] + - nm_delete_maintenance_group_node_1.current == [] + - idempotency_delete_maintenance_group_1 is not changed + - idempotency_delete_maintenance_group_1.previous == [] + - nm_delete_maintenance_group_node_2 is changed + - nm_delete_maintenance_group_node_2.previous != [] + - nm_delete_maintenance_group_node_2.current == [] + + - name: Delete maintenance group - clean up the environment + aci_maintenance_group: + <<: *aci_maintenance_group_present + state: absent + + - name: Delete maintenance policy - clean up the environment + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + state: absent + + - name: Delete scheduler - clean up the environment + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: absent diff --git a/tests/integration/targets/aci_maintenance_policy/aliases b/tests/integration/targets/aci_maintenance_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml new file mode 100644 index 000000000..a60a93b80 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml @@ -0,0 +1,167 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure Scheduler exists + aci_fabric_scheduler: &aci_fabric_scheduler_present + <<: *aci_info + name: anstest_scheduler + state: present + + - name: Ensure first maintenance policy does not exist + aci_maintenance_policy: &aci_maintenance_policy_absent + <<: *aci_info + name: anstest_policy + runmode: pauseNever + graceful: True + scheduler: anstest_scheduler + ignoreCompat: true + adminst: untriggered + state: absent + + - name: Ensure second maintenance policy does not exist + aci_maintenance_policy: &aci_maintenance_policy_2_absent + <<: *aci_info + name: anstest_policy_2 + scheduler: anstest_scheduler + state: absent + + - name: Create first maintenance policy (check_mode) + aci_maintenance_policy: &aci_maintenance_policy_present + <<: *aci_maintenance_policy_absent + state: present + check_mode: true + register: cm_add_maintenance_policy_1 + + - name: Create first maintenance policy (normal_mode) + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + register: nm_add_maintenance_policy_1 + + - name: Create first maintenance policy again - testing idempotency + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + register: idempotency_add_maintenance_policy_1 + + - name: Create second maintenance policy + aci_maintenance_policy: &aci_maintenance_policy_2_present + <<: *aci_maintenance_policy_2_absent + state: present + register: nm_add_maintenance_policy_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_maintenance_policy_1 is changed + - cm_add_maintenance_policy_1.previous == [] + - cm_add_maintenance_policy_1.current == [] + - nm_add_maintenance_policy_1 is changed + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.adminSt == "untriggered" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.graceful == "yes" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.ignoreCompat == "yes" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.name == "anstest_policy" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.runMode == "pauseNever" + - nm_add_maintenance_policy_1.current.0.maintMaintP.children.0.maintRsPolScheduler.attributes.tnTrigSchedPName == "anstest_scheduler" + - idempotency_add_maintenance_policy_1 is not changed + - nm_add_maintenance_policy_2 is changed + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.adminSt == "untriggered" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.graceful == "no" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.ignoreCompat == "no" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.name == "anstest_policy_2" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.runMode == "pauseOnlyOnFailures" + - nm_add_maintenance_policy_2.current.0.maintMaintP.children.0.maintRsPolScheduler.attributes.tnTrigSchedPName == "anstest_scheduler" + + - name: Query all maintenance policies + aci_maintenance_policy: + <<: *aci_info + state: query + register: query_all_maintenance_policy + + - name: Query first maintenance policy + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + state: query + register: query_first_maintenance_policy + + - name: Asserts for query tasks + assert: + that: + - query_all_maintenance_policy is not changed + - query_all_maintenance_policy.current | length >= 2 + - '"maintRsPolScheduler" in query_all_maintenance_policy.filter_string' + - '"class/maintMaintP.json" in query_all_maintenance_policy.url' + - query_first_maintenance_policy is not changed + - query_first_maintenance_policy.current.0.maintMaintP.attributes.adminSt == "untriggered" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.graceful == "yes" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.ignoreCompat == "yes" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.name == "anstest_policy" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.runMode == "pauseNever" + - query_first_maintenance_policy.current.0.maintMaintP.children.0.maintRsPolScheduler.attributes.tnTrigSchedPName == "anstest_scheduler" + + - name: Delete first maintenance policy (check_mode) + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + state: absent + check_mode: true + register: cm_delete_maintenance_policy_1 + + - name: Delete first maintenance policy (normal_mode) + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + state: absent + register: nm_delete_maintenance_policy_1 + + - name: Delete first maintenance policy again - testing idempotency + aci_maintenance_policy: + <<: *aci_maintenance_policy_present + state: absent + register: idempotency_delete_maintenance_policy_1 + + - name: Delete second maintenance policy (normal_mode) + aci_maintenance_policy: + <<: *aci_maintenance_policy_2_present + state: absent + register: nm_delete_maintenance_policy_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_maintenance_policy_1 is changed + - cm_delete_maintenance_policy_1.proposed == {} + - nm_delete_maintenance_policy_1 is changed + - nm_delete_maintenance_policy_1.previous != [] + - nm_delete_maintenance_policy_1.current == [] + - idempotency_delete_maintenance_policy_1 is not changed + - idempotency_delete_maintenance_policy_1.previous == [] + - nm_delete_maintenance_policy_2 is changed + - nm_delete_maintenance_policy_2.previous != [] + - nm_delete_maintenance_policy_2.current == [] + + - name: Delete scheduler - clean up the environment + aci_fabric_scheduler: + <<: *aci_fabric_scheduler_present + state: absent From 512a71d94c81a65675534a6e6a73e6b1a661f6ef Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Mon, 17 Jul 2023 23:29:25 -0400 Subject: [PATCH 04/31] [ignore] Add test cases for aci_interface_policy_fc and aci_interface_policy_l2 --- .../targets/aci_interface_policy_fc/aliases | 2 + .../aci_interface_policy_fc/tasks/main.yml | 139 +++++++++++++++++ .../targets/aci_interface_policy_l2/aliases | 2 + .../aci_interface_policy_l2/tasks/main.yml | 147 ++++++++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 tests/integration/targets/aci_interface_policy_fc/aliases create mode 100644 tests/integration/targets/aci_interface_policy_fc/tasks/main.yml create mode 100644 tests/integration/targets/aci_interface_policy_l2/aliases create mode 100644 tests/integration/targets/aci_interface_policy_l2/tasks/main.yml diff --git a/tests/integration/targets/aci_interface_policy_fc/aliases b/tests/integration/targets/aci_interface_policy_fc/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_fc/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml new file mode 100644 index 000000000..53072c473 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml @@ -0,0 +1,139 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first fc interface policy does not exist + aci_interface_policy_fc: &aci_interface_policy_fc_absent + <<: *aci_info + name: anstest_policy + description: test for fc interface policy + port_mode: np + state: absent + + - name: Ensure second fc interface policy does not exist + aci_interface_policy_fc: &aci_interface_policy_fc_2_absent + <<: *aci_info + name: anstest_policy_2 + state: absent + + - name: Create first fc interface policy (check_mode) + aci_interface_policy_fc: &aci_interface_policy_fc_present + <<: *aci_interface_policy_fc_absent + state: present + check_mode: true + register: cm_add_interface_policy_fc_1 + + - name: Create first fc interface policy (normal_mode) + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_present + register: nm_add_interface_policy_fc_1 + + - name: Create first fc interface policy again - testing idempotency + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_present + register: idempotency_add_interface_policy_fc_1 + + - name: Create second fc interface policy + aci_interface_policy_fc: &aci_interface_policy_fc_2_present + <<: *aci_interface_policy_fc_2_absent + state: present + register: nm_add_interface_policy_fc_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_interface_policy_fc_1 is changed + - cm_add_interface_policy_fc_1.previous == [] + - cm_add_interface_policy_fc_1.current == [] + - nm_add_interface_policy_fc_1 is changed + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.name == "anstest_policy" + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.portMode == "np" + - idempotency_add_interface_policy_fc_1 is not changed + - nm_add_interface_policy_fc_2 is changed + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.name == "anstest_policy_2" + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.portMode == "f" + + - name: Query all maintenance policies + aci_interface_policy_fc: + <<: *aci_info + state: query + register: query_all_interface_policy_fc + + - name: Query first fc interface policy + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_present + state: query + register: query_first_interface_policy_fc + + - name: Asserts for query tasks + assert: + that: + - query_all_interface_policy_fc is not changed + - query_all_interface_policy_fc.current | length >= 2 + - '"class/fcIfPol.json" in query_all_interface_policy_fc.url' + - query_first_interface_policy_fc is not changed + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.name == "anstest_policy" + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.portMode == "np" + + - name: Delete first fc interface policy (check_mode) + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_present + state: absent + check_mode: true + register: cm_delete_interface_policy_fc_1 + + - name: Delete first fc interface policy (normal_mode) + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_present + state: absent + register: nm_delete_interface_policy_fc_1 + + - name: Delete first fc interface policy again - testing idempotency + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_present + state: absent + register: idempotency_delete_interface_policy_fc_1 + + - name: Delete second fc interface policy (normal_mode) + aci_interface_policy_fc: + <<: *aci_interface_policy_fc_2_present + state: absent + register: nm_delete_interface_policy_fc_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_interface_policy_fc_1 is changed + - cm_delete_interface_policy_fc_1.proposed == {} + - nm_delete_interface_policy_fc_1 is changed + - nm_delete_interface_policy_fc_1.previous != [] + - nm_delete_interface_policy_fc_1.current == [] + - idempotency_delete_interface_policy_fc_1 is not changed + - idempotency_delete_interface_policy_fc_1.previous == [] + - nm_delete_interface_policy_fc_2 is changed + - nm_delete_interface_policy_fc_2.previous != [] + - nm_delete_interface_policy_fc_2.current == [] diff --git a/tests/integration/targets/aci_interface_policy_l2/aliases b/tests/integration/targets/aci_interface_policy_l2/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_l2/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml b/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml new file mode 100644 index 000000000..25e733551 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml @@ -0,0 +1,147 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first l2 interface policy does not exist + aci_interface_policy_l2: &aci_interface_policy_l2_absent + <<: *aci_info + name: anstest_policy + description: test for l2 interface policy + vlan_scope: portlocal + qinq: core + vepa: true + state: absent + + - name: Ensure second l2 interface policy does not exist + aci_interface_policy_l2: &aci_interface_policy_l2_2_absent + <<: *aci_info + name: anstest_policy_2 + state: absent + + - name: Create first l2 interface policy (check_mode) + aci_interface_policy_l2: &aci_interface_policy_l2_present + <<: *aci_interface_policy_l2_absent + state: present + check_mode: true + register: cm_add_interface_policy_l2_1 + + - name: Create first l2 interface policy (normal_mode) + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_present + register: nm_add_interface_policy_l2_1 + + - name: Create first l2 interface policy again - testing idempotency + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_present + register: idempotency_add_interface_policy_l2_1 + + - name: Create second l2 interface policy + aci_interface_policy_l2: &aci_interface_policy_l2_2_present + <<: *aci_interface_policy_l2_2_absent + state: present + register: nm_add_interface_policy_l2_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_interface_policy_l2_1 is changed + - cm_add_interface_policy_l2_1.previous == [] + - cm_add_interface_policy_l2_1.current == [] + - nm_add_interface_policy_l2_1 is changed + - nm_add_interface_policy_l2_1.current.0.l2IfPol.attributes.name == "anstest_policy" + - nm_add_interface_policy_l2_1.current.0.l2IfPol.attributes.vlanScope == "portlocal" + - nm_add_interface_policy_l2_1.current.0.l2IfPol.attributes.qinq == "corePort" + - nm_add_interface_policy_l2_1.current.0.l2IfPol.attributes.vepa == "enabled" + - idempotency_add_interface_policy_l2_1 is not changed + - nm_add_interface_policy_l2_2 is changed + - nm_add_interface_policy_l2_2.current.0.l2IfPol.attributes.name == "anstest_policy_2" + - nm_add_interface_policy_l2_2.current.0.l2IfPol.attributes.vlanScope == "global" + - nm_add_interface_policy_l2_2.current.0.l2IfPol.attributes.qinq == "disabled" + - nm_add_interface_policy_l2_2.current.0.l2IfPol.attributes.vepa == "disabled" + + - name: Query all maintenance policies + aci_interface_policy_l2: + <<: *aci_info + state: query + register: query_all_interface_policy_l2 + + - name: Query first l2 interface policy + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_present + state: query + register: query_first_interface_policy_l2 + + - name: Asserts for query tasks + assert: + that: + - query_all_interface_policy_l2 is not changed + - query_all_interface_policy_l2.current | length >= 2 + - '"class/l2IfPol.json" in query_all_interface_policy_l2.url' + - query_first_interface_policy_l2 is not changed + - query_first_interface_policy_l2.current.0.l2IfPol.attributes.name == "anstest_policy" + - query_first_interface_policy_l2.current.0.l2IfPol.attributes.vlanScope == "portlocal" + - query_first_interface_policy_l2.current.0.l2IfPol.attributes.qinq == "corePort" + - query_first_interface_policy_l2.current.0.l2IfPol.attributes.vepa == "enabled" + + - name: Delete first l2 interface policy (check_mode) + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_present + state: absent + check_mode: true + register: cm_delete_interface_policy_l2_1 + + - name: Delete first l2 interface policy (normal_mode) + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_present + state: absent + register: nm_delete_interface_policy_l2_1 + + - name: Delete first l2 interface policy again - testing idempotency + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_present + state: absent + register: idempotency_delete_interface_policy_l2_1 + + - name: Delete second l2 interface policy (normal_mode) + aci_interface_policy_l2: + <<: *aci_interface_policy_l2_2_present + state: absent + register: nm_delete_interface_policy_l2_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_interface_policy_l2_1 is changed + - cm_delete_interface_policy_l2_1.proposed == {} + - nm_delete_interface_policy_l2_1 is changed + - nm_delete_interface_policy_l2_1.previous != [] + - nm_delete_interface_policy_l2_1.current == [] + - idempotency_delete_interface_policy_l2_1 is not changed + - idempotency_delete_interface_policy_l2_1.previous == [] + - nm_delete_interface_policy_l2_2 is changed + - nm_delete_interface_policy_l2_2.previous != [] + - nm_delete_interface_policy_l2_2.current == [] From beb561fcad37454ce0bc205a26b6121fbf0ff239 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 18 Jul 2023 13:09:35 -0400 Subject: [PATCH 05/31] [ignore] Add test cases for interface policies lldp, mcp and port channel. --- .../aci_interface_policy_fc/tasks/main.yml | 2 +- .../aci_interface_policy_l2/tasks/main.yml | 2 +- .../targets/aci_interface_policy_lldp/aliases | 2 + .../aci_interface_policy_lldp/tasks/main.yml | 143 ++++++++++++++ .../targets/aci_interface_policy_mcp/aliases | 2 + .../aci_interface_policy_mcp/tasks/main.yml | 139 ++++++++++++++ .../aci_interface_policy_port_channel/aliases | 2 + .../tasks/main.yml | 174 ++++++++++++++++++ 8 files changed, 464 insertions(+), 2 deletions(-) create mode 100644 tests/integration/targets/aci_interface_policy_lldp/aliases create mode 100644 tests/integration/targets/aci_interface_policy_lldp/tasks/main.yml create mode 100644 tests/integration/targets/aci_interface_policy_mcp/aliases create mode 100644 tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml create mode 100644 tests/integration/targets/aci_interface_policy_port_channel/aliases create mode 100644 tests/integration/targets/aci_interface_policy_port_channel/tasks/main.yml diff --git a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml index 53072c473..c71e266bc 100644 --- a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml +++ b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml @@ -77,7 +77,7 @@ - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.name == "anstest_policy_2" - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.portMode == "f" - - name: Query all maintenance policies + - name: Query all fc interface policies aci_interface_policy_fc: <<: *aci_info state: query diff --git a/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml b/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml index 25e733551..f52b74fdb 100644 --- a/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml +++ b/tests/integration/targets/aci_interface_policy_l2/tasks/main.yml @@ -83,7 +83,7 @@ - nm_add_interface_policy_l2_2.current.0.l2IfPol.attributes.qinq == "disabled" - nm_add_interface_policy_l2_2.current.0.l2IfPol.attributes.vepa == "disabled" - - name: Query all maintenance policies + - name: Query all l2 interface policies aci_interface_policy_l2: <<: *aci_info state: query diff --git a/tests/integration/targets/aci_interface_policy_lldp/aliases b/tests/integration/targets/aci_interface_policy_lldp/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_lldp/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_interface_policy_lldp/tasks/main.yml b/tests/integration/targets/aci_interface_policy_lldp/tasks/main.yml new file mode 100644 index 000000000..225e142ba --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_lldp/tasks/main.yml @@ -0,0 +1,143 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first lldp interface policy does not exist + aci_interface_policy_lldp: &aci_interface_policy_lldp_absent + <<: *aci_info + name: anstest_policy + description: test for lldp interface policy + receive_state: false + transmit_state: false + state: absent + + - name: Ensure second lldp interface policy does not exist + aci_interface_policy_lldp: &aci_interface_policy_lldp_2_absent + <<: *aci_info + name: anstest_policy_2 + state: absent + + - name: Create first lldp interface policy (check_mode) + aci_interface_policy_lldp: &aci_interface_policy_lldp_present + <<: *aci_interface_policy_lldp_absent + state: present + check_mode: true + register: cm_add_interface_policy_lldp_1 + + - name: Create first lldp interface policy (normal_mode) + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_present + register: nm_add_interface_policy_lldp_1 + + - name: Create first lldp interface policy again - testing idempotency + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_present + register: idempotency_add_interface_policy_lldp_1 + + - name: Create second lldp interface policy + aci_interface_policy_lldp: &aci_interface_policy_lldp_2_present + <<: *aci_interface_policy_lldp_2_absent + state: present + register: nm_add_interface_policy_lldp_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_interface_policy_lldp_1 is changed + - cm_add_interface_policy_lldp_1.previous == [] + - cm_add_interface_policy_lldp_1.current == [] + - nm_add_interface_policy_lldp_1 is changed + - nm_add_interface_policy_lldp_1.current.0.lldpIfPol.attributes.name == "anstest_policy" + - nm_add_interface_policy_lldp_1.current.0.lldpIfPol.attributes.adminRxSt == "disabled" + - nm_add_interface_policy_lldp_1.current.0.lldpIfPol.attributes.adminTxSt == "disabled" + - idempotency_add_interface_policy_lldp_1 is not changed + - nm_add_interface_policy_lldp_2 is changed + - nm_add_interface_policy_lldp_2.current.0.lldpIfPol.attributes.name == "anstest_policy_2" + - nm_add_interface_policy_lldp_2.current.0.lldpIfPol.attributes.adminRxSt == "enabled" + - nm_add_interface_policy_lldp_2.current.0.lldpIfPol.attributes.adminTxSt == "enabled" + + - name: Query all lldp interface policies + aci_interface_policy_lldp: + <<: *aci_info + state: query + register: query_all_interface_policy_lldp + + - name: Query first lldp interface policy + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_present + state: query + register: query_first_interface_policy_lldp + + - name: Asserts for query tasks + assert: + that: + - query_all_interface_policy_lldp is not changed + - query_all_interface_policy_lldp.current | length >= 2 + - '"class/lldpIfPol.json" in query_all_interface_policy_lldp.url' + - query_first_interface_policy_lldp is not changed + - query_first_interface_policy_lldp.current.0.lldpIfPol.attributes.name == "anstest_policy" + - query_first_interface_policy_lldp.current.0.lldpIfPol.attributes.adminRxSt == "disabled" + - query_first_interface_policy_lldp.current.0.lldpIfPol.attributes.adminTxSt == "disabled" + + - name: Delete first lldp interface policy (check_mode) + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_present + state: absent + check_mode: true + register: cm_delete_interface_policy_lldp_1 + + - name: Delete first lldp interface policy (normal_mode) + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_present + state: absent + register: nm_delete_interface_policy_lldp_1 + + - name: Delete first lldp interface policy again - testing idempotency + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_present + state: absent + register: idempotency_delete_interface_policy_lldp_1 + + - name: Delete second lldp interface policy (normal_mode) + aci_interface_policy_lldp: + <<: *aci_interface_policy_lldp_2_present + state: absent + register: nm_delete_interface_policy_lldp_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_interface_policy_lldp_1 is changed + - cm_delete_interface_policy_lldp_1.proposed == {} + - nm_delete_interface_policy_lldp_1 is changed + - nm_delete_interface_policy_lldp_1.previous != [] + - nm_delete_interface_policy_lldp_1.current == [] + - idempotency_delete_interface_policy_lldp_1 is not changed + - idempotency_delete_interface_policy_lldp_1.previous == [] + - nm_delete_interface_policy_lldp_2 is changed + - nm_delete_interface_policy_lldp_2.previous != [] + - nm_delete_interface_policy_lldp_2.current == [] diff --git a/tests/integration/targets/aci_interface_policy_mcp/aliases b/tests/integration/targets/aci_interface_policy_mcp/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_mcp/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml b/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml new file mode 100644 index 000000000..a8901eacc --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml @@ -0,0 +1,139 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first mcp interface policy does not exist + aci_interface_policy_mcp: &aci_interface_policy_mcp_absent + <<: *aci_info + name: anstest_policy + description: test for mcp interface policy + admin_state: false + state: absent + + - name: Ensure second mcp interface policy does not exist + aci_interface_policy_mcp: &aci_interface_policy_mcp_2_absent + <<: *aci_info + name: anstest_policy_2 + state: absent + + - name: Create first mcp interface policy (check_mode) + aci_interface_policy_mcp: &aci_interface_policy_mcp_present + <<: *aci_interface_policy_mcp_absent + state: present + check_mode: true + register: cm_add_interface_policy_mcp_1 + + - name: Create first mcp interface policy (normal_mode) + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present + register: nm_add_interface_policy_mcp_1 + + - name: Create first mcp interface policy again - testing idempotency + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present + register: idempotency_add_interface_policy_mcp_1 + + - name: Create second mcp interface policy + aci_interface_policy_mcp: &aci_interface_policy_mcp_2_present + <<: *aci_interface_policy_mcp_2_absent + state: present + register: nm_add_interface_policy_mcp_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_interface_policy_mcp_1 is changed + - cm_add_interface_policy_mcp_1.previous == [] + - cm_add_interface_policy_mcp_1.current == [] + - nm_add_interface_policy_mcp_1 is changed + - nm_add_interface_policy_mcp_1.current.0.mcpIfPol.attributes.name == "anstest_policy" + - nm_add_interface_policy_mcp_1.current.0.mcpIfPol.attributes.adminSt == "disabled" + - idempotency_add_interface_policy_mcp_1 is not changed + - nm_add_interface_policy_mcp_2 is changed + - nm_add_interface_policy_mcp_2.current.0.mcpIfPol.attributes.name == "anstest_policy_2" + - nm_add_interface_policy_mcp_2.current.0.mcpIfPol.attributes.adminSt == "enabled" + + - name: Query all mcp interface policies + aci_interface_policy_mcp: + <<: *aci_info + state: query + register: query_all_interface_policy_mcp + + - name: Query first mcp interface policy + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present + state: query + register: query_first_interface_policy_mcp + + - name: Asserts for query tasks + assert: + that: + - query_all_interface_policy_mcp is not changed + - query_all_interface_policy_mcp.current | length >= 2 + - '"class/mcpIfPol.json" in query_all_interface_policy_mcp.url' + - query_first_interface_policy_mcp is not changed + - query_first_interface_policy_mcp.current.0.mcpIfPol.attributes.name == "anstest_policy" + - query_first_interface_policy_mcp.current.0.mcpIfPol.attributes.adminSt == "disabled" + + - name: Delete first mcp interface policy (check_mode) + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present + state: absent + check_mode: true + register: cm_delete_interface_policy_mcp_1 + + - name: Delete first mcp interface policy (normal_mode) + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present + state: absent + register: nm_delete_interface_policy_mcp_1 + + - name: Delete first mcp interface policy again - testing idempotency + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present + state: absent + register: idempotency_delete_interface_policy_mcp_1 + + - name: Delete second mcp interface policy (normal_mode) + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_2_present + state: absent + register: nm_delete_interface_policy_mcp_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_interface_policy_mcp_1 is changed + - cm_delete_interface_policy_mcp_1.proposed == {} + - nm_delete_interface_policy_mcp_1 is changed + - nm_delete_interface_policy_mcp_1.previous != [] + - nm_delete_interface_policy_mcp_1.current == [] + - idempotency_delete_interface_policy_mcp_1 is not changed + - idempotency_delete_interface_policy_mcp_1.previous == [] + - nm_delete_interface_policy_mcp_2 is changed + - nm_delete_interface_policy_mcp_2.previous != [] + - nm_delete_interface_policy_mcp_2.current == [] diff --git a/tests/integration/targets/aci_interface_policy_port_channel/aliases b/tests/integration/targets/aci_interface_policy_port_channel/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_port_channel/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_interface_policy_port_channel/tasks/main.yml b/tests/integration/targets/aci_interface_policy_port_channel/tasks/main.yml new file mode 100644 index 000000000..36c84b30f --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_port_channel/tasks/main.yml @@ -0,0 +1,174 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: Ensure first port channel interface policy does not exist + aci_interface_policy_port_channel: &aci_interface_policy_port_channel_absent + <<: *aci_info + name: anstest_policy + description: test for port channel interface policy + max_links: 8 + min_links: 2 + mode: active + fast_select: false + graceful_convergence: false + load_defer: true + suspend_individual: false + symmetric_hash: true + state: absent + + - name: Ensure second port channel interface policy does not exist + aci_interface_policy_port_channel: &aci_interface_policy_port_channel_2_absent + <<: *aci_info + name: anstest_policy_2 + fast_select: true + graceful_convergence: true + suspend_individual: true + state: absent + + - name: Create first port channel interface policy (check_mode) + aci_interface_policy_port_channel: &aci_interface_policy_port_channel_present + <<: *aci_interface_policy_port_channel_absent + state: present + check_mode: true + register: cm_add_interface_policy_port_channel_1 + + - name: Create first port channel interface policy (normal_mode) + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + register: nm_add_interface_policy_port_channel_1 + + - name: Create first port channel interface policy again - testing idempotency + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + register: idempotency_add_interface_policy_port_channel_1 + + - name: Create second port channel interface policy + aci_interface_policy_port_channel: &aci_interface_policy_port_channel_2_present + <<: *aci_interface_policy_port_channel_2_absent + state: present + register: nm_add_interface_policy_port_channel_2 + + - name: Modify first port channel interface policy with max links above 16 - testing failure message + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + max_links: 17 + ignore_errors: true + register: nm_policy_port_channel_max_links_failure + + - name: Modify first port channel interface policy with min links bellow 1 - testing failure message + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + min_links: 0 + ignore_errors: true + register: nm_policy_port_channel_min_links_failure + + - name: Asserts for creation tasks + assert: + that: + - cm_add_interface_policy_port_channel_1 is changed + - cm_add_interface_policy_port_channel_1.previous == [] + - cm_add_interface_policy_port_channel_1.current == [] + - nm_add_interface_policy_port_channel_1 is changed + - nm_add_interface_policy_port_channel_1.current.0.lacpLagPol.attributes.name == "anstest_policy" + - nm_add_interface_policy_port_channel_1.current.0.lacpLagPol.attributes.ctrl == "load-defer,symmetric-hash" + - nm_add_interface_policy_port_channel_1.current.0.lacpLagPol.attributes.maxLinks == "8" + - nm_add_interface_policy_port_channel_1.current.0.lacpLagPol.attributes.minLinks == "2" + - nm_add_interface_policy_port_channel_1.current.0.lacpLagPol.attributes.mode == "active" + - idempotency_add_interface_policy_port_channel_1 is not changed + - nm_add_interface_policy_port_channel_2 is changed + - nm_add_interface_policy_port_channel_2.current.0.lacpLagPol.attributes.name == "anstest_policy_2" + - nm_add_interface_policy_port_channel_2.current.0.lacpLagPol.attributes.ctrl == "fast-sel-hot-stdby,graceful-conv,susp-individual" + - nm_add_interface_policy_port_channel_2.current.0.lacpLagPol.attributes.maxLinks == "16" + - nm_add_interface_policy_port_channel_2.current.0.lacpLagPol.attributes.minLinks == "1" + - nm_add_interface_policy_port_channel_2.current.0.lacpLagPol.attributes.mode == "off" + - nm_policy_port_channel_max_links_failure.msg == "The \"max_links\" must be a value between 1 and 16" + - nm_policy_port_channel_min_links_failure.msg == "The \"min_links\" must be a value between 1 and 16" + + - name: Query all port channel interface policies + aci_interface_policy_port_channel: + <<: *aci_info + state: query + register: query_all_interface_policy_port_channel + + - name: Query first port channel interface policy + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + state: query + register: query_first_interface_policy_port_channel + + - name: Asserts for query tasks + assert: + that: + - query_all_interface_policy_port_channel is not changed + - query_all_interface_policy_port_channel.current | length >= 2 + - '"class/lacpLagPol.json" in query_all_interface_policy_port_channel.url' + - query_first_interface_policy_port_channel is not changed + - query_first_interface_policy_port_channel.current.0.lacpLagPol.attributes.name == "anstest_policy" + - query_first_interface_policy_port_channel.current.0.lacpLagPol.attributes.ctrl == "load-defer,symmetric-hash" + - query_first_interface_policy_port_channel.current.0.lacpLagPol.attributes.maxLinks == "8" + - query_first_interface_policy_port_channel.current.0.lacpLagPol.attributes.minLinks == "2" + - query_first_interface_policy_port_channel.current.0.lacpLagPol.attributes.mode == "active" + + - name: Delete first port channel interface policy (check_mode) + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + state: absent + check_mode: true + register: cm_delete_interface_policy_port_channel_1 + + - name: Delete first port channel interface policy (normal_mode) + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + state: absent + register: nm_delete_interface_policy_port_channel_1 + + - name: Delete first port channel interface policy again - testing idempotency + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_present + state: absent + register: idempotency_delete_interface_policy_port_channel_1 + + - name: Delete second port channel interface policy (normal_mode) + aci_interface_policy_port_channel: + <<: *aci_interface_policy_port_channel_2_present + state: absent + register: nm_delete_interface_policy_port_channel_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_interface_policy_port_channel_1 is changed + - cm_delete_interface_policy_port_channel_1.proposed == {} + - nm_delete_interface_policy_port_channel_1 is changed + - nm_delete_interface_policy_port_channel_1.previous != [] + - nm_delete_interface_policy_port_channel_1.current == [] + - idempotency_delete_interface_policy_port_channel_1 is not changed + - idempotency_delete_interface_policy_port_channel_1.previous == [] + - nm_delete_interface_policy_port_channel_2 is changed + - nm_delete_interface_policy_port_channel_2.previous != [] + - nm_delete_interface_policy_port_channel_2.current == [] From 44d7d075e575fa34abcf10fd65d19c59a9725ff9 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 18 Jul 2023 14:02:10 -0400 Subject: [PATCH 06/31] [ignore] Modify fabricNodeBlk class object for aci_maintenance_group_node and aci_firmware_group_node. --- plugins/modules/aci_firmware_group_node.py | 5 ++++- plugins/modules/aci_maintenance_group_node.py | 5 ++++- .../targets/aci_maintenance_group_node/tasks/main.yml | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/modules/aci_firmware_group_node.py b/plugins/modules/aci_firmware_group_node.py index b41a2601b..8d28f85bf 100644 --- a/plugins/modules/aci_firmware_group_node.py +++ b/plugins/modules/aci_firmware_group_node.py @@ -221,6 +221,9 @@ def main(): group = module.params.get("group") node = module.params.get("node") name_alias = module.params.get("name_alias") + block_name = None + if node is not None: + block_name = "blk{0}-{0}".format(node) aci = ACIModule(module) aci.construct_url( @@ -233,7 +236,7 @@ def main(): subclass_1=dict( aci_class="fabricNodeBlk", aci_rn="nodeblk-blk{0}-{0}".format(node), - target_filter={"name": node}, + target_filter={"name": block_name}, module_object=node, ), ) diff --git a/plugins/modules/aci_maintenance_group_node.py b/plugins/modules/aci_maintenance_group_node.py index 272143410..1e5c86db9 100644 --- a/plugins/modules/aci_maintenance_group_node.py +++ b/plugins/modules/aci_maintenance_group_node.py @@ -218,6 +218,9 @@ def main(): group = module.params.get("group") node = module.params.get("node") name_alias = module.params.get("name_alias") + block_name = None + if node is not None: + block_name = "blk{0}-{0}".format(node) aci = ACIModule(module) aci.construct_url( @@ -230,7 +233,7 @@ def main(): subclass_1=dict( aci_class="fabricNodeBlk", aci_rn="nodeblk-blk{0}-{0}".format(node), - target_filter={"name": "blk{0}-{0}".format(node)}, + target_filter={"name": block_name}, module_object=node, ), ) diff --git a/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml b/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml index 472f59c4d..0198285b1 100644 --- a/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml @@ -90,8 +90,12 @@ - cm_add_maintenance_group_node_1.previous == [] - cm_add_maintenance_group_node_1.current == [] - nm_add_maintenance_group_node_1 is changed + - nm_add_maintenance_group_node_1.current.0.fabricNodeBlk.attributes.from_ == "1001" + - nm_add_maintenance_group_node_1.current.0.fabricNodeBlk.attributes.to_ == "1001" - idempotency_add_maintenance_group_node_1 is not changed - nm_add_maintenance_group_node_2 is changed + - nm_add_maintenance_group_node_2.current.0.fabricNodeBlk.attributes.from_ == "1002" + - nm_add_maintenance_group_node_2.current.0.fabricNodeBlk.attributes.to_ == "1002" - name: Query all maintenance group nodes @@ -110,7 +114,10 @@ assert: that: - query_all_maintenance_group_node is not changed + - query_all_maintenance_group_node.current | length >= 2 - query_first_maintenance_group_node is not changed + - query_first_maintenance_group_node.current.0.fabricNodeBlk.attributes.from_ == "1001" + - query_first_maintenance_group_node.current.0.fabricNodeBlk.attributes.to_ == "1001" - name: Delete first maintenance group (check_mode) aci_maintenance_group_node: From aae0a863242008fac8910c6a1cecfa0c788c9088 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 19 Jul 2023 14:18:31 -0400 Subject: [PATCH 07/31] [ignore] Add test cases for aci_tenant_action_rule and aci_tenant_ep_retention_policy. --- .../modules/aci_tenant_ep_retention_policy.py | 4 +- .../aci_tenant_action_rule_profile/aliases | 2 + .../tasks/main.yml | 146 ++++++++++++ .../aci_tenant_ep_retention_policy/aliases | 2 + .../tasks/main.yml | 214 ++++++++++++++++++ 5 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 tests/integration/targets/aci_tenant_action_rule_profile/aliases create mode 100644 tests/integration/targets/aci_tenant_action_rule_profile/tasks/main.yml create mode 100644 tests/integration/targets/aci_tenant_ep_retention_policy/aliases create mode 100644 tests/integration/targets/aci_tenant_ep_retention_policy/tasks/main.yml diff --git a/plugins/modules/aci_tenant_ep_retention_policy.py b/plugins/modules/aci_tenant_ep_retention_policy.py index c1896bb3a..c499adaaa 100644 --- a/plugins/modules/aci_tenant_ep_retention_policy.py +++ b/plugins/modules/aci_tenant_ep_retention_policy.py @@ -253,7 +253,7 @@ BOUNCE_TRIG_MAPPING = dict( coop="protocol", - rarp="rarp-flood", + flood="rarp-flood", ) @@ -308,7 +308,7 @@ def main(): if move_frequency == 0: move_frequency = "none" remote_ep_interval = module.params.get("remote_ep_interval") - if remote_ep_interval is not None and remote_ep_interval not in range(120, 65536): + if remote_ep_interval is not None and remote_ep_interval != 0 and remote_ep_interval not in range(120, 65536): module.fail_json(msg="The remote_ep_interval must be a value of 0 or between 120 and 65535") if remote_ep_interval == 0: remote_ep_interval = "infinite" diff --git a/tests/integration/targets/aci_tenant_action_rule_profile/aliases b/tests/integration/targets/aci_tenant_action_rule_profile/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_tenant_action_rule_profile/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_tenant_action_rule_profile/tasks/main.yml b/tests/integration/targets/aci_tenant_action_rule_profile/tasks/main.yml new file mode 100644 index 000000000..b993b0e33 --- /dev/null +++ b/tests/integration/targets/aci_tenant_action_rule_profile/tasks/main.yml @@ -0,0 +1,146 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: create tenant + aci_tenant: &aci_tenant_present + <<: *aci_info + tenant: ansible_test + state: present + + - name: Ensure first action rule profile does not exist + aci_tenant_action_rule_profile: &aci_tenant_action_rule_profile_absent + <<: *aci_tenant_present + name: anstest + description: test for action rule profile + state: absent + + - name: Ensure second action rule profile does not exist + aci_tenant_action_rule_profile: &aci_tenant_action_rule_profile_2_absent + <<: *aci_tenant_present + name: anstest_2 + state: absent + + - name: Create first action rule profile (check_mode) + aci_tenant_action_rule_profile: &aci_tenant_action_rule_profile_present + <<: *aci_tenant_action_rule_profile_absent + state: present + check_mode: true + register: cm_add_tenant_action_rule_profile_1 + + - name: Create first action rule profile (normal_mode) + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_present + register: nm_add_tenant_action_rule_profile_1 + + - name: Create first action rule profile again - testing idempotency + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_present + register: idempotency_add_tenant_action_rule_profile_1 + + - name: Create second action rule profile + aci_tenant_action_rule_profile: &aci_tenant_action_rule_profile_2_present + <<: *aci_tenant_action_rule_profile_2_absent + state: present + register: nm_add_tenant_action_rule_profile_2 + + - name: Asserts for creation tasks + assert: + that: + - cm_add_tenant_action_rule_profile_1 is changed + - cm_add_tenant_action_rule_profile_1.previous == [] + - cm_add_tenant_action_rule_profile_1.current == [] + - nm_add_tenant_action_rule_profile_1 is changed + - nm_add_tenant_action_rule_profile_1.current.0.rtctrlAttrP.attributes.name == "anstest" + - idempotency_add_tenant_action_rule_profile_1 is not changed + - nm_add_tenant_action_rule_profile_2 is changed + - nm_add_tenant_action_rule_profile_2.current.0.rtctrlAttrP.attributes.name == "anstest_2" + + - name: Query all action rule profiles + aci_tenant_action_rule_profile: + <<: *aci_info + state: query + register: query_all_tenant_action_rule_profile + + - name: Query first action rule profile + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_present + state: query + register: query_first_tenant_action_rule_profile + + - name: Asserts for query tasks + assert: + that: + - query_all_tenant_action_rule_profile is not changed + - query_all_tenant_action_rule_profile.current | length >= 2 + - '"class/rtctrlAttrP.json" in query_all_tenant_action_rule_profile.url' + - query_first_tenant_action_rule_profile is not changed + - query_first_tenant_action_rule_profile.current.0.rtctrlAttrP.attributes.name == "anstest" + + - name: Delete first action rule profile (check_mode) + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_present + state: absent + check_mode: true + register: cm_delete_tenant_action_rule_profile_1 + + - name: Delete first action rule profile (normal_mode) + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_present + state: absent + register: nm_delete_tenant_action_rule_profile_1 + + - name: Delete first action rule profile again - testing idempotency + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_present + state: absent + register: idempotency_delete_tenant_action_rule_profile_1 + + - name: Delete second action rule profile (normal_mode) + aci_tenant_action_rule_profile: + <<: *aci_tenant_action_rule_profile_2_present + state: absent + register: nm_delete_tenant_action_rule_profile_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_tenant_action_rule_profile_1 is changed + - cm_delete_tenant_action_rule_profile_1.proposed == {} + - nm_delete_tenant_action_rule_profile_1 is changed + - nm_delete_tenant_action_rule_profile_1.previous != [] + - nm_delete_tenant_action_rule_profile_1.current == [] + - idempotency_delete_tenant_action_rule_profile_1 is not changed + - idempotency_delete_tenant_action_rule_profile_1.previous == [] + - nm_delete_tenant_action_rule_profile_2 is changed + - nm_delete_tenant_action_rule_profile_2.previous != [] + - nm_delete_tenant_action_rule_profile_2.current == [] + + - name: Delete tenant - clean up the environment + aci_tenant: + <<: *aci_tenant_present + state: absent \ No newline at end of file diff --git a/tests/integration/targets/aci_tenant_ep_retention_policy/aliases b/tests/integration/targets/aci_tenant_ep_retention_policy/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_tenant_ep_retention_policy/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_tenant_ep_retention_policy/tasks/main.yml b/tests/integration/targets/aci_tenant_ep_retention_policy/tasks/main.yml new file mode 100644 index 000000000..96ba34077 --- /dev/null +++ b/tests/integration/targets/aci_tenant_ep_retention_policy/tasks/main.yml @@ -0,0 +1,214 @@ +# Test code for the ACI modules +# Copyright: (c) 2023, Gaspard Micol (@gmicol) + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Test that we have an ACI APIC host, ACI username and ACI password + fail: + msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' + when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined + +- name: Set vars + set_fact: + aci_info: &aci_info + host: "{{ aci_hostname }}" + username: "{{ aci_username }}" + password: "{{ aci_password }}" + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: debug + +- name: Verify Cloud and Non-Cloud Sites in use. + include_tasks: ../../../../../../integration/targets/aci_cloud_provider/tasks/main.yml + +- name: Execute tasks only for non-cloud sites + when: query_cloud.current == [] # This condition will execute only non-cloud sites + block: # block specifies execution of tasks within, based on conditions + # Clean Environment + - name: create tenant + aci_tenant: &aci_tenant_present + <<: *aci_info + tenant: ansible_test + state: present + + - name: Ensure first EP retention protocol policy does not exist + aci_tenant_ep_retention_policy: &aci_tenant_ep_retention_policy_absent + <<: *aci_tenant_present + name: ep_policy_anstest + description: test for EP retention protocol policy + bounce_age: 300 + bounce_trigger: flood + hold_interval: 600 + local_ep_interval: 1800 + remote_ep_interval: 600 + move_frequency: 512 + state: absent + + - name: Ensure second EP retention protocol policy does not exist + aci_tenant_ep_retention_policy: &aci_tenant_ep_retention_policy_2_absent + <<: *aci_tenant_present + name: ep_policy_anstest_2 + bounce_age: 0 + local_ep_interval: 0 + remote_ep_interval: 0 + move_frequency: 0 + state: absent + + - name: Create first EP retention protocol policy (check_mode) + aci_tenant_ep_retention_policy: &aci_tenant_ep_retention_policy_present + <<: *aci_tenant_ep_retention_policy_absent + state: present + check_mode: true + register: cm_add_tenant_ep_retention_policy_1 + + - name: Create first EP retention protocol policy (normal_mode) + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + register: nm_add_tenant_ep_retention_policy_1 + + - name: Create first EP retention protocol policy again - testing idempotency + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + register: idempotency_add_tenant_ep_retention_policy_1 + + - name: Create second EP retention protocol policy + aci_tenant_ep_retention_policy: &aci_tenant_ep_retention_policy_2_present + <<: *aci_tenant_ep_retention_policy_2_absent + state: present + register: nm_add_tenant_ep_retention_policy_2 + + - name: Modify EP retention protocol policy bounce age - testing failure message + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + bounce_age: 100 + ignore_errors: true + register: Modify_tenant_ep_retention_policy_bounce_age + + - name: Modify EP retention protocol policy hold interval - testing failure message + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + hold_interval: 4 + ignore_errors: true + register: Modify_tenant_ep_retention_policy_hold_interval + + - name: Modify EP retention protocol policy move frequency - testing failure message + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + move_frequency: 65540 + ignore_errors: true + register: Modify_tenant_ep_retention_policy_move_frequency + + - name: Modify EP retention protocol policy local ep interval - testing failure message + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + local_ep_interval: 119 + ignore_errors: true + register: Modify_tenant_ep_retention_policy_local_ep_interval + + - name: Modify EP retention protocol policy remote ep interval - testing failure message + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + remote_ep_interval: 119 + ignore_errors: true + register: Modify_tenant_ep_retention_policy_remote_ep_interval + + - name: Asserts for creation tasks + assert: + that: + - cm_add_tenant_ep_retention_policy_1 is changed + - cm_add_tenant_ep_retention_policy_1.previous == [] + - cm_add_tenant_ep_retention_policy_1.current == [] + - nm_add_tenant_ep_retention_policy_1 is changed + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.name == "ep_policy_anstest" + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.bounceAgeIntvl == "300" + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.bounceTrig == "rarp-flood" + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.holdIntvl == "600" + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.localEpAgeIntvl == "1800" + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.moveFreq == "512" + - nm_add_tenant_ep_retention_policy_1.current.0.fvEpRetPol.attributes.remoteEpAgeIntvl == "600" + - idempotency_add_tenant_ep_retention_policy_1 is not changed + - nm_add_tenant_ep_retention_policy_2 is changed + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.bounceAgeIntvl == "infinite" + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.bounceTrig == "protocol" + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.holdIntvl == "300" + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.localEpAgeIntvl == "infinite" + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.moveFreq == "none" + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.remoteEpAgeIntvl == "infinite" + - nm_add_tenant_ep_retention_policy_2.current.0.fvEpRetPol.attributes.name == "ep_policy_anstest_2" + - Modify_tenant_ep_retention_policy_bounce_age.msg == "The bounce_age must be a value of 0 or between 150 and 65535" + - Modify_tenant_ep_retention_policy_hold_interval.msg == "The hold_interval must be a value between 5 and 65535" + - Modify_tenant_ep_retention_policy_move_frequency.msg == "The move_frequency must be a value between 0 and 65535" + - Modify_tenant_ep_retention_policy_local_ep_interval.msg == "The local_ep_interval must be a value of 0 or between 120 and 65535" + - Modify_tenant_ep_retention_policy_remote_ep_interval.msg == "The remote_ep_interval must be a value of 0 or between 120 and 65535" + + - name: Query all EP retention protocol policies + aci_tenant_ep_retention_policy: + <<: *aci_info + state: query + register: query_all_tenant_ep_retention_policy + + - name: Query first EP retention protocol policy + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + state: query + register: query_first_tenant_ep_retention_policy + + - name: Asserts for query tasks + assert: + that: + - query_all_tenant_ep_retention_policy is not changed + - query_all_tenant_ep_retention_policy.current | length >= 2 + - '"class/fvEpRetPol.json" in query_all_tenant_ep_retention_policy.url' + - query_first_tenant_ep_retention_policy is not changed + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.name == "ep_policy_anstest" + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.bounceAgeIntvl == "300" + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.bounceTrig == "rarp-flood" + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.holdIntvl == "600" + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.localEpAgeIntvl == "1800" + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.moveFreq == "512" + - query_first_tenant_ep_retention_policy.current.0.fvEpRetPol.attributes.remoteEpAgeIntvl == "600" + + - name: Delete first EP retention protocol policy (check_mode) + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + state: absent + check_mode: true + register: cm_delete_tenant_ep_retention_policy_1 + + - name: Delete first EP retention protocol policy (normal_mode) + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + state: absent + register: nm_delete_tenant_ep_retention_policy_1 + + - name: Delete first EP retention protocol policy again - testing idempotency + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_present + state: absent + register: idempotency_delete_tenant_ep_retention_policy_1 + + - name: Delete second EP retention protocol policy (normal_mode) + aci_tenant_ep_retention_policy: + <<: *aci_tenant_ep_retention_policy_2_present + state: absent + register: nm_delete_tenant_ep_retention_policy_2 + + - name: Asserts for deletion tasks + assert: + that: + - cm_delete_tenant_ep_retention_policy_1 is changed + - cm_delete_tenant_ep_retention_policy_1.proposed == {} + - nm_delete_tenant_ep_retention_policy_1 is changed + - nm_delete_tenant_ep_retention_policy_1.previous != [] + - nm_delete_tenant_ep_retention_policy_1.current == [] + - idempotency_delete_tenant_ep_retention_policy_1 is not changed + - idempotency_delete_tenant_ep_retention_policy_1.previous == [] + - nm_delete_tenant_ep_retention_policy_2 is changed + - nm_delete_tenant_ep_retention_policy_2.previous != [] + - nm_delete_tenant_ep_retention_policy_2.current == [] + + - name: Delete tenant - clean up the environment + aci_tenant: + <<: *aci_tenant_present + state: absent \ No newline at end of file From fe8044489788ae2c37815dc4c8f2a069ea64389c Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 20 Jul 2023 14:48:22 -0400 Subject: [PATCH 08/31] [ignore] Modify modules that were missing test cases. --- plugins/modules/aci_fabric_scheduler.py | 22 +++--- plugins/modules/aci_firmware_group.py | 60 +++++++++++----- plugins/modules/aci_firmware_group_node.py | 32 +++++---- plugins/modules/aci_firmware_policy.py | 42 +++++------ plugins/modules/aci_interface_policy_fc.py | 46 +++++++++++++ plugins/modules/aci_maintenance_group.py | 69 ++++++++++++++++--- plugins/modules/aci_maintenance_group_node.py | 12 +++- plugins/modules/aci_maintenance_policy.py | 9 ++- tests/integration/inventory.networking | 10 +-- .../targets/aci_firmware_group/tasks/main.yml | 8 ++- .../aci_interface_policy_fc/tasks/main.yml | 21 ++++++ .../aci_maintenance_group/tasks/main.yml | 9 +++ 12 files changed, 255 insertions(+), 85 deletions(-) diff --git a/plugins/modules/aci_fabric_scheduler.py b/plugins/modules/aci_fabric_scheduler.py index 6ed30a771..e12e2221c 100644 --- a/plugins/modules/aci_fabric_scheduler.py +++ b/plugins/modules/aci_fabric_scheduler.py @@ -9,16 +9,12 @@ ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} -DOCUMENTATION = """ +DOCUMENTATION = r""" --- module: aci_fabric_scheduler - -short_description: This modules creates ACI schedulers. - - +short_description: This modules creates ACI schedulers (trig:SchedP) description: - - With the module you can create schedule policies that can be a shell, onetime execution or recurring - +- With the module you can create schedule policies that can be a shell, onetime execution or recurring. options: name: description: @@ -78,10 +74,14 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation -- cisco.aci.owner +- module: cisco.aci.aci +- module: cisco.aci.annotation +- module: cisco.aci.owner +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(trig:SchedP). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) """ @@ -131,7 +131,7 @@ state: present """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index 1a9db1a6c..7ac8d40b1 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -1,5 +1,7 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -8,43 +10,57 @@ ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} -DOCUMENTATION = """ +DOCUMENTATION = r""" --- module: aci_firmware_group - -short_description: This module creates a firmware group - - +short_description: Manage firmware groups (firmware:FwGrp) description: - - This module creates a firmware group, so that you can apply firmware policy to nodes. +- This module creates a firmware group, so that you can apply firmware policy to nodes. options: group: description: - - This the name of the firmware group + - This the name of the firmware group. + type: str + policy: + description: + - This is the name of the firmware policy, which was create by aci_firmware_policy. + - It is important that you use the same name as the policy created with aci_firmware_policy. + type: str + type: + description: + - Type of the firmware group. + - The APIC defaults to C(range) when unset during creation. type: str - firmwarepol: + choices: [ ALL, ALL_IN_POD, range ] + description: description: - - This is the name of the firmware policy, which was create by aci_firmware_policy. It is important that - - you use the same name as the policy created with aci_firmware_policy + - Description for the firmware group. type: str + aliases: [ descr ] state: description: - - Use C(present) or C(absent) for adding or removing. - - Use C(query) for listing an object or multiple objects. + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. type: str default: present choices: [ absent, present, query ] name_alias: description: - - The alias for the current object. This relates to the nameAlias field in ACI. + - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: - cisco.aci.aci - cisco.aci.annotation - cisco.aci.owner +seealso: +- module: aci.aci_firmware_policy +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(firmware:FwGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) + - Gaspard Micol (@gmicol) """ @@ -55,7 +71,7 @@ username: admin password: SomeSecretPassword group: fmgroup - firmwarepol: fmpolicy1 + policy: fmpolicy1 state: present delegate_to: localhost @@ -88,7 +104,7 @@ register: query_result """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success @@ -203,7 +219,9 @@ def main(): argument_spec.update(aci_owner_spec()) argument_spec.update( group=dict(type="str"), # Not required for querying all objects - firmwarepol=dict(type="str"), # Not required for querying all objects + policy=dict(type="str"), # Not required for querying all objects + type=dict(type="str", choices=["ALL", "ALL_IN_POD", "range"]), + description=dict(type="str", aliases=["descr"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -213,13 +231,15 @@ def main(): supports_check_mode=True, required_if=[ ["state", "absent", ["group"]], - ["state", "present", ["group", "firmwarepol"]], + ["state", "present", ["group", "policy"]], ], ) state = module.params.get("state") group = module.params.get("group") - firmwarepol = module.params.get("firmwarepol") + policy = module.params.get("policy") + type = module.params.get("type") + description = module.params.get("description") name_alias = module.params.get("name_alias") aci = ACIModule(module) @@ -240,13 +260,15 @@ def main(): aci_class="firmwareFwGrp", class_config=dict( name=group, + descr=description, + type=type, nameAlias=name_alias, ), child_configs=[ dict( firmwareRsFwgrpp=dict( attributes=dict( - tnFirmwareFwPName=firmwarepol, + tnFirmwareFwPName=policy, ), ), ), diff --git a/plugins/modules/aci_firmware_group_node.py b/plugins/modules/aci_firmware_group_node.py index 8d28f85bf..5ddde8961 100644 --- a/plugins/modules/aci_firmware_group_node.py +++ b/plugins/modules/aci_firmware_group_node.py @@ -1,50 +1,54 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type - ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} -DOCUMENTATION = """ +DOCUMENTATION = r""" --- module: aci_firmware_group_node - -short_description: This modules adds and remove nodes from the firmware group - - +short_description: Manage firmware group nodes (fabric:NodeBlk) description: - - This module addes/deletes a node to the firmware group. This modules assigns 1 node at a time. - +- This module addes/deletes a node to the firmware group. This modules assigns 1 node at a time. options: group: description: - - This is the name of the firmware group + - This is the name of the firmware group. type: str node: description: - - The node to be added to the firmware group - the value equals the NodeID + - The node to be added to the firmware group. + - the value equals the NodeID. type: str state: description: - - Use C(present) or C(absent) for adding or removing. - - Use C(query) for listing an object or multiple objects. + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. type: str default: present choices: [ absent, present, query ] name_alias: description: - - The alias for the current object. This relates to the nameAlias field in ACI. + - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: - cisco.aci.aci - cisco.aci.annotation +seealso: +- module: cisco.aci.aci_firmware_group +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:Out). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) + - Gaspard Micol (@gmicol) """ EXAMPLES = r""" @@ -89,7 +93,7 @@ register: query_result """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index bbe37ecfd..7e41f6b6c 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -1,6 +1,7 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- - +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -10,54 +11,55 @@ ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} -DOCUMENTATION = """ +DOCUMENTATION = r""" --- module: aci_firmware_policy - -short_description: This creates a firmware policy - - +short_description: Manage firmware policies (firmware:FwP) description: - - This module creates a firmware policy for firmware groups. The firmware policy is create first and then - - referenced by the firmware group. You will assign the firmware and specify if you want to ignore the compatibility - - check +- This module creates a firmware policy for firmware groups. +- The firmware policy is create first and then referenced by the firmware group. +- You will assign the firmware and specify if you want to ignore the compatibility check. options: name: description: - - Name of the firmware policy + - Name of the firmware policy type: str version: description: - - The version of the firmware associated with this policy. This value is very import as well as constructing - - it correctly. The syntax for this field is n9000-xx.x. If you look at the firmware repository using the UI - - each version will have a "Full Version" column, this is the value you need to use. So, if the Full Version - - is 13.1(1i), the value for this field would be n9000-13.1(1i) + - The version of the firmware associated with this policy. This value is very import as well as constructing + - it correctly. The syntax for this field is n9000-xx.x. If you look at the firmware repository using the UI + - each version will have a "Full Version" column, this is the value you need to use. So, if the Full Version + - is 13.1(1i), the value for this field would be n9000-13.1(1i) type: str ignoreCompat: description: - - Check if compatibility checks should be ignored + - Check if compatibility checks should be ignored type: bool state: description: - - Use C(present) or C(absent) for adding or removing. - - Use C(query) for listing an object or multiple objects. + - 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 name_alias: description: - - The alias for the current object. This relates to the nameAlias field in ACI. + - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: - cisco.aci.aci - cisco.aci.annotation - cisco.aci.owner +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(firmware:FwP). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) + - Gaspard Micol (@gmicol) """ -# FIXME: Add more, better examples EXAMPLES = r""" - name: firmware policy cisco.aci.aci_firmware_policy: @@ -72,7 +74,7 @@ """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success diff --git a/plugins/modules/aci_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index eaf8e1249..41fdf0e59 100644 --- a/plugins/modules/aci_interface_policy_fc.py +++ b/plugins/modules/aci_interface_policy_fc.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -32,6 +33,35 @@ - The APIC defaults to C(f) when unset during creation. type: str choices: [ f, np ] + auto_max_speed: + description: + - The maximum automatic CPU or port speed. + - The APIC defaults to C(32G) when unset during creation. + type: str + choices: [ 2G, 4G, 8G, 16G, 32G ] + fill_pattern: + description: + - Fill Pattern for native FC ports. + - The APIC defaults to C(IDLE) when unset during creation. + type: str + choices: [ ARBFF, IDLE ] + buffer_credits: + description: + - Receive buffer credits for native FC ports. + - The APIC defaults to C(64) when unset during creation. + type: int + speed: + description: + - The CPU or port speed. + - The APIC defaults to C(auto) when unset during creation. + type: str + choices: [ auto, unknown, 2G, 4G, 8G, 16G, 32G ] + trunk_mode: + description: + - Trunking on/off for native FC ports. + - The APIC defaults to C(trunk-off) when unset during creation. + type: str + choices: [ auto, trunk-off, trunk-on, un-init ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -54,6 +84,7 @@ link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Dag Wieers (@dagwieers) +- Gaspard Micol (@gmicol) """ EXAMPLES = r""" @@ -212,6 +243,11 @@ def main(): fc_policy=dict(type="str", aliases=["name"]), # Not required for querying all objects description=dict(type="str", aliases=["descr"]), port_mode=dict(type="str", choices=["f", "np"]), # No default provided on purpose + auto_max_speed=dict(type="str", choices=["2G", "4G", "8G", "16G", "32G"]), + fill_pattern=dict(type="str", choices= ["ARBFF", "IDLE"]), + buffer_credits=dict(type="int"), + speed=dict(type="str", choices=["auto", "unknown", "2G", "4G", "8G", "16G", "32G"]), + trunk_mode=dict(type="str", choices=["auto", "trunk-off", "trunk-on", "un-init"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -227,6 +263,11 @@ def main(): fc_policy = module.params.get("fc_policy") port_mode = module.params.get("port_mode") + auto_max_speed = module.params.get("auto_max_speed") + fill_pattern = module.params.get("fill_pattern") + buffer_credits = module.params.get("buffer_credits") + speed = module.params.get("speed") + trunk_mode = module.params.get("trunk_mode") description = module.params.get("description") state = module.params.get("state") name_alias = module.params.get("name_alias") @@ -250,6 +291,11 @@ def main(): name=fc_policy, descr=description, portMode=port_mode, + automaxspeed= auto_max_speed, + fillPattern=fill_pattern, + rxBBCredit=buffer_credits, + speed=speed, + trunkMode=trunk_mode, nameAlias=name_alias, ), ) diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 98b0df9f2..3685767c9 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -9,40 +10,63 @@ ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} -DOCUMENTATION = """ +DOCUMENTATION = r""" module: aci_maintenance_group -short_description: This creates an ACI maintenance group -notes: - - a maintenance policy (aci_maintenance_policy must be created prior to creating an aci maintenance group +short_description: This creates an ACI maintenance group (maint:MaintGrp) description: - - This modules creates an ACI maintenance group + - This modules creates an ACI maintenance group. options: group: description: - - This is the name of the group + - The name of the maintenance group. type: str policy: description: - - This is the name of the policy that was created using aci_maintenance_policy + - The name of the maintenance policy. + type: str + firmware_nodes_type: + description: + - The firmware type of nodes in the maintenance group. + - The APIC defaults to C(switch) when unset during creation. + type: str + choices: [ cApicPatch, catalog, config, controller, controllerPatch, plugin, pluginPackage, switch, switchPatch, vpod ] + type: + description: + - The type of the maintenance group. + - The APIC defaults to C(range) when unset during creation. type: str + choices: [ ALL, ALL_IN_POD, range ] + description: + description: + - Description for the maintenance group. + type: str + aliases: [ descr ] state: description: - - Use C(present) or C(absent) for adding or removing. - - Use C(query) for listing an object or multiple objects. + - 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 name_alias: description: - - The alias for the current object. This relates to the nameAlias field in ACI. + - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: - cisco.aci.aci - cisco.aci.annotation - cisco.aci.owner +notes: +- A maintenance policy M(cisco.aci.aci_maintenance_policy) must be created prior to creating an aci maintenance group. +seealso: +- module: cisco.aci.aci_maintenance_policy +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(maint:MaintGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) + - Gaspard Micol (@gmicol) """ EXAMPLES = r""" @@ -85,7 +109,7 @@ register: query_result """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success @@ -201,6 +225,23 @@ def main(): argument_spec.update( group=dict(type="str"), # Not required for querying all objects policy=dict(type="str"), # Not required for querying all objects + firmware_nodes_type = dict( + type="str", + choices=[ + "cApicPatch", + "catalog", + "config", + "controller", + "controllerPatch", + "plugin", + "pluginPackage", + "switch", + "switchPatch", + "vpod", + ] + ), + type=dict(type="str", choices=["ALL", "ALL_IN_POD", "range"]), + description=dict(type="str", aliases=["descr"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -217,6 +258,9 @@ def main(): state = module.params.get("state") group = module.params.get("group") policy = module.params.get("policy") + firmware_nodes_type = module.params.get("firmware_nodes_type") + type = module.params.get("type") + description = module.params.get("description") name_alias = module.params.get("name_alias") aci = ACIModule(module) aci.construct_url( @@ -236,6 +280,9 @@ def main(): aci_class="maintMaintGrp", class_config=dict( name=group, + fwtype = firmware_nodes_type, + type=type, + descr=description, nameAlias=name_alias, ), child_configs=[ diff --git a/plugins/modules/aci_maintenance_group_node.py b/plugins/modules/aci_maintenance_group_node.py index 1e5c86db9..be97ede40 100644 --- a/plugins/modules/aci_maintenance_group_node.py +++ b/plugins/modules/aci_maintenance_group_node.py @@ -1,5 +1,7 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -11,7 +13,7 @@ DOCUMENTATION = r""" --- module: aci_maintenance_group_node -short_description: Manage maintenance group nodes +short_description: Manage maintenance group nodes (fabric:NodeBlk) description: - Manage maintenance group nodes options: @@ -22,7 +24,7 @@ node: description: - The node to be added to the maintenance group. - - The value equals the nodeid. + - The value equals the NodeID. type: str state: description: @@ -39,8 +41,14 @@ - cisco.aci.aci - cisco.aci.annotation +seealso: +- module: cisco.aci.aci_maintenance_group +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fabric:NodeBlk). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) +- Gaspard Micol (@gmicol) """ EXAMPLES = r""" diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index ddc62df09..9824ed57c 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -12,7 +13,7 @@ DOCUMENTATION = r""" --- module: aci_maintenance_policy -short_description: Manage firmware maintenance policies +short_description: Manage firmware maintenance policies (maint:MaintP) description: - Manage maintenance policies that defines behavior during an ACI upgrade. options: @@ -64,8 +65,14 @@ notes: - A scheduler is required for this module, which could have been created using the M(cisco.aci.aci_fabric_scheduler) module or via the UI. +seealso: +- module: cisco.aci.aci_fabric_scheduler +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(maint:MaintP). + link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) +- Gaspard Micol (@gmicol) """ EXAMPLES = r""" diff --git a/tests/integration/inventory.networking b/tests/integration/inventory.networking index 357f58758..291aababb 100644 --- a/tests/integration/inventory.networking +++ b/tests/integration/inventory.networking @@ -1,10 +1,10 @@ [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-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-v60 ansible_host=173.36.219.70 aci_hostname=173.36.219.70 -cn-dmz-apic-m1-07-v32 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 +#cn-dmz-apic-m1-07-v32 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 aci_password="sJ94G92#8dq2hx*K4qh" 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 aci_password="sJ94G92#8dq2hx*K4qh" cloud_type=azure region=westus region_2=westus2 vnet_gateway=true [aci:vars] aci_username=ansible_github_ci diff --git a/tests/integration/targets/aci_firmware_group/tasks/main.yml b/tests/integration/targets/aci_firmware_group/tasks/main.yml index e060f3d03..f806770dd 100644 --- a/tests/integration/targets/aci_firmware_group/tasks/main.yml +++ b/tests/integration/targets/aci_firmware_group/tasks/main.yml @@ -37,14 +37,16 @@ aci_firmware_group: &aci_firmware_group_absent <<: *aci_info group: anstest_group - firmwarepol: anstest_policy + policy: anstest_policy + type: ALL + description: test firmware group state: absent - name: Ensure second firmware group does not exist aci_firmware_group: &aci_firmware_group_2_absent <<: *aci_info group: anstest_group_2 - firmwarepol: anstest_policy + policy: anstest_policy state: absent - name: Create first firmware group (check_mode) @@ -78,6 +80,7 @@ - cm_add_firmware_group_1.current == [] - nm_add_firmware_group_1 is changed - nm_add_firmware_group_1.current.0.firmwareFwGrp.attributes.name == "anstest_group" + - nm_add_firmware_group_1.current.0.firmwareFwGrp.attributes.type == "ALL" - nm_add_firmware_group_1.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" - idempotency_add_firmware_group_1 is not changed - nm_add_firmware_group_2 is changed @@ -106,6 +109,7 @@ - '"class/firmwareFwGrp.json" in query_all_firmware_group.url' - query_first_firmware_group is not changed - query_first_firmware_group.current.0.firmwareFwGrp.attributes.name == "anstest_group" + - query_first_firmware_group.current.0.firmwareFwGrp.attributes.type == "ALL" - query_first_firmware_group.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" - name: Delete first firmware group (check_mode) diff --git a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml index c71e266bc..d95553d7c 100644 --- a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml +++ b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml @@ -32,6 +32,11 @@ name: anstest_policy description: test for fc interface policy port_mode: np + auto_max_speed: 16G + fill_pattern: ARBFF + buffer_credits: 32 + speed: 8G + trunk_mode: trunk-on state: absent - name: Ensure second fc interface policy does not exist @@ -72,10 +77,21 @@ - nm_add_interface_policy_fc_1 is changed - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.name == "anstest_policy" - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.portMode == "np" + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.automaxspeed == "16G" + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.fillPattern == "ARBFF" + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.rxBBCredit == "32" + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.speed == "8G" + - nm_add_interface_policy_fc_1.current.0.fcIfPol.attributes.trunkMode == "trunk-on" - idempotency_add_interface_policy_fc_1 is not changed - nm_add_interface_policy_fc_2 is changed - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.name == "anstest_policy_2" - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.portMode == "f" + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.automaxspeed == "32G" + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.fillPattern == "IDLE" + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.rxBBCredit == "64" + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.speed == "auto" + - nm_add_interface_policy_fc_2.current.0.fcIfPol.attributes.trunkMode == "trunk-off" + - idempotency_add_interface_policy_fc_1 is not changed - name: Query all fc interface policies aci_interface_policy_fc: @@ -98,6 +114,11 @@ - query_first_interface_policy_fc is not changed - query_first_interface_policy_fc.current.0.fcIfPol.attributes.name == "anstest_policy" - query_first_interface_policy_fc.current.0.fcIfPol.attributes.portMode == "np" + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.automaxspeed == "16G" + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.fillPattern == "ARBFF" + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.rxBBCredit == "32" + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.speed == "8G" + - query_first_interface_policy_fc.current.0.fcIfPol.attributes.trunkMode == "trunk-on" - name: Delete first fc interface policy (check_mode) aci_interface_policy_fc: diff --git a/tests/integration/targets/aci_maintenance_group/tasks/main.yml b/tests/integration/targets/aci_maintenance_group/tasks/main.yml index f538b2043..55b9c38d0 100644 --- a/tests/integration/targets/aci_maintenance_group/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_group/tasks/main.yml @@ -44,6 +44,9 @@ <<: *aci_info group: anstest_group policy: anstest_policy + firmware_nodes_type: controller + type: ALL + description: test for maintenance group state: absent - name: Ensure second maintenance group does not exist @@ -84,11 +87,15 @@ - cm_add_maintenance_group_1.current == [] - nm_add_maintenance_group_1 is changed - nm_add_maintenance_group_1.current.0.maintMaintGrp.attributes.name == "anstest_group" + - nm_add_maintenance_group_1.current.0.maintMaintGrp.attributes.fwtype == "controller" + - nm_add_maintenance_group_1.current.0.maintMaintGrp.attributes.type == "ALL" - nm_add_maintenance_group_1.current.0.maintMaintGrp.children.0.maintRsMgrpp.attributes.tnMaintMaintPName == "anstest_policy" - idempotency_add_maintenance_group_1 is not changed - nm_add_maintenance_group_2 is changed - nm_add_maintenance_group_2.current.0.maintMaintGrp.attributes.name == "anstest_group_2" - nm_add_maintenance_group_2.current.0.maintMaintGrp.children.0.maintRsMgrpp.attributes.tnMaintMaintPName == "anstest_policy_2" + - nm_add_maintenance_group_2.current.0.maintMaintGrp.attributes.fwtype == "switch" + - nm_add_maintenance_group_2.current.0.maintMaintGrp.attributes.type == "range" - name: Query all maintenance groups @@ -115,6 +122,8 @@ - query_first_maintenance_group is not changed - query_first_maintenance_group.current.0.maintMaintGrp.attributes.name == "anstest_group" - query_first_maintenance_group.current.0.maintMaintGrp.children.0.maintRsMgrpp.attributes.tnMaintMaintPName == "anstest_policy" + - query_first_maintenance_group.current.0.maintMaintGrp.attributes.fwtype == "controller" + - query_first_maintenance_group.current.0.maintMaintGrp.attributes.type == "ALL" - name: Delete first maintenance group (check_mode) aci_maintenance_group: From faabf35debf766494c8011da5201fe4d79456976 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 20 Jul 2023 15:01:35 -0400 Subject: [PATCH 09/31] [ignore] Modify Python modules to check black and sanity tests. --- plugins/modules/aci_firmware_policy.py | 2 +- plugins/modules/aci_interface_policy_fc.py | 4 ++-- plugins/modules/aci_maintenance_group.py | 24 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index 7e41f6b6c..e0c867c41 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -16,7 +16,7 @@ module: aci_firmware_policy short_description: Manage firmware policies (firmware:FwP) description: -- This module creates a firmware policy for firmware groups. +- This module creates a firmware policy for firmware groups. - The firmware policy is create first and then referenced by the firmware group. - You will assign the firmware and specify if you want to ignore the compatibility check. options: diff --git a/plugins/modules/aci_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index 41fdf0e59..1ef61266a 100644 --- a/plugins/modules/aci_interface_policy_fc.py +++ b/plugins/modules/aci_interface_policy_fc.py @@ -244,7 +244,7 @@ def main(): description=dict(type="str", aliases=["descr"]), port_mode=dict(type="str", choices=["f", "np"]), # No default provided on purpose auto_max_speed=dict(type="str", choices=["2G", "4G", "8G", "16G", "32G"]), - fill_pattern=dict(type="str", choices= ["ARBFF", "IDLE"]), + fill_pattern=dict(type="str", choices=["ARBFF", "IDLE"]), buffer_credits=dict(type="int"), speed=dict(type="str", choices=["auto", "unknown", "2G", "4G", "8G", "16G", "32G"]), trunk_mode=dict(type="str", choices=["auto", "trunk-off", "trunk-on", "un-init"]), @@ -291,7 +291,7 @@ def main(): name=fc_policy, descr=description, portMode=port_mode, - automaxspeed= auto_max_speed, + automaxspeed=auto_max_speed, fillPattern=fill_pattern, rxBBCredit=buffer_credits, speed=speed, diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 3685767c9..06eb92e43 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -225,20 +225,20 @@ def main(): argument_spec.update( group=dict(type="str"), # Not required for querying all objects policy=dict(type="str"), # Not required for querying all objects - firmware_nodes_type = dict( + firmware_nodes_type=dict( type="str", choices=[ - "cApicPatch", - "catalog", - "config", - "controller", - "controllerPatch", - "plugin", - "pluginPackage", - "switch", - "switchPatch", + "cApicPatch", + "catalog", + "config", + "controller", + "controllerPatch", + "plugin", + "pluginPackage", + "switch", + "switchPatch", "vpod", - ] + ], ), type=dict(type="str", choices=["ALL", "ALL_IN_POD", "range"]), description=dict(type="str", aliases=["descr"]), @@ -280,7 +280,7 @@ def main(): aci_class="maintMaintGrp", class_config=dict( name=group, - fwtype = firmware_nodes_type, + fwtype=firmware_nodes_type, type=type, descr=description, nameAlias=name_alias, From d28e08b2861ca0636d687ece824cad7377a2bd80 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 20 Jul 2023 15:04:34 -0400 Subject: [PATCH 10/31] [ignore] small changes --- tests/integration/inventory.networking | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration/inventory.networking b/tests/integration/inventory.networking index 291aababb..f3d5d1a29 100644 --- a/tests/integration/inventory.networking +++ b/tests/integration/inventory.networking @@ -1,10 +1,10 @@ [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-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-v60 ansible_host=173.36.219.70 aci_hostname=173.36.219.70 -#cn-dmz-apic-m1-07-v32 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 aci_password="sJ94G92#8dq2hx*K4qh" 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 aci_password="sJ94G92#8dq2hx*K4qh" cloud_type=azure region=westus region_2=westus2 vnet_gateway=true +cn-dmz-apic-m1-07-v32 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 aci_password="sJ94G92#8dq2hx*K4qh" 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 aci_password="sJ94G92#8dq2hx*K4qh" cloud_type=azure region=westus region_2=westus2 vnet_gateway=true [aci:vars] aci_username=ansible_github_ci From 80d1e9a869267d14298acff30ddafb97264843e2 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 20 Jul 2023 15:15:33 -0400 Subject: [PATCH 11/31] [ignore] Modify documentations for aci_firmware and aci_maintenance modules. --- plugins/modules/aci_firmware_group.py | 15 ++++++++------- plugins/modules/aci_firmware_group_node.py | 11 +++++++---- plugins/modules/aci_firmware_policy.py | 8 ++++---- plugins/modules/aci_maintenance_group.py | 7 ++++--- plugins/modules/aci_maintenance_group_node.py | 8 ++++++-- plugins/modules/aci_maintenance_policy.py | 4 ++-- 6 files changed, 31 insertions(+), 22 deletions(-) diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index 7ac8d40b1..e6569d8d6 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -19,12 +19,11 @@ options: group: description: - - This the name of the firmware group. + - The name of the firmware group. type: str policy: description: - - This is the name of the firmware policy, which was create by aci_firmware_policy. - - It is important that you use the same name as the policy created with aci_firmware_policy. + - The name of the firmware policy. type: str type: description: @@ -49,12 +48,14 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation -- cisco.aci.owner +- module: cisco.aci.aci +- module: cisco.aci.annotation +- module: cisco.aci.owner +notes: +- A firmware policy is required for this module, which could have been created using the M(cisco.aci.aci_firmware_policy) module or via the UI. seealso: -- module: aci.aci_firmware_policy +- module: cisco.aci.aci_firmware_policy - name: APIC Management Information Model reference description: More information about the internal APIC class B(firmware:FwGrp). link: https://developer.cisco.com/docs/apic-mim-ref/ diff --git a/plugins/modules/aci_firmware_group_node.py b/plugins/modules/aci_firmware_group_node.py index 5ddde8961..9ea0d2780 100644 --- a/plugins/modules/aci_firmware_group_node.py +++ b/plugins/modules/aci_firmware_group_node.py @@ -19,7 +19,7 @@ options: group: description: - - This is the name of the firmware group. + - The name of the firmware group. type: str node: description: @@ -38,13 +38,16 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation +- module: cisco.aci.aci +- module: cisco.aci.annotation +notes: +- A firmware group is required for this module, which could have been created using the M(cisco.aci.aci_firmware_group) module or via the UI. seealso: +- module: cisco.aci.aci_firmware_policy - module: cisco.aci.aci_firmware_group - name: APIC Management Information Model reference - description: More information about the internal APIC class B(l3ext:Out). + description: More information about the internal APIC class B(fabric:NodeBlk). link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index e0c867c41..358b55a30 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -22,7 +22,7 @@ options: name: description: - - Name of the firmware policy + - The name of the firmware policy type: str version: description: @@ -47,9 +47,9 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation -- cisco.aci.owner +- module: cisco.aci.aci +- module: cisco.aci.annotation +- module: cisco.aci.owner seealso: - name: APIC Management Information Model reference diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 06eb92e43..0eb5583da 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -53,13 +53,14 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation -- cisco.aci.owner +- module: cisco.aci.aci +- module: cisco.aci.annotation +- module: cisco.aci.owner notes: - A maintenance policy M(cisco.aci.aci_maintenance_policy) must be created prior to creating an aci maintenance group. seealso: +- module: cisco.aci.aci_fabric_scheduler - module: cisco.aci.aci_maintenance_policy - name: APIC Management Information Model reference description: More information about the internal APIC class B(maint:MaintGrp). diff --git a/plugins/modules/aci_maintenance_group_node.py b/plugins/modules/aci_maintenance_group_node.py index be97ede40..0a9e9b075 100644 --- a/plugins/modules/aci_maintenance_group_node.py +++ b/plugins/modules/aci_maintenance_group_node.py @@ -38,10 +38,14 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation +- module: cisco.aci.aci +- module: cisco.aci.annotation +notes: +- A maintenance group is required for this module, which could have been created using the M(cisco.aci.aci_maintenance_group) module or via the UI. seealso: +- module: cisco.aci.aci_fabric_scheduler +- module: cisco.aci.aci_maintenance_policy - module: cisco.aci.aci_maintenance_group - name: APIC Management Information Model reference description: More information about the internal APIC class B(fabric:NodeBlk). diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index 9824ed57c..2c8196b3e 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -60,8 +60,8 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- cisco.aci.aci -- cisco.aci.annotation +- module: cisco.aci.aci +- module: cisco.aci.annotation notes: - A scheduler is required for this module, which could have been created using the M(cisco.aci.aci_fabric_scheduler) module or via the UI. From 1155caa68d1e6c1988a25776c4c24e58bab360de Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 20 Jul 2023 15:47:13 -0400 Subject: [PATCH 12/31] Revert "[ignore] Modify documentations for aci_firmware and aci_maintenance modules." This reverts commit 4cc7d94e64872cbc13f8d68f9d257dbf85a4b96d. --- plugins/modules/aci_firmware_group.py | 15 +++++++-------- plugins/modules/aci_firmware_group_node.py | 11 ++++------- plugins/modules/aci_firmware_policy.py | 8 ++++---- plugins/modules/aci_maintenance_group.py | 7 +++---- plugins/modules/aci_maintenance_group_node.py | 8 ++------ plugins/modules/aci_maintenance_policy.py | 4 ++-- 6 files changed, 22 insertions(+), 31 deletions(-) diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index e6569d8d6..7ac8d40b1 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -19,11 +19,12 @@ options: group: description: - - The name of the firmware group. + - This the name of the firmware group. type: str policy: description: - - The name of the firmware policy. + - This is the name of the firmware policy, which was create by aci_firmware_policy. + - It is important that you use the same name as the policy created with aci_firmware_policy. type: str type: description: @@ -48,14 +49,12 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation -- module: cisco.aci.owner +- cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner -notes: -- A firmware policy is required for this module, which could have been created using the M(cisco.aci.aci_firmware_policy) module or via the UI. seealso: -- module: cisco.aci.aci_firmware_policy +- module: aci.aci_firmware_policy - name: APIC Management Information Model reference description: More information about the internal APIC class B(firmware:FwGrp). link: https://developer.cisco.com/docs/apic-mim-ref/ diff --git a/plugins/modules/aci_firmware_group_node.py b/plugins/modules/aci_firmware_group_node.py index 9ea0d2780..5ddde8961 100644 --- a/plugins/modules/aci_firmware_group_node.py +++ b/plugins/modules/aci_firmware_group_node.py @@ -19,7 +19,7 @@ options: group: description: - - The name of the firmware group. + - This is the name of the firmware group. type: str node: description: @@ -38,16 +38,13 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation +- cisco.aci.aci +- cisco.aci.annotation -notes: -- A firmware group is required for this module, which could have been created using the M(cisco.aci.aci_firmware_group) module or via the UI. seealso: -- module: cisco.aci.aci_firmware_policy - module: cisco.aci.aci_firmware_group - name: APIC Management Information Model reference - description: More information about the internal APIC class B(fabric:NodeBlk). + description: More information about the internal APIC class B(l3ext:Out). link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Steven Gerhart (@sgerhart) diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index 358b55a30..e0c867c41 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -22,7 +22,7 @@ options: name: description: - - The name of the firmware policy + - Name of the firmware policy type: str version: description: @@ -47,9 +47,9 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation -- module: cisco.aci.owner +- cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner seealso: - name: APIC Management Information Model reference diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 0eb5583da..06eb92e43 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -53,14 +53,13 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation -- module: cisco.aci.owner +- cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner notes: - A maintenance policy M(cisco.aci.aci_maintenance_policy) must be created prior to creating an aci maintenance group. seealso: -- module: cisco.aci.aci_fabric_scheduler - module: cisco.aci.aci_maintenance_policy - name: APIC Management Information Model reference description: More information about the internal APIC class B(maint:MaintGrp). diff --git a/plugins/modules/aci_maintenance_group_node.py b/plugins/modules/aci_maintenance_group_node.py index 0a9e9b075..be97ede40 100644 --- a/plugins/modules/aci_maintenance_group_node.py +++ b/plugins/modules/aci_maintenance_group_node.py @@ -38,14 +38,10 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation +- cisco.aci.aci +- cisco.aci.annotation -notes: -- A maintenance group is required for this module, which could have been created using the M(cisco.aci.aci_maintenance_group) module or via the UI. seealso: -- module: cisco.aci.aci_fabric_scheduler -- module: cisco.aci.aci_maintenance_policy - module: cisco.aci.aci_maintenance_group - name: APIC Management Information Model reference description: More information about the internal APIC class B(fabric:NodeBlk). diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index 2c8196b3e..9824ed57c 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -60,8 +60,8 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation +- cisco.aci.aci +- cisco.aci.annotation notes: - A scheduler is required for this module, which could have been created using the M(cisco.aci.aci_fabric_scheduler) module or via the UI. From f954a6e7ca534c9d24e1c491aeba79af0799874e Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 20 Jul 2023 16:03:15 -0400 Subject: [PATCH 13/31] [ignore] Modify Documentation for aci_fabric_scheduler to check sanity tests. --- plugins/modules/aci_fabric_scheduler.py | 119 ++++++++++++------------ 1 file changed, 59 insertions(+), 60 deletions(-) diff --git a/plugins/modules/aci_fabric_scheduler.py b/plugins/modules/aci_fabric_scheduler.py index e12e2221c..15de7cd91 100644 --- a/plugins/modules/aci_fabric_scheduler.py +++ b/plugins/modules/aci_fabric_scheduler.py @@ -28,44 +28,43 @@ aliases: [ descr ] recurring: description: - - If you want to make the Scheduler a recurring it would be a "True" and for a - oneTime execution it would be "False". For a shell just exclude this option from - the task + - If you want to make the Scheduler a recurring it would be a C(True) and for a oneTime execution it would be C(False). + - For a shell, just exclude this option from the task. type: bool windowname: description: - - This is the name for your what recurring or oneTime execution + - This is the name for your what recurring or oneTime execution type: str concurCap: description: - - This is the amount of devices that can be executed on at a time + - This is the amount of devices that can be executed on at a time type: int maxTime: description: - - This is the amount MAX amount of time a process can be executed + - This is the amount MAX amount of time a process can be executed type: str date: description: - - This is the date and time that the scheduler will execute + - This is the date and time that the scheduler will execute type: str hour: description: - - This set the hour of execution + - This set the hour of execution type: int minute: description: - - This sets the minute of execution, used in conjunction with hour + - This sets the minute of execution, used in conjunction with hour type: int day: description: - - This sets the day when execution will take place + - This sets the day when execution will take place type: str - default: "every-day" - choices: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday','Sunday', 'even-day', 'odd-day', 'every-day'] + default: every-day + choices: [ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, even-day, odd-day, every-day ] state: description: - - Use C(present) or C(absent) for adding or removing. - - Use C(query) for listing an object or multiple objects. + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. type: str default: present choices: [ absent, present, query ] @@ -74,61 +73,61 @@ - The alias for the current object. This relates to the nameAlias field in ACI. type: str extends_documentation_fragment: -- module: cisco.aci.aci -- module: cisco.aci.annotation -- module: cisco.aci.owner +- cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner seealso: - name: APIC Management Information Model reference description: More information about the internal APIC class B(trig:SchedP). link: https://developer.cisco.com/docs/apic-mim-ref/ author: - - Steven Gerhart (@sgerhart) +- Steven Gerhart (@sgerhart) """ EXAMPLES = r""" - - name: Simple Scheduler (Empty) - cisco.aci.aci_fabric_scheduler: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: false - name: simpleScheduler - state: present - - name: Remove Simple Scheduler - cisco.aci.aci_fabric_scheduler: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: false - name: simpleScheduler - state: absent - - name: One Time Scheduler - cisco.aci.aci_fabric_scheduler: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: false - name: OneTime - windowname: OneTime - recurring: False - concurCap: 20 - date: "2018-11-20T24:00:00" - state: present - - name: Recurring Scheduler - cisco.aci.aci_fabric_scheduler: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: false - name: Recurring - windowname: Recurring - recurring: True - concurCap: 20 - hour: 13 - minute: 30 - day: Tuesday - state: present +- name: Simple Scheduler (Empty) + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: false + name: simpleScheduler + state: present +- name: Remove Simple Scheduler + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: false + name: simpleScheduler + state: absent +- name: One Time Scheduler + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: false + name: OneTime + windowname: OneTime + recurring: False + concurCap: 20 + date: "2018-11-20T24:00:00" + state: present +- name: Recurring Scheduler + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: false + name: Recurring + windowname: Recurring + recurring: True + concurCap: 20 + hour: 13 + minute: 30 + day: Tuesday + state: present """ RETURN = r""" From 40217b6bcc0aaf53f3e46c579c503ae85a8d1782 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Fri, 21 Jul 2023 13:21:47 -0400 Subject: [PATCH 14/31] [ignore] Add missing atttributes for aci_maintenance_policy and aci_firmware_policy. --- plugins/modules/aci_firmware_policy.py | 110 +++++++++++++---- plugins/modules/aci_maintenance_policy.py | 111 +++++++++++++++--- .../targets/aci_bd_to_l3out/tasks/main.yml | 16 +-- .../aci_firmware_policy/tasks/main.yml | 2 +- .../aci_maintenance_policy/tasks/main.yml | 23 +++- 5 files changed, 212 insertions(+), 50 deletions(-) diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index e0c867c41..6b821c9c6 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -22,7 +22,24 @@ options: name: description: - - Name of the firmware policy + - The name of the firmware policy + type: str + effective_on_reboot: + description: + - A property that indicates if the selected firmware version will be active after reboot. + - The firmware must be effective on an unplanned reboot before the scheduled maintenance operation. + type: bool + ignore_compat: + description: + - Check if compatibility checks should be ignored + type: bool + sr_upgrade: + description: + - The SR firware upgrade. + type: bool + sr_version: + description: + - The SR version of the firmware associated with this policy. type: str version: description: @@ -31,10 +48,21 @@ - each version will have a "Full Version" column, this is the value you need to use. So, if the Full Version - is 13.1(1i), the value for this field would be n9000-13.1(1i) type: str - ignoreCompat: + version_check_override: description: - - Check if compatibility checks should be ignored - type: bool + - The version check override. + - This is a directive to ignore the version check for the next install. + - The version check, which occurs during a maintenance window, checks to see if the desired version matches the running version. + - If the versions do not match, the install is performed. If the versions do match, the install is not performed. + - The version check override is a one-time override that performs the install whether or not the versions match. + - The APIC defaults to C(untriggered) when unset during creation. + type: str + choices: [ trigger, trigger-immediate, triggered, untriggered ] + description: + description: + - Description for the firmware policy. + type: str + aliases: [ descr ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -61,17 +89,44 @@ """ EXAMPLES = r""" - - name: firmware policy - cisco.aci.aci_firmware_policy: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: false - name: test2FrmPol - version: n9000-13.2(1m) - ignoreCompat: False - state: present +- name: Create a firmware policy + cisco.aci.aci_firmware_policy: + host: apic + username: admin + password: SomeSecretPassword + name: my_firmware_policy + version: n9000-13.2(1m) + ignore_compat: False + state: present + delegate_to: localhost + +- name: Delete a firmware policy + cisco.aci.aci_firmware_policy: + host: apic + username: admin + password: SomeSecretPassword + name: my_firmware_policy + state: absent + delegate_to: localhost +- name: Query all maintenance policies + cisco.aci.aci_firmware_policy: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific firmware policy + cisco.aci.aci_firmware_policy: + host: apic + username: admin + password: SomeSecretPassword + name: my_firmware_policy + state: query + delegate_to: localhost + register: query_result """ RETURN = r""" @@ -190,8 +245,13 @@ def main(): argument_spec.update(aci_owner_spec()) argument_spec.update( name=dict(type="str"), # Not required for querying all objects + description=dict(type="str", aliases=["descr"]), version=dict(type="str"), - ignoreCompat=dict(type="bool"), + effective_on_reboot=dict(type="bool"), + ignore_compat=dict(type="bool"), + sr_upgrade=dict(type="bool"), + sr_version=dict(type="str"), + version_check_override=dict(type="str", choices=["trigger", "trigger-immediate", "triggered", "untriggered"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -204,18 +264,19 @@ def main(): ["state", "present", ["name", "version"]], ], ) + aci = ACIModule(module) state = module.params.get("state") name = module.params.get("name") + description = module.params.get("description") version = module.params.get("version") + effective_on_reboot = aci.boolean(module.params.get("effective_on_reboot"), "yes", "no") + ignore_compat = aci.boolean(module.params.get("ignore_compat"), "yes", "no") + sr_version = module.params.get("sr_version") + sr_upgrade = aci.boolean(module.params.get("sr_upgrade"), "yes", "no") + version_check_override = module.params.get("version_check_override") name_alias = module.params.get("name_alias") - if module.params.get("ignoreCompat"): - ignore = "yes" - else: - ignore = "no" - - aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class="firmwareFwP", @@ -232,8 +293,13 @@ def main(): aci_class="firmwareFwP", class_config=dict( name=name, + descr=description, version=version, - ignoreCompat=ignore, + effectiveOnReboot=effective_on_reboot, + ignoreCompat=ignore_compat, + srUpgrade=sr_upgrade, + srVersion=sr_version, + versionCheckOverride=version_check_override, nameAlias=name_alias, ), ) diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index 9824ed57c..e947dc616 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -22,12 +22,12 @@ - The name for the maintenance policy. type: str aliases: [ maintenance_policy ] - runmode: + run_mode: description: - Whether the system pauses on error or just continues through it. + - The APIC defaults to C(pauseOnlyOnFailures) when unset during creation. type: str - choices: [ pauseOnlyOnFailures, pauseNever ] - default: pauseOnlyOnFailures + choices: [ pauseAlwaysBetweenSets, pauseOnlyOnFailures, pauseNever ] graceful: description: - Whether the system will bring down the nodes gracefully during an upgrade, which reduces traffic lost. @@ -37,17 +37,69 @@ description: - The name of scheduler that is applied to the policy. type: str - adminst: + admin_state: description: - - Will trigger an immediate upgrade for nodes if adminst is set to triggered. + - The administrative state of the executable policies. + - Will trigger an immediate upgrade for nodes if C(admin_state) is set to triggered. + - The APIC defaults to C(untriggered) when unset during creation. type: str choices: [ triggered, untriggered ] - default: untriggered - ignoreCompat: + download_state: + description: + - The download state of the executable policies. + - The APIC defaults to C(untriggered) when unset during creation. + type: str + choices: [ triggered, untriggered ] + notif_condition: + description: + - Specifies under what pause condition will admin be notified via email/text as configured. + - This notification mechanism is independent of events/faults. + - The APIC defaults to C(notifyOnlyOnFailures) when unset during creation. + type: str + choices: [ notifyAlwaysBetweenSets, notifyNever, notifyOnlyOnFailures ] + smu_operation: + description: + - Specifies SMU operation. + type: str + choices: [ smuInstall, smuUninstall ] + smu_operation_flags: + description: + - Specifies SMU operation flags + - Indicates if node should be reloaded immediately or skip auto reload on SMU Install/Uninstall. + type: str + choices: [ smuReloadImmediate, smuReloadSkip ] + sr_upgrade: + description: + - The SR firware upgrade. + type: bool + sr_version: + description: + - The SR version of the compatibility catalog. + type: str + version: + description: + - The version of the compatibility catalog. + type: str + version_check_override: + description: + - The version check override. + - This is a directive to ignore the version check for the next install. + - The version check, which occurs during a maintenance window, checks to see if the desired version matches the running version. + - If the versions do not match, the install is performed. If the versions do match, the install is not performed. + - The version check override is a one-time override that performs the install whether or not the versions match. + - The APIC defaults to C(untriggered) when unset during creation. + type: str + choices: [ trigger, trigger-immediate, triggered, untriggered ] + ignore_compat: description: - To check whether compatibility checks should be ignored - The APIC defaults to C(false) when unset during creation. type: bool + description: + description: + - Description for the maintenance policy. + type: str + aliases: [ descr ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -230,11 +282,20 @@ def main(): argument_spec.update(aci_annotation_spec()) argument_spec.update( name=dict(type="str", aliases=["maintenance_policy"]), # Not required for querying all objects - runmode=dict(type="str", default="pauseOnlyOnFailures", choices=["pauseOnlyOnFailures", "pauseNever"]), + run_mode=dict(type="str", choices=["pauseAlwaysBetweenSets", "pauseOnlyOnFailures", "pauseNever"]), graceful=dict(type="bool"), scheduler=dict(type="str"), - ignoreCompat=dict(type="bool"), - adminst=dict(type="str", default="untriggered", choices=["triggered", "untriggered"]), + ignore_compat=dict(type="bool"), + admin_state=dict(type="str", choices=["triggered", "untriggered"]), + download_state=dict(type="str", choices=["triggered", "untriggered"]), + notif_condition=dict(type="str", choices=["notifyAlwaysBetweenSets", "notifyNever", "notifyOnlyOnFailures"]), + smu_operation=dict(type="str", choices=["smuInstall", "smuUninstall"]), + smu_operation_flags=dict(type="str", choices=["smuReloadImmediate", "smuReloadSkip"]), + sr_upgrade=dict(type="bool"), + sr_version=dict(type="str"), + version=dict(type="str"), + version_check_override=dict(type="str", choices=["trigger", "trigger-immediate", "triggered", "untriggered"]), + description=dict(type="str", aliases=["descr"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -252,11 +313,20 @@ def main(): state = module.params.get("state") name = module.params.get("name") - runmode = module.params.get("runmode") + run_mode = module.params.get("run_mode") scheduler = module.params.get("scheduler") - adminst = module.params.get("adminst") + admin_state = module.params.get("admin_state") + download_state = module.params.get("download_state") + notif_condition = module.params.get("notif_condition") + smu_operation = module.params.get("smu_operation") + smu_operation_flags = module.params.get("smu_operation_flags") + sr_upgrade = aci.boolean(module.params.get("sr_upgrade")) + sr_version = module.params.get("sr_version") + version = module.params.get("version") + version_check_override = module.params.get("version_check_override") graceful = aci.boolean(module.params.get("graceful")) - ignoreCompat = aci.boolean(module.params.get("ignoreCompat")) + ignore_compat = aci.boolean(module.params.get("ignore_compat")) + description = module.params.get("description") name_alias = module.params.get("name_alias") aci.construct_url( @@ -276,10 +346,19 @@ def main(): aci_class="maintMaintP", class_config=dict( name=name, - runMode=runmode, + descr=description, + runMode=run_mode, graceful=graceful, - adminSt=adminst, - ignoreCompat=ignoreCompat, + adminSt=admin_state, + downloadSt=download_state, + notifCond=notif_condition, + smuOperation=smu_operation, + smuOperationFlags=smu_operation_flags, + srUpgrade=sr_upgrade, + srVersion=sr_version, + version=version, + versionCheckOverride=version_check_override, + ignoreCompat=ignore_compat, nameAlias=name_alias, ), child_configs=[ diff --git a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml index 012d88eaf..487767668 100644 --- a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml +++ b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml @@ -32,48 +32,48 @@ - name: Execute tasks only for non-cloud sites when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions - - name: ensure tenant exists for tests to kick off + - name: Create tenant for tests to kick off cisco.aci.aci_tenant: &aci_tenant_present <<: *aci_tenant_absent state: present - - name: ensure vrf exists for tests to kick off + - name: Create vrf for tests to kick off cisco.aci.aci_vrf: &aci_vrf_present <<: *aci_tenant_present vrf: anstest - - name: ensure first L3out exists for tests to kick off + - name: Create first L3out for tests to kick off cisco.aci.aci_l3out: &aci_l3_out_present <<: *aci_vrf_present l3out: ansible_l3out domain: ansible_dom state: present - - name: ensure second L3out exists for tests to kick off + - name: Create second L3out for tests to kick off cisco.aci.aci_l3out: &aci_l3_out_present_2 <<: *aci_vrf_present l3out: ansible_l3out_2 domain: ansible_dom state: present - - name: ensure first bd exists for tests to kick off + - name: Create first bd for tests to kick off cisco.aci.aci_bd: &aci_bd_present <<: *aci_tenant_present bd: anstest - - name: ensure second bd exists for tests to kick off + - name: Create second bd for tests to kick off cisco.aci.aci_bd: &aci_bd_present_2 <<: *aci_tenant_present bd: anstest_2 - - name: Remove first binding bd_to_l3out for tests to kick off + - name: Ensure first binding bd_to_l3out does not exist for tests to kick off cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_absent <<: *aci_tenant_present bd: anstest l3out: ansible_l3out state: absent - - name: Remove second binding bd_to_l3out for tests to kick off + - name: Ensure second binding bd_to_l3out does not exist for tests to kick off cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_absent_2 <<: *aci_tenant_present bd: anstest_2 diff --git a/tests/integration/targets/aci_firmware_policy/tasks/main.yml b/tests/integration/targets/aci_firmware_policy/tasks/main.yml index 7f872a767..ec0bb88ae 100644 --- a/tests/integration/targets/aci_firmware_policy/tasks/main.yml +++ b/tests/integration/targets/aci_firmware_policy/tasks/main.yml @@ -31,7 +31,7 @@ <<: *aci_info name: anstest_policy version: n9000-15.2(7) - ignoreCompat: True + ignore_compat: true state: absent - name: Ensure second firmware policy does not exist diff --git a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml index a60a93b80..85d7e3a17 100644 --- a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml @@ -36,11 +36,16 @@ aci_maintenance_policy: &aci_maintenance_policy_absent <<: *aci_info name: anstest_policy - runmode: pauseNever + description: test for maintenance policy + run_mode: pauseNever graceful: True scheduler: anstest_scheduler - ignoreCompat: true - adminst: untriggered + ignore_compat: true + admin_state: untriggered + download_state: untriggered + notif_condition: notifyAlwaysBetweenSets + smu_operation: smuInstall + smu_operation_flags: smuReloadSkip state: absent - name: Ensure second maintenance policy does not exist @@ -81,6 +86,10 @@ - cm_add_maintenance_policy_1.current == [] - nm_add_maintenance_policy_1 is changed - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.adminSt == "untriggered" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.downloadSt == "untriggered" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.notifCond == "notifyAlwaysBetweenSets" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.smuOperation == "smuInstall" + - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.smuOperationFlags == "smuReloadSkip" - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.graceful == "yes" - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.ignoreCompat == "yes" - nm_add_maintenance_policy_1.current.0.maintMaintP.attributes.name == "anstest_policy" @@ -91,6 +100,10 @@ - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.adminSt == "untriggered" - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.graceful == "no" - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.ignoreCompat == "no" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.downloadSt == "untriggered" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.notifCond == "notifyOnlyOnFailures" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.smuOperation == "smuInstall" + - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.smuOperationFlags == "smuReloadImmediate" - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.name == "anstest_policy_2" - nm_add_maintenance_policy_2.current.0.maintMaintP.attributes.runMode == "pauseOnlyOnFailures" - nm_add_maintenance_policy_2.current.0.maintMaintP.children.0.maintRsPolScheduler.attributes.tnTrigSchedPName == "anstest_scheduler" @@ -116,6 +129,10 @@ - '"class/maintMaintP.json" in query_all_maintenance_policy.url' - query_first_maintenance_policy is not changed - query_first_maintenance_policy.current.0.maintMaintP.attributes.adminSt == "untriggered" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.downloadSt == "untriggered" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.notifCond == "notifyAlwaysBetweenSets" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.smuOperation == "smuInstall" + - query_first_maintenance_policy.current.0.maintMaintP.attributes.smuOperationFlags == "smuReloadSkip" - query_first_maintenance_policy.current.0.maintMaintP.attributes.graceful == "yes" - query_first_maintenance_policy.current.0.maintMaintP.attributes.ignoreCompat == "yes" - query_first_maintenance_policy.current.0.maintMaintP.attributes.name == "anstest_policy" From bc329b1e4e783d062c18808878da47b1a3dc2879 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 27 Jul 2023 13:18:01 -0400 Subject: [PATCH 15/31] [ignore] Rebase 1. --- plugins/module_utils/constants.py | 17 ++++++++ plugins/modules/aci_fabric_scheduler.py | 18 +++++---- plugins/modules/aci_firmware_group.py | 27 ++++++++----- plugins/modules/aci_firmware_policy.py | 9 ++--- plugins/modules/aci_interface_policy_fc.py | 6 +-- plugins/modules/aci_maintenance_group.py | 40 +++++++------------ .../targets/aci_firmware_group/tasks/main.yml | 5 +-- .../aci_interface_policy_fc/tasks/main.yml | 2 +- .../aci_maintenance_group/tasks/main.yml | 2 +- 9 files changed, 69 insertions(+), 57 deletions(-) diff --git a/plugins/module_utils/constants.py b/plugins/module_utils/constants.py index 4147d0f35..477e3f285 100644 --- a/plugins/module_utils/constants.py +++ b/plugins/module_utils/constants.py @@ -46,3 +46,20 @@ redhat="Redhat", vmware="VMware", ) + +MATCH_TYPE_GROUP_MAPPING = {"all": "ALL", "all_in_pod":"ALL_IN_POD", "range": "range"} + +MATCH_FC_FILL_PATTERN_MAPPING = {"arbff": "ARBFF", "idle": "IDLE"} + +MATCH_FIRMWARE_NODES_TYPE_MAPPING = { + "c_apic_patch": "cApicPatch", + "catalog": "catalog", + "config": "config", + "controller": "controller", + "controller_patch": "controllerPatch", + "plugin": "plugin", + "plugin_package": "pluginPackage", + "switch": "switch", + "switch_patch": "switchPatch", + "vpod": "vpod", +} diff --git a/plugins/modules/aci_fabric_scheduler.py b/plugins/modules/aci_fabric_scheduler.py index 15de7cd91..0d2628e4a 100644 --- a/plugins/modules/aci_fabric_scheduler.py +++ b/plugins/modules/aci_fabric_scheduler.py @@ -33,31 +33,32 @@ type: bool windowname: description: - - This is the name for your what recurring or oneTime execution + - The name of the schedule window. + - Mandatory for the child class object B(trig:AbsWinddowP) type: str concurCap: description: - - This is the amount of devices that can be executed on at a time + - The amount of devices that can be executed on at a time type: int maxTime: description: - - This is the amount MAX amount of time a process can be executed + - The amount MAX amount of time a process can be executed type: str date: description: - - This is the date and time that the scheduler will execute + - The date and time that the scheduler will execute type: str hour: description: - - This set the hour of execution + - The number of hours of execution type: int minute: description: - - This sets the minute of execution, used in conjunction with hour + - The number of minutes of execution, used in conjunction with hour type: int day: description: - - This sets the day when execution will take place + - The number of days when execution will take place type: str default: every-day choices: [ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, even-day, odd-day, every-day ] @@ -94,6 +95,7 @@ validate_certs: false name: simpleScheduler state: present + - name: Remove Simple Scheduler cisco.aci.aci_fabric_scheduler: host: "{{ inventory_hostname }}" @@ -102,6 +104,7 @@ validate_certs: false name: simpleScheduler state: absent + - name: One Time Scheduler cisco.aci.aci_fabric_scheduler: host: "{{ inventory_hostname }}" @@ -114,6 +117,7 @@ concurCap: 20 date: "2018-11-20T24:00:00" state: present + - name: Recurring Scheduler cisco.aci.aci_fabric_scheduler: host: "{{ inventory_hostname }}" diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index 7ac8d40b1..957661eab 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -19,22 +19,23 @@ options: group: description: - - This the name of the firmware group. + - Name of the firmware group. type: str policy: description: - - This is the name of the firmware policy, which was create by aci_firmware_policy. - - It is important that you use the same name as the policy created with aci_firmware_policy. + - Name of the firmware policy + - It is important that you use the same name as the policy created with M(cisco.aci.aci_firmware_policy). type: str - type: + aliases: [ firmwarepol ] + type_group: description: - Type of the firmware group. - The APIC defaults to C(range) when unset during creation. type: str - choices: [ ALL, ALL_IN_POD, range ] + choices: [ all, all_in_pod, range ] description: description: - - Description for the firmware group. + - Description of the firmware group. type: str aliases: [ descr ] state: @@ -53,8 +54,11 @@ - cisco.aci.annotation - cisco.aci.owner +notes: +The C(policy) used must exist before using this module in your playbook. +The M(cisco.aci.aci_firmware_policy) module can be used for this. seealso: -- module: aci.aci_firmware_policy +- module: cisco.aci.aci_firmware_policy - name: APIC Management Information Model reference description: More information about the internal APIC class B(firmware:FwGrp). link: https://developer.cisco.com/docs/apic-mim-ref/ @@ -211,6 +215,7 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_TYPE_GROUP_MAPPING def main(): @@ -219,8 +224,8 @@ def main(): argument_spec.update(aci_owner_spec()) argument_spec.update( group=dict(type="str"), # Not required for querying all objects - policy=dict(type="str"), # Not required for querying all objects - type=dict(type="str", choices=["ALL", "ALL_IN_POD", "range"]), + policy=dict(type="str", aliases=["firmwarepol"]), # Not required for querying all objects + type_group=dict(type="str", choices=list(MATCH_TYPE_GROUP_MAPPING.keys())), description=dict(type="str", aliases=["descr"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), @@ -238,7 +243,7 @@ def main(): state = module.params.get("state") group = module.params.get("group") policy = module.params.get("policy") - type = module.params.get("type") + type_group = MATCH_TYPE_GROUP_MAPPING.get(module.params.get("type")) description = module.params.get("description") name_alias = module.params.get("name_alias") @@ -261,7 +266,7 @@ def main(): class_config=dict( name=group, descr=description, - type=type, + type=type_group, nameAlias=name_alias, ), child_configs=[ diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index 6b821c9c6..f28489f1e 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -17,7 +17,7 @@ short_description: Manage firmware policies (firmware:FwP) description: - This module creates a firmware policy for firmware groups. -- The firmware policy is create first and then referenced by the firmware group. +- The firmware policy is created first and then referenced by the firmware group. - You will assign the firmware and specify if you want to ignore the compatibility check. options: name: @@ -43,10 +43,9 @@ type: str version: description: - - The version of the firmware associated with this policy. This value is very import as well as constructing - - it correctly. The syntax for this field is n9000-xx.x. If you look at the firmware repository using the UI - - each version will have a "Full Version" column, this is the value you need to use. So, if the Full Version - - is 13.1(1i), the value for this field would be n9000-13.1(1i) + - The version of the firmware associated with this policy. + - The syntax for this field is n9000-xx.x. + - if the Full Version is 13.1(1i), the value for this field would be n9000-13.1(1i). type: str version_check_override: description: diff --git a/plugins/modules/aci_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index 1ef61266a..783a5d029 100644 --- a/plugins/modules/aci_interface_policy_fc.py +++ b/plugins/modules/aci_interface_policy_fc.py @@ -233,7 +233,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec - +from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_FC_FILL_PATTERN_MAPPING def main(): argument_spec = aci_argument_spec() @@ -244,7 +244,7 @@ def main(): description=dict(type="str", aliases=["descr"]), port_mode=dict(type="str", choices=["f", "np"]), # No default provided on purpose auto_max_speed=dict(type="str", choices=["2G", "4G", "8G", "16G", "32G"]), - fill_pattern=dict(type="str", choices=["ARBFF", "IDLE"]), + fill_pattern=dict(type="str", choices=list(MATCH_FC_FILL_PATTERN_MAPPING.keys())), buffer_credits=dict(type="int"), speed=dict(type="str", choices=["auto", "unknown", "2G", "4G", "8G", "16G", "32G"]), trunk_mode=dict(type="str", choices=["auto", "trunk-off", "trunk-on", "un-init"]), @@ -264,7 +264,7 @@ def main(): fc_policy = module.params.get("fc_policy") port_mode = module.params.get("port_mode") auto_max_speed = module.params.get("auto_max_speed") - fill_pattern = module.params.get("fill_pattern") + fill_pattern = MATCH_FC_FILL_PATTERN_MAPPING.get(module.params.get("fill_pattern")) buffer_credits = module.params.get("buffer_credits") speed = module.params.get("speed") trunk_mode = module.params.get("trunk_mode") diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 06eb92e43..6e22ead5b 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -24,21 +24,22 @@ description: - The name of the maintenance policy. type: str + aliases: [ maintenancepol ] firmware_nodes_type: description: - The firmware type of nodes in the maintenance group. - The APIC defaults to C(switch) when unset during creation. type: str - choices: [ cApicPatch, catalog, config, controller, controllerPatch, plugin, pluginPackage, switch, switchPatch, vpod ] - type: + choices: [ c_apic_patch, catalog, config, controller, controller_patch, plugin, plugin_package, switch, switch_patch, vpod ] + type_group: description: - The type of the maintenance group. - The APIC defaults to C(range) when unset during creation. type: str - choices: [ ALL, ALL_IN_POD, range ] + choices: [ all, all_in_pod, range ] description: description: - - Description for the maintenance group. + - Description of the maintenance group. type: str aliases: [ descr ] state: @@ -58,7 +59,9 @@ - cisco.aci.owner notes: -- A maintenance policy M(cisco.aci.aci_maintenance_policy) must be created prior to creating an aci maintenance group. +notes: +The C(policy) used must exist before using this module in your playbook. +The M(cisco.aci.aci_maintenance_policy) module can be used for this. seealso: - module: cisco.aci.aci_maintenance_policy - name: APIC Management Information Model reference @@ -215,6 +218,7 @@ """ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec +from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_TYPE_GROUP_MAPPING, MATCH_FIRMWARE_NODES_TYPE_MAPPING from ansible.module_utils.basic import AnsibleModule @@ -224,23 +228,9 @@ def main(): argument_spec.update(aci_owner_spec()) argument_spec.update( group=dict(type="str"), # Not required for querying all objects - policy=dict(type="str"), # Not required for querying all objects - firmware_nodes_type=dict( - type="str", - choices=[ - "cApicPatch", - "catalog", - "config", - "controller", - "controllerPatch", - "plugin", - "pluginPackage", - "switch", - "switchPatch", - "vpod", - ], - ), - type=dict(type="str", choices=["ALL", "ALL_IN_POD", "range"]), + policy=dict(type="str", aliases=["maintenancepol"]), # Not required for querying all objects + firmware_nodes_type=dict(type="str", choices=list(MATCH_FIRMWARE_NODES_TYPE_MAPPING.keys())), + type_group=dict(type="str", choices=list(MATCH_TYPE_GROUP_MAPPING.keys())), description=dict(type="str", aliases=["descr"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), @@ -258,8 +248,8 @@ def main(): state = module.params.get("state") group = module.params.get("group") policy = module.params.get("policy") - firmware_nodes_type = module.params.get("firmware_nodes_type") - type = module.params.get("type") + firmware_nodes_type = MATCH_FIRMWARE_NODES_TYPE_MAPPING.get(module.params.get("firmware_nodes_type")) + type_group = MATCH_TYPE_GROUP_MAPPING.get(module.params.get("type")) description = module.params.get("description") name_alias = module.params.get("name_alias") aci = ACIModule(module) @@ -281,7 +271,7 @@ def main(): class_config=dict( name=group, fwtype=firmware_nodes_type, - type=type, + type=type_group, descr=description, nameAlias=name_alias, ), diff --git a/tests/integration/targets/aci_firmware_group/tasks/main.yml b/tests/integration/targets/aci_firmware_group/tasks/main.yml index f806770dd..0e184094b 100644 --- a/tests/integration/targets/aci_firmware_group/tasks/main.yml +++ b/tests/integration/targets/aci_firmware_group/tasks/main.yml @@ -38,7 +38,7 @@ <<: *aci_info group: anstest_group policy: anstest_policy - type: ALL + type_group: all description: test firmware group state: absent @@ -84,9 +84,6 @@ - nm_add_firmware_group_1.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" - idempotency_add_firmware_group_1 is not changed - nm_add_firmware_group_2 is changed - - nm_add_firmware_group_2.current.0.firmwareFwGrp.attributes.name == "anstest_group_2" - - nm_add_firmware_group_2.current.0.firmwareFwGrp.children.0.firmwareRsFwgrpp.attributes.tnFirmwareFwPName == "anstest_policy" - - name: Query all firmware groups aci_firmware_group: diff --git a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml index d95553d7c..5e039380e 100644 --- a/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml +++ b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml @@ -33,7 +33,7 @@ description: test for fc interface policy port_mode: np auto_max_speed: 16G - fill_pattern: ARBFF + fill_pattern: arbff buffer_credits: 32 speed: 8G trunk_mode: trunk-on diff --git a/tests/integration/targets/aci_maintenance_group/tasks/main.yml b/tests/integration/targets/aci_maintenance_group/tasks/main.yml index 55b9c38d0..2177afbc6 100644 --- a/tests/integration/targets/aci_maintenance_group/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_group/tasks/main.yml @@ -45,7 +45,7 @@ group: anstest_group policy: anstest_policy firmware_nodes_type: controller - type: ALL + type_group: all description: test for maintenance group state: absent From bb28a874829cb5ce8cc9a31e688634934745e4ef Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 27 Jul 2023 13:22:44 -0400 Subject: [PATCH 16/31] [ignore] Rebase 2. --- plugins/module_utils/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/module_utils/constants.py b/plugins/module_utils/constants.py index 477e3f285..132b3e0fd 100644 --- a/plugins/module_utils/constants.py +++ b/plugins/module_utils/constants.py @@ -47,7 +47,7 @@ vmware="VMware", ) -MATCH_TYPE_GROUP_MAPPING = {"all": "ALL", "all_in_pod":"ALL_IN_POD", "range": "range"} +MATCH_TYPE_GROUP_MAPPING = {"all": "ALL", "all_in_pod": "ALL_IN_POD", "range": "range"} MATCH_FC_FILL_PATTERN_MAPPING = {"arbff": "ARBFF", "idle": "IDLE"} From 9ead5a70fea993e343b636eac152d35fb60668b5 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 27 Jul 2023 14:03:48 -0400 Subject: [PATCH 17/31] [ignore] Modify python files for asserting sanity and formating checks. --- plugins/modules/aci_firmware_group.py | 4 ++-- plugins/modules/aci_interface_policy_fc.py | 1 + plugins/modules/aci_maintenance_group.py | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index 957661eab..5b31ad15f 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -55,8 +55,8 @@ - cisco.aci.owner notes: -The C(policy) used must exist before using this module in your playbook. -The M(cisco.aci.aci_firmware_policy) module can be used for this. +- The C(policy) used must exist before using this module in your playbook. +- The M(cisco.aci.aci_firmware_policy) module can be used for this. seealso: - module: cisco.aci.aci_firmware_policy - name: APIC Management Information Model reference diff --git a/plugins/modules/aci_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index 783a5d029..7a565792a 100644 --- a/plugins/modules/aci_interface_policy_fc.py +++ b/plugins/modules/aci_interface_policy_fc.py @@ -235,6 +235,7 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_FC_FILL_PATTERN_MAPPING + def main(): argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 6e22ead5b..c4715e548 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -59,9 +59,8 @@ - cisco.aci.owner notes: -notes: -The C(policy) used must exist before using this module in your playbook. -The M(cisco.aci.aci_maintenance_policy) module can be used for this. +- The C(policy) used must exist before using this module in your playbook. +- The M(cisco.aci.aci_maintenance_policy) module can be used for this. seealso: - module: cisco.aci.aci_maintenance_policy - name: APIC Management Information Model reference From 183c17fdd85ba34e9dd90a7c919ad29af35ef424 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Thu, 27 Jul 2023 14:20:35 -0400 Subject: [PATCH 18/31] [ignore] Modify documentation for aci_interface_policy_fc. --- plugins/modules/aci_interface_policy_fc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/aci_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index 7a565792a..5d1742bb8 100644 --- a/plugins/modules/aci_interface_policy_fc.py +++ b/plugins/modules/aci_interface_policy_fc.py @@ -44,7 +44,7 @@ - Fill Pattern for native FC ports. - The APIC defaults to C(IDLE) when unset during creation. type: str - choices: [ ARBFF, IDLE ] + choices: [ arbff, idle ] buffer_credits: description: - Receive buffer credits for native FC ports. From 67390170e8cb10fbf6e16d4051861aea047e6ef3 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Fri, 28 Jul 2023 13:46:18 -0400 Subject: [PATCH 19/31] [ignore] Modify names of tasks for test files. --- tests/integration/targets/aci_firmware_group/tasks/main.yml | 2 +- .../targets/aci_firmware_group_node/tasks/main.yml | 4 ++-- .../targets/aci_maintenance_group/tasks/main.yml | 4 ++-- .../targets/aci_maintenance_group_node/tasks/main.yml | 6 +++--- .../targets/aci_maintenance_policy/tasks/main.yml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/integration/targets/aci_firmware_group/tasks/main.yml b/tests/integration/targets/aci_firmware_group/tasks/main.yml index 0e184094b..5cf88997c 100644 --- a/tests/integration/targets/aci_firmware_group/tasks/main.yml +++ b/tests/integration/targets/aci_firmware_group/tasks/main.yml @@ -26,7 +26,7 @@ when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions # Clean Environment - - name: Ensure firmware policy exists + - name: Create firmware policy aci_firmware_policy: &aci_firmware_policy_present <<: *aci_info name: anstest_policy diff --git a/tests/integration/targets/aci_firmware_group_node/tasks/main.yml b/tests/integration/targets/aci_firmware_group_node/tasks/main.yml index 7c9d1f31f..8da20a7ca 100644 --- a/tests/integration/targets/aci_firmware_group_node/tasks/main.yml +++ b/tests/integration/targets/aci_firmware_group_node/tasks/main.yml @@ -26,14 +26,14 @@ when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions # Clean Environment - - name: Ensure firmware policy exists + - name: Create firmware policy exists aci_firmware_policy: &aci_firmware_policy_present <<: *aci_info name: anstest_policy version: n9000-15.2(7) state: present - - name: Ensure first firmware group does not exist + - name: Create first firmware group aci_firmware_group: &aci_firmware_group_present <<: *aci_info group: anstest_group diff --git a/tests/integration/targets/aci_maintenance_group/tasks/main.yml b/tests/integration/targets/aci_maintenance_group/tasks/main.yml index 2177afbc6..12284c8a6 100644 --- a/tests/integration/targets/aci_maintenance_group/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_group/tasks/main.yml @@ -26,13 +26,13 @@ when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions # Clean Environment - - name: Ensure Scheduler exists + - name: Create Scheduler aci_fabric_scheduler: &aci_fabric_scheduler_present <<: *aci_info name: anstest_scheduler state: present - - name: Ensure maintenance policy exists + - name: Create maintenance policy aci_maintenance_policy: &aci_maintenance_policy_present <<: *aci_info name: anstest_policy diff --git a/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml b/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml index 0198285b1..9be9ecbe8 100644 --- a/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_group_node/tasks/main.yml @@ -26,20 +26,20 @@ when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions # Clean Environment - - name: Ensure Scheduler exists + - name: Create Scheduler aci_fabric_scheduler: &aci_fabric_scheduler_present <<: *aci_info name: anstest_scheduler state: present - - name: Ensure maintenance policy exists + - name: Create maintenance policy aci_maintenance_policy: &aci_maintenance_policy_present <<: *aci_info name: anstest_policy scheduler: anstest_scheduler state: present - - name: Ensure first maintenance groupe exists + - name: Create maintenance groupe aci_maintenance_group: &aci_maintenance_group_present <<: *aci_info group: anstest_group diff --git a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml index 85d7e3a17..c6bb225c4 100644 --- a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml @@ -26,7 +26,7 @@ when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions # Clean Environment - - name: Ensure Scheduler exists + - name: Create Scheduler aci_fabric_scheduler: &aci_fabric_scheduler_present <<: *aci_info name: anstest_scheduler From 8b5cc1717be3b4f49472ce297472649417811181 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 1 Aug 2023 13:29:54 -0400 Subject: [PATCH 20/31] [ignore] Modify Documentations and module for aci_interface_policy_mcp. --- plugins/modules/aci_fabric_scheduler.py | 20 +-- plugins/modules/aci_interface_policy_lldp.py | 2 +- plugins/modules/aci_interface_policy_mcp.py | 59 +++++++- plugins/modules/aci_interface_policy_ospf.py | 2 +- .../aci_interface_policy_port_channel.py | 2 +- .../aci_interface_policy_mcp/tasks/main.yml | 136 ++++++++++++++++-- 6 files changed, 197 insertions(+), 24 deletions(-) diff --git a/plugins/modules/aci_fabric_scheduler.py b/plugins/modules/aci_fabric_scheduler.py index 0d2628e4a..364bbc7f5 100644 --- a/plugins/modules/aci_fabric_scheduler.py +++ b/plugins/modules/aci_fabric_scheduler.py @@ -12,9 +12,9 @@ DOCUMENTATION = r""" --- module: aci_fabric_scheduler -short_description: This modules creates ACI schedulers (trig:SchedP) +short_description: This module creates ACI schedulers (trig:SchedP) description: -- With the module you can create schedule policies that can be a shell, onetime execution or recurring. +- With the module you can create schedule policies that can be a shell, one-time execution or recurring. options: name: description: @@ -28,37 +28,37 @@ aliases: [ descr ] recurring: description: - - If you want to make the Scheduler a recurring it would be a C(True) and for a oneTime execution it would be C(False). + - If you want to make the scheduler a recurring operation, it should be set C(True) and for a one-time execution it should be C(False). - For a shell, just exclude this option from the task. type: bool windowname: description: - The name of the schedule window. - - Mandatory for the child class object B(trig:AbsWinddowP) + - This is mandatory for the child class object B(trig:AbsWinddowP) type: str concurCap: description: - - The amount of devices that can be executed on at a time + - The amount of devices that can be executed on at a time. type: int maxTime: description: - - The amount MAX amount of time a process can be executed + - The maximum amount of time a process can be executed. type: str date: description: - - The date and time that the scheduler will execute + - The date and time that the scheduler will execute. type: str hour: description: - - The number of hours of execution + - The number of hours of execution. type: int minute: description: - - The number of minutes of execution, used in conjunction with hour + - The number of minutes of execution, used in conjunction with hour. type: int day: description: - - The number of days when execution will take place + - The number of days when execution will take place. type: str default: every-day choices: [ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, even-day, odd-day, every-day ] diff --git a/plugins/modules/aci_interface_policy_lldp.py b/plugins/modules/aci_interface_policy_lldp.py index 8c1299374..12f18c9ee 100644 --- a/plugins/modules/aci_interface_policy_lldp.py +++ b/plugins/modules/aci_interface_policy_lldp.py @@ -23,7 +23,7 @@ aliases: [ name ] description: description: - - The description for the LLDP interface policy name. + - The description of the LLDP interface policy name. type: str aliases: [ descr ] receive_state: diff --git a/plugins/modules/aci_interface_policy_mcp.py b/plugins/modules/aci_interface_policy_mcp.py index 1a25eced5..3ed313e17 100644 --- a/plugins/modules/aci_interface_policy_mcp.py +++ b/plugins/modules/aci_interface_policy_mcp.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2023, Gaspard Micol (@gmicol) # 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 @@ -23,7 +24,7 @@ aliases: [ mcp_interface, name ] description: description: - - The description for the MCP interface. + - The description of the MCP interface. type: str aliases: [ descr ] admin_state: @@ -31,6 +32,38 @@ - Enable or disable admin state. - The APIC defaults to C(true) when unset during creation. type: bool + mcp_mode: + description: + - Instance MCP mode + - The APIC defaults to C(non_strict) when unset during creation. + type: str + choices: [ non_strict, strict ] + grace_period: + description: + - For strict mode, grace period timeout in sec during which early loop detection takes place. + type: int + aliases: [ gracePeriod ] + grace_period_millisec: + description: + - For strict mode, grace period timeout in millisec during which early loop detection takes place + type: int + aliases: [ grace_period_msec, gracePeriodMsec ] + init_delay_time: + description: + - For strict mode, delay time in seconds for mcp to wait before sending BPDUs. + - This gives time for STP on the external network to converge. + type: int + aliases: [ strict_init_delay_time, strictInitDelayTime ] + tx_frequence: + description: + - For strict mode, transmission frequency of MCP packets until grace period on each L2 interface in seconds. + type: int + aliases: [ strict_tx_freq, strictTxFreq ] + tx_frequence_millisec: + description: + - For strict mode, transmission frequency of MCP packets until grace period on each L2 interface in milliseconds + type: int + aliases: [strict_tx_freq_msec, strictTxFreqMsec ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -53,6 +86,7 @@ link: https://developer.cisco.com/docs/apic-mim-ref/ author: - Dag Wieers (@dagwieers) +- Gaspard Micol (@gmicol) """ EXAMPLES = r""" @@ -204,6 +238,11 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec +MATCH_MCP_MODE_MAPPING = { + "non_strict": "off", + "strict": "on" +} + def main(): argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) @@ -212,6 +251,12 @@ def main(): mcp=dict(type="str", aliases=["mcp_interface", "name"]), # Not required for querying all objects description=dict(type="str", aliases=["descr"]), admin_state=dict(type="bool"), + mcp_mode=dict(type="str", choices= list(MATCH_MCP_MODE_MAPPING.keys())), + grace_period=dict(type="int", aliases=["gracePeriod"]), + grace_period_millisec=dict(type="int", aliases=["grace_period_msec", "gracePeriodMsec"]), + init_delay_time=dict(type="int", aliases=["strict_init_delay_time", "strictInitDelayTime"]), + tx_frequence=dict(type="int", aliases=["strict_tx_freq", "strictTxFreq"]), + tx_frequence_millisec=dict(type="int", aliases=["strict_tx_freq_msec", "strictTxFreqMsec"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -230,6 +275,12 @@ def main(): mcp = module.params.get("mcp") description = module.params.get("description") admin_state = aci.boolean(module.params.get("admin_state"), "enabled", "disabled") + mcp_mode = MATCH_MCP_MODE_MAPPING.get(module.params.get("mcp_mode")) + grace_period = module.params.get("grace_period") + grace_period_millisec = module.params.get("grace_period_millisec") + init_delay_time = module.params.get("init_delay_time") + tx_frequence = module.params.get("tx_frequence") + tx_frequence_millisec = module.params.get("tx_frequence_millisec") state = module.params.get("state") name_alias = module.params.get("name_alias") @@ -251,6 +302,12 @@ def main(): name=mcp, descr=description, adminSt=admin_state, + mcpMode = mcp_mode, + gracePeriod = grace_period, + gracePeriodMsec = grace_period_millisec, + strictInitDelayTime = init_delay_time, + strictTxFreq = tx_frequence, + strictTxFreqMsec = tx_frequence_millisec, nameAlias=name_alias, ), ) diff --git a/plugins/modules/aci_interface_policy_ospf.py b/plugins/modules/aci_interface_policy_ospf.py index 7bb918923..5fce567ae 100644 --- a/plugins/modules/aci_interface_policy_ospf.py +++ b/plugins/modules/aci_interface_policy_ospf.py @@ -31,7 +31,7 @@ aliases: [ ospf_interface, name ] description: description: - - The description for the OSPF interface. + - The description of the OSPF interface. type: str aliases: [ descr ] network_type: diff --git a/plugins/modules/aci_interface_policy_port_channel.py b/plugins/modules/aci_interface_policy_port_channel.py index 028bd849b..c6422df9c 100644 --- a/plugins/modules/aci_interface_policy_port_channel.py +++ b/plugins/modules/aci_interface_policy_port_channel.py @@ -23,7 +23,7 @@ aliases: [ name ] description: description: - - The description for the port channel. + - The description of the port channel. type: str aliases: [ descr ] max_links: diff --git a/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml b/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml index a8901eacc..7255c14ad 100644 --- a/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml +++ b/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml @@ -26,6 +26,21 @@ when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions # Clean Environment + - name: Ensure first mcp interface policy does not exist - APIC version >= 5.0 + aci_interface_policy_mcp: &aci_interface_policy_mcp_absent_5 + <<: *aci_info + name: anstest_policy + description: test for mcp interface policy + mcp_mode: strict + grace_period: 4 + grace_period_millisec: 500 + init_delay_time: 5 + tx_frequence: 2 + tx_frequence_millisec: 500 + admin_state: false + state: absent + when: version.current.0.topSystem.attributes.version is version('5', '>=') + - name: Ensure first mcp interface policy does not exist aci_interface_policy_mcp: &aci_interface_policy_mcp_absent <<: *aci_info @@ -33,6 +48,7 @@ description: test for mcp interface policy admin_state: false state: absent + when: version.current.0.topSystem.attributes.version is version('5', '<') - name: Ensure second mcp interface policy does not exist aci_interface_policy_mcp: &aci_interface_policy_mcp_2_absent @@ -40,22 +56,45 @@ name: anstest_policy_2 state: absent - - name: Create first mcp interface policy (check_mode) + - name: Create first mcp interface policy (check_mode) - APIC version >= 5.0 + aci_interface_policy_mcp: &aci_interface_policy_mcp_present_5 + <<: *aci_interface_policy_mcp_absent_5 + state: present + check_mode: true + register: cm_add_interface_policy_mcp_1_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Create first mcp interface policy (normal_mode) - APIC version >= 5.0 + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present_5 + register: nm_add_interface_policy_mcp_1_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Create first mcp interface policy again - testing idempotency - APIC version >= 5.0 + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present_5 + register: idempotency_add_interface_policy_mcp_1_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Create first mcp interface policy (check_mode) - APIC version < 5.0 aci_interface_policy_mcp: &aci_interface_policy_mcp_present <<: *aci_interface_policy_mcp_absent state: present check_mode: true register: cm_add_interface_policy_mcp_1 + when: version.current.0.topSystem.attributes.version is version('5', '<') - - name: Create first mcp interface policy (normal_mode) + - name: Create first mcp interface policy (normal_mode) - APIC version < 5.0 aci_interface_policy_mcp: <<: *aci_interface_policy_mcp_present register: nm_add_interface_policy_mcp_1 + when: version.current.0.topSystem.attributes.version is version('5', '<') - - name: Create first mcp interface policy again - testing idempotency + - name: Create first mcp interface policy again - testing idempotency - APIC version < 5.0 aci_interface_policy_mcp: <<: *aci_interface_policy_mcp_present register: idempotency_add_interface_policy_mcp_1 + when: version.current.0.topSystem.attributes.version is version('5', '<') - name: Create second mcp interface policy aci_interface_policy_mcp: &aci_interface_policy_mcp_2_present @@ -63,7 +102,19 @@ state: present register: nm_add_interface_policy_mcp_2 - - name: Asserts for creation tasks + - name: Asserts for creation tasks for first mcp interface policy - APIC version >= 5.0 + assert: + that: + - cm_add_interface_policy_mcp_1_5 is changed + - cm_add_interface_policy_mcp_1_5.previous == [] + - cm_add_interface_policy_mcp_1_5.current == [] + - nm_add_interface_policy_mcp_1_5 is changed + - nm_add_interface_policy_mcp_1_5.current.0.mcpIfPol.attributes.name == "anstest_policy" + - nm_add_interface_policy_mcp_1_5.current.0.mcpIfPol.attributes.adminSt == "disabled" + - idempotency_add_interface_policy_mcp_1_5 is not changed + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Asserts for creation tasks for first mcp interface policy - APIC version < 5.0 assert: that: - cm_add_interface_policy_mcp_1 is changed @@ -73,6 +124,11 @@ - nm_add_interface_policy_mcp_1.current.0.mcpIfPol.attributes.name == "anstest_policy" - nm_add_interface_policy_mcp_1.current.0.mcpIfPol.attributes.adminSt == "disabled" - idempotency_add_interface_policy_mcp_1 is not changed + when: version.current.0.topSystem.attributes.version is version('5', '<') + + - name: Asserts for creation tasks for second mcp interface policy + assert: + that: - nm_add_interface_policy_mcp_2 is changed - nm_add_interface_policy_mcp_2.current.0.mcpIfPol.attributes.name == "anstest_policy_2" - nm_add_interface_policy_mcp_2.current.0.mcpIfPol.attributes.adminSt == "enabled" @@ -83,11 +139,19 @@ state: query register: query_all_interface_policy_mcp + - name: Query first mcp interface policy + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present_5 + state: query + register: query_first_interface_policy_mcp_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') + - name: Query first mcp interface policy aci_interface_policy_mcp: <<: *aci_interface_policy_mcp_present state: query register: query_first_interface_policy_mcp + when: version.current.0.topSystem.attributes.version is version('5', '<') - name: Asserts for query tasks assert: @@ -95,28 +159,64 @@ - query_all_interface_policy_mcp is not changed - query_all_interface_policy_mcp.current | length >= 2 - '"class/mcpIfPol.json" in query_all_interface_policy_mcp.url' - - query_first_interface_policy_mcp is not changed + + - name: Asserts for individual query tasks - APIC version >= 5.0 + assert: + that: + - query_first_interface_policy_mcp_5.current.0.mcpIfPol.attributes.name == "anstest_policy" + - query_first_interface_policy_mcp_5.current.0.mcpIfPol.attributes.adminSt == "disabled" + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Asserts for individual query tasks - APIC version < 5.0 + assert: + that: - query_first_interface_policy_mcp.current.0.mcpIfPol.attributes.name == "anstest_policy" - query_first_interface_policy_mcp.current.0.mcpIfPol.attributes.adminSt == "disabled" + when: version.current.0.topSystem.attributes.version is version('5', '<') + + - name: Delete first mcp interface policy (check_mode) - APIC version >= 5.0 + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present_5 + state: absent + check_mode: true + register: cm_delete_interface_policy_mcp_1_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') - - name: Delete first mcp interface policy (check_mode) + - name: Delete first mcp interface policy (normal_mode) - APIC version >= 5.0 + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present_5 + state: absent + register: nm_delete_interface_policy_mcp_1_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Delete first mcp interface policy again - testing idempotency - APIC version >= 5.0 + aci_interface_policy_mcp: + <<: *aci_interface_policy_mcp_present_5 + state: absent + register: idempotency_delete_interface_policy_mcp_1_5 + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Delete first mcp interface policy (check_mode) - APIC version < 5.0 aci_interface_policy_mcp: <<: *aci_interface_policy_mcp_present state: absent check_mode: true register: cm_delete_interface_policy_mcp_1 + when: version.current.0.topSystem.attributes.version is version('5', '<') - - name: Delete first mcp interface policy (normal_mode) + - name: Delete first mcp interface policy (normal_mode) - APIC version < 5.0 aci_interface_policy_mcp: <<: *aci_interface_policy_mcp_present state: absent register: nm_delete_interface_policy_mcp_1 + when: version.current.0.topSystem.attributes.version is version('5', '<') - - name: Delete first mcp interface policy again - testing idempotency + - name: Delete first mcp interface policy again - testing idempotency - APIC version < 5.0 aci_interface_policy_mcp: <<: *aci_interface_policy_mcp_present state: absent register: idempotency_delete_interface_policy_mcp_1 + when: version.current.0.topSystem.attributes.version is version('5', '<') - name: Delete second mcp interface policy (normal_mode) aci_interface_policy_mcp: @@ -124,7 +224,19 @@ state: absent register: nm_delete_interface_policy_mcp_2 - - name: Asserts for deletion tasks + - name: Asserts for first mcp interface policy deletion tasks - APIC version >= 5.0 + assert: + that: + - cm_delete_interface_policy_mcp_1_5 is changed + - cm_delete_interface_policy_mcp_1_5.proposed == {} + - nm_delete_interface_policy_mcp_1_5 is changed + - nm_delete_interface_policy_mcp_1_5.previous != [] + - nm_delete_interface_policy_mcp_1_5.current == [] + - idempotency_delete_interface_policy_mcp_1_5 is not changed + - idempotency_delete_interface_policy_mcp_1_5.previous == [] + when: version.current.0.topSystem.attributes.version is version('5', '>=') + + - name: Asserts for first mcp interface policy deletion tasks - APIC version < 5.0 assert: that: - cm_delete_interface_policy_mcp_1 is changed @@ -134,6 +246,10 @@ - nm_delete_interface_policy_mcp_1.current == [] - idempotency_delete_interface_policy_mcp_1 is not changed - idempotency_delete_interface_policy_mcp_1.previous == [] - - nm_delete_interface_policy_mcp_2 is changed + when: version.current.0.topSystem.attributes.version is version('5', '<') + + - name: Asserts for second mcp interface policy deletion tasks + assert: + that: - nm_delete_interface_policy_mcp_2.previous != [] - nm_delete_interface_policy_mcp_2.current == [] From e21850070f6b9ebaaab7beb92ddc2e2a730f5f7b Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 1 Aug 2023 14:03:41 -0400 Subject: [PATCH 21/31] [ignore] Modify Documentations for certain modules. --- plugins/modules/aci_firmware_group.py | 2 +- plugins/modules/aci_firmware_group_node.py | 2 +- plugins/modules/aci_interface_policy_mcp.py | 15 ++++++++------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index 5b31ad15f..eb3c5fd17 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -55,7 +55,7 @@ - cisco.aci.owner notes: -- The C(policy) used must exist before using this module in your playbook. +- The C(policy) must exist before using this module in your playbook. - The M(cisco.aci.aci_firmware_policy) module can be used for this. seealso: - module: cisco.aci.aci_firmware_policy diff --git a/plugins/modules/aci_firmware_group_node.py b/plugins/modules/aci_firmware_group_node.py index 5ddde8961..876004a32 100644 --- a/plugins/modules/aci_firmware_group_node.py +++ b/plugins/modules/aci_firmware_group_node.py @@ -24,7 +24,7 @@ node: description: - The node to be added to the firmware group. - - the value equals the NodeID. + - The value equals the NodeID. type: str state: description: diff --git a/plugins/modules/aci_interface_policy_mcp.py b/plugins/modules/aci_interface_policy_mcp.py index 3ed313e17..771a8d7de 100644 --- a/plugins/modules/aci_interface_policy_mcp.py +++ b/plugins/modules/aci_interface_policy_mcp.py @@ -243,6 +243,7 @@ "strict": "on" } + def main(): argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) @@ -251,7 +252,7 @@ def main(): mcp=dict(type="str", aliases=["mcp_interface", "name"]), # Not required for querying all objects description=dict(type="str", aliases=["descr"]), admin_state=dict(type="bool"), - mcp_mode=dict(type="str", choices= list(MATCH_MCP_MODE_MAPPING.keys())), + mcp_mode=dict(type="str", choices=list(MATCH_MCP_MODE_MAPPING.keys())), grace_period=dict(type="int", aliases=["gracePeriod"]), grace_period_millisec=dict(type="int", aliases=["grace_period_msec", "gracePeriodMsec"]), init_delay_time=dict(type="int", aliases=["strict_init_delay_time", "strictInitDelayTime"]), @@ -302,12 +303,12 @@ def main(): name=mcp, descr=description, adminSt=admin_state, - mcpMode = mcp_mode, - gracePeriod = grace_period, - gracePeriodMsec = grace_period_millisec, - strictInitDelayTime = init_delay_time, - strictTxFreq = tx_frequence, - strictTxFreqMsec = tx_frequence_millisec, + mcpMode=mcp_mode, + gracePeriod=grace_period, + gracePeriodMsec=grace_period_millisec, + strictInitDelayTime=init_delay_time, + strictTxFreq=tx_frequence, + strictTxFreqMsec=tx_frequence_millisec, nameAlias=name_alias, ), ) From 7f5f48ceb50a135519dbff6c17285f500deea8f8 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 1 Aug 2023 14:06:23 -0400 Subject: [PATCH 22/31] [ignore] Modify formating for aci_interface_policy_mcp. --- plugins/modules/aci_interface_policy_mcp.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/modules/aci_interface_policy_mcp.py b/plugins/modules/aci_interface_policy_mcp.py index 771a8d7de..41f802e24 100644 --- a/plugins/modules/aci_interface_policy_mcp.py +++ b/plugins/modules/aci_interface_policy_mcp.py @@ -238,10 +238,7 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec -MATCH_MCP_MODE_MAPPING = { - "non_strict": "off", - "strict": "on" -} +MATCH_MCP_MODE_MAPPING = {"non_strict": "off", "strict": "on"} def main(): From 4a99c2babe1dcfb06647ac70d9164c8688ff46ce Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 2 Aug 2023 21:17:07 -0400 Subject: [PATCH 23/31] Revert "[ignore] Modify formating for aci_interface_policy_mcp." This reverts commit 5619bc45f0f77cc3791b9ab9f2e7e2d540a6513a. --- plugins/modules/aci_interface_policy_mcp.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/modules/aci_interface_policy_mcp.py b/plugins/modules/aci_interface_policy_mcp.py index 41f802e24..771a8d7de 100644 --- a/plugins/modules/aci_interface_policy_mcp.py +++ b/plugins/modules/aci_interface_policy_mcp.py @@ -238,7 +238,10 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec -MATCH_MCP_MODE_MAPPING = {"non_strict": "off", "strict": "on"} +MATCH_MCP_MODE_MAPPING = { + "non_strict": "off", + "strict": "on" +} def main(): From ce449efd7d12ad55e6d0825a98eda7da7768df66 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 2 Aug 2023 21:47:59 -0400 Subject: [PATCH 24/31] [ignore] Modify aci firmware group node, firmware policy and maintenance policy python scripts. --- plugins/modules/aci_firmware_group_node.py | 2 +- plugins/modules/aci_firmware_policy.py | 3 +- plugins/modules/aci_maintenance_policy.py | 34 +++++++++++-------- .../aci_maintenance_policy/tasks/main.yml | 8 ++--- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/plugins/modules/aci_firmware_group_node.py b/plugins/modules/aci_firmware_group_node.py index 876004a32..893eaa867 100644 --- a/plugins/modules/aci_firmware_group_node.py +++ b/plugins/modules/aci_firmware_group_node.py @@ -15,7 +15,7 @@ module: aci_firmware_group_node short_description: Manage firmware group nodes (fabric:NodeBlk) description: -- This module addes/deletes a node to the firmware group. This modules assigns 1 node at a time. +- This module adds/deletes a node to the firmware group. options: group: description: diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index f28489f1e..71611f0d1 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -17,8 +17,7 @@ short_description: Manage firmware policies (firmware:FwP) description: - This module creates a firmware policy for firmware groups. -- The firmware policy is created first and then referenced by the firmware group. -- You will assign the firmware and specify if you want to ignore the compatibility check. +- The compatibility check can be explicitly ignored while assigning the firmware. options: name: description: diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index e947dc616..6bcdddf41 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -27,7 +27,7 @@ - Whether the system pauses on error or just continues through it. - The APIC defaults to C(pauseOnlyOnFailures) when unset during creation. type: str - choices: [ pauseAlwaysBetweenSets, pauseOnlyOnFailures, pauseNever ] + choices: [ pause_always_between_sets, pause_only_on_failures, pause_never ] graceful: description: - Whether the system will bring down the nodes gracefully during an upgrade, which reduces traffic lost. @@ -50,24 +50,24 @@ - The APIC defaults to C(untriggered) when unset during creation. type: str choices: [ triggered, untriggered ] - notif_condition: + notify_condition: description: - Specifies under what pause condition will admin be notified via email/text as configured. - This notification mechanism is independent of events/faults. - The APIC defaults to C(notifyOnlyOnFailures) when unset during creation. type: str - choices: [ notifyAlwaysBetweenSets, notifyNever, notifyOnlyOnFailures ] + choices: [ notify_always_between_sets, notify_never, notify_only_on_failures ] smu_operation: description: - Specifies SMU operation. type: str - choices: [ smuInstall, smuUninstall ] + choices: [ smu_install, smu_uninstall ] smu_operation_flags: description: - Specifies SMU operation flags - Indicates if node should be reloaded immediately or skip auto reload on SMU Install/Uninstall. type: str - choices: [ smuReloadImmediate, smuReloadSkip ] + choices: [ smu_reload_immediate, smu_reload_skip ] sr_upgrade: description: - The SR firware upgrade. @@ -277,20 +277,25 @@ from ansible.module_utils.basic import AnsibleModule +MATCH_RUN_MODE_MAPPING = dict(pause_always_between_sets="pauseAlwaysBetweenSets", pause_only_on_failures="pauseOnlyOnFailures", pause_never="pauseNever") +MATCH_NOTIFY_CONDITION_MAPPING = dict(notify_always_between_sets="notifyAlwaysBetweenSets", notify_never="notifyNever", notify_only_on_failures="notifyOnlyOnFailures") +MATCH_SMU_OPERATION_MAPPING = dict(smu_install="smuInstall", smu_uninstall="smuUninstall") +MATCH_SMU_OPERATION_FLAGS_MAPPING = dict(smu_reload_immediate="smuReloadImmediate", smu_reload_skip="smuReloadSkip") + def main(): argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) argument_spec.update( name=dict(type="str", aliases=["maintenance_policy"]), # Not required for querying all objects - run_mode=dict(type="str", choices=["pauseAlwaysBetweenSets", "pauseOnlyOnFailures", "pauseNever"]), + run_mode=dict(type="str", choices=list(MATCH_RUN_MODE_MAPPING.keys())), graceful=dict(type="bool"), scheduler=dict(type="str"), ignore_compat=dict(type="bool"), admin_state=dict(type="str", choices=["triggered", "untriggered"]), download_state=dict(type="str", choices=["triggered", "untriggered"]), - notif_condition=dict(type="str", choices=["notifyAlwaysBetweenSets", "notifyNever", "notifyOnlyOnFailures"]), - smu_operation=dict(type="str", choices=["smuInstall", "smuUninstall"]), - smu_operation_flags=dict(type="str", choices=["smuReloadImmediate", "smuReloadSkip"]), + notify_condition=dict(type="str", choices=list(MATCH_NOTIFY_CONDITION_MAPPING.keys())), + smu_operation=dict(type="str", choices=list(MATCH_SMU_OPERATION_MAPPING.keys())), + smu_operation_flags=dict(type="str", choices=list(MATCH_SMU_OPERATION_FLAGS_MAPPING.keys())), sr_upgrade=dict(type="bool"), sr_version=dict(type="str"), version=dict(type="str"), @@ -313,14 +318,13 @@ def main(): state = module.params.get("state") name = module.params.get("name") - run_mode = module.params.get("run_mode") + run_mode = MATCH_RUN_MODE_MAPPING.get(module.params.get("run_mode")) scheduler = module.params.get("scheduler") admin_state = module.params.get("admin_state") download_state = module.params.get("download_state") - notif_condition = module.params.get("notif_condition") - smu_operation = module.params.get("smu_operation") - smu_operation_flags = module.params.get("smu_operation_flags") - sr_upgrade = aci.boolean(module.params.get("sr_upgrade")) + notify_condition = MATCH_NOTIFY_CONDITION_MAPPING.get(module.params.get("notify_condition")) + smu_operation = MATCH_SMU_OPERATION_MAPPING.get(module.params.get("smu_operation")) + smu_operation_flags = MATCH_SMU_OPERATION_FLAGS_MAPPING.get(module.params.get("smu_operation_flags")) sr_version = module.params.get("sr_version") version = module.params.get("version") version_check_override = module.params.get("version_check_override") @@ -351,7 +355,7 @@ def main(): graceful=graceful, adminSt=admin_state, downloadSt=download_state, - notifCond=notif_condition, + notifCond=notify_condition, smuOperation=smu_operation, smuOperationFlags=smu_operation_flags, srUpgrade=sr_upgrade, diff --git a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml index c6bb225c4..9377293bf 100644 --- a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml @@ -37,15 +37,15 @@ <<: *aci_info name: anstest_policy description: test for maintenance policy - run_mode: pauseNever + run_mode: pause_never graceful: True scheduler: anstest_scheduler ignore_compat: true admin_state: untriggered download_state: untriggered - notif_condition: notifyAlwaysBetweenSets - smu_operation: smuInstall - smu_operation_flags: smuReloadSkip + notify_condition: notify_always_between_sets + smu_operation: smu_install + smu_operation_flags: smu_reloadSkip state: absent - name: Ensure second maintenance policy does not exist From d642df8fe5756f14d2a958667d5d64a327fc1ac4 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 2 Aug 2023 22:47:22 -0400 Subject: [PATCH 25/31] [ignore] Apply black and format the previous modified files. --- plugins/modules/aci_interface_policy_mcp.py | 5 +---- plugins/modules/aci_maintenance_policy.py | 6 +++++- .../targets/aci_maintenance_policy/tasks/main.yml | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/modules/aci_interface_policy_mcp.py b/plugins/modules/aci_interface_policy_mcp.py index 771a8d7de..41f802e24 100644 --- a/plugins/modules/aci_interface_policy_mcp.py +++ b/plugins/modules/aci_interface_policy_mcp.py @@ -238,10 +238,7 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec -MATCH_MCP_MODE_MAPPING = { - "non_strict": "off", - "strict": "on" -} +MATCH_MCP_MODE_MAPPING = {"non_strict": "off", "strict": "on"} def main(): diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index 6bcdddf41..7a89f376c 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -278,10 +278,13 @@ MATCH_RUN_MODE_MAPPING = dict(pause_always_between_sets="pauseAlwaysBetweenSets", pause_only_on_failures="pauseOnlyOnFailures", pause_never="pauseNever") -MATCH_NOTIFY_CONDITION_MAPPING = dict(notify_always_between_sets="notifyAlwaysBetweenSets", notify_never="notifyNever", notify_only_on_failures="notifyOnlyOnFailures") +MATCH_NOTIFY_CONDITION_MAPPING = dict( + notify_always_between_sets="notifyAlwaysBetweenSets", notify_never="notifyNever", notify_only_on_failures="notifyOnlyOnFailures" +) MATCH_SMU_OPERATION_MAPPING = dict(smu_install="smuInstall", smu_uninstall="smuUninstall") MATCH_SMU_OPERATION_FLAGS_MAPPING = dict(smu_reload_immediate="smuReloadImmediate", smu_reload_skip="smuReloadSkip") + def main(): argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) @@ -326,6 +329,7 @@ def main(): smu_operation = MATCH_SMU_OPERATION_MAPPING.get(module.params.get("smu_operation")) smu_operation_flags = MATCH_SMU_OPERATION_FLAGS_MAPPING.get(module.params.get("smu_operation_flags")) sr_version = module.params.get("sr_version") + sr_upgrade = module.params.get("sr_upgrade") version = module.params.get("version") version_check_override = module.params.get("version_check_override") graceful = aci.boolean(module.params.get("graceful")) diff --git a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml index 9377293bf..8628c2a84 100644 --- a/tests/integration/targets/aci_maintenance_policy/tasks/main.yml +++ b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml @@ -45,7 +45,7 @@ download_state: untriggered notify_condition: notify_always_between_sets smu_operation: smu_install - smu_operation_flags: smu_reloadSkip + smu_operation_flags: smu_reload_skip state: absent - name: Ensure second maintenance policy does not exist From 160e112e99c2036a73ebd7773aa52a941b8fa4c0 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 2 Aug 2023 23:24:36 -0400 Subject: [PATCH 26/31] [ignore] Modify type attribute for aci maintenance group and firmware group. --- plugins/modules/aci_firmware_group.py | 2 +- plugins/modules/aci_maintenance_group.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index eb3c5fd17..9687b05f3 100644 --- a/plugins/modules/aci_firmware_group.py +++ b/plugins/modules/aci_firmware_group.py @@ -243,7 +243,7 @@ def main(): state = module.params.get("state") group = module.params.get("group") policy = module.params.get("policy") - type_group = MATCH_TYPE_GROUP_MAPPING.get(module.params.get("type")) + type_group = MATCH_TYPE_GROUP_MAPPING.get(module.params.get("type_group")) description = module.params.get("description") name_alias = module.params.get("name_alias") diff --git a/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index c4715e548..d4d249e25 100644 --- a/plugins/modules/aci_maintenance_group.py +++ b/plugins/modules/aci_maintenance_group.py @@ -248,7 +248,7 @@ def main(): group = module.params.get("group") policy = module.params.get("policy") firmware_nodes_type = MATCH_FIRMWARE_NODES_TYPE_MAPPING.get(module.params.get("firmware_nodes_type")) - type_group = MATCH_TYPE_GROUP_MAPPING.get(module.params.get("type")) + type_group = MATCH_TYPE_GROUP_MAPPING.get(module.params.get("type_group")) description = module.params.get("description") name_alias = module.params.get("name_alias") aci = ACIModule(module) From 1a6cd2d89256827ae89795c796f9ff80d1bce0ca Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 8 Aug 2023 11:52:27 -0400 Subject: [PATCH 27/31] [ignore] Modify aci_interface_policy_fc, aci_firmware_policy and aci_maintenance_policy to add constants. --- plugins/module_utils/constants.py | 25 +++++++++++++++++++++ plugins/modules/aci_firmware_policy.py | 7 +++--- plugins/modules/aci_interface_policy_fc.py | 6 ++--- plugins/modules/aci_maintenance_policy.py | 26 +++++++++++----------- tests/integration/inventory.networking | 4 ++-- 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/plugins/module_utils/constants.py b/plugins/module_utils/constants.py index 132b3e0fd..2a6a3e883 100644 --- a/plugins/module_utils/constants.py +++ b/plugins/module_utils/constants.py @@ -63,3 +63,28 @@ "switch_patch": "switchPatch", "vpod": "vpod", } + +MATCH_TRIGGER_MAPPING = { + "trigger": "trigger", + "trigger_immediate": "trigger-immediate", + "triggered": "triggered", + "untriggered": "untriggered", +} + +INTERFACE_POLICY_FC_SPEED_LIST = ["auto", "unknown", "2G", "4G", "8G", "16G", "32G"] + +MATCH_RUN_MODE_MAPPING = dict( + pause_always_between_sets="pauseAlwaysBetweenSets", + pause_only_on_failures="pauseOnlyOnFailures", + pause_never="pauseNever", +) + +MATCH_NOTIFY_CONDITION_MAPPING = dict( + notify_always_between_sets="notifyAlwaysBetweenSets", + notify_never="notifyNever", + notify_only_on_failures="notifyOnlyOnFailures", +) + +MATCH_SMU_OPERATION_MAPPING = dict(smu_install="smuInstall", smu_uninstall="smuUninstall") + +MATCH_SMU_OPERATION_FLAGS_MAPPING = dict(smu_reload_immediate="smuReloadImmediate", smu_reload_skip="smuReloadSkip") diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index 71611f0d1..7f40819fe 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -55,7 +55,7 @@ - The version check override is a one-time override that performs the install whether or not the versions match. - The APIC defaults to C(untriggered) when unset during creation. type: str - choices: [ trigger, trigger-immediate, triggered, untriggered ] + choices: [ trigger, trigger_immediate, triggered, untriggered ] description: description: - Description for the firmware policy. @@ -235,6 +235,7 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_TRIGGER_MAPPING def main(): @@ -249,7 +250,7 @@ def main(): ignore_compat=dict(type="bool"), sr_upgrade=dict(type="bool"), sr_version=dict(type="str"), - version_check_override=dict(type="str", choices=["trigger", "trigger-immediate", "triggered", "untriggered"]), + version_check_override=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), ) @@ -272,7 +273,7 @@ def main(): ignore_compat = aci.boolean(module.params.get("ignore_compat"), "yes", "no") sr_version = module.params.get("sr_version") sr_upgrade = aci.boolean(module.params.get("sr_upgrade"), "yes", "no") - version_check_override = module.params.get("version_check_override") + version_check_override = MATCH_TRIGGER_MAPPING.get(module.params.get("version_check_override")) name_alias = module.params.get("name_alias") aci.construct_url( diff --git a/plugins/modules/aci_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index 5d1742bb8..2e61a177d 100644 --- a/plugins/modules/aci_interface_policy_fc.py +++ b/plugins/modules/aci_interface_policy_fc.py @@ -233,7 +233,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec, aci_owner_spec -from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_FC_FILL_PATTERN_MAPPING +from ansible_collections.cisco.aci.plugins.module_utils.constants import MATCH_FC_FILL_PATTERN_MAPPING, INTERFACE_POLICY_FC_SPEED_LIST def main(): @@ -244,10 +244,10 @@ def main(): fc_policy=dict(type="str", aliases=["name"]), # Not required for querying all objects description=dict(type="str", aliases=["descr"]), port_mode=dict(type="str", choices=["f", "np"]), # No default provided on purpose - auto_max_speed=dict(type="str", choices=["2G", "4G", "8G", "16G", "32G"]), + auto_max_speed=dict(type="str", choices=INTERFACE_POLICY_FC_SPEED_LIST[2:]), fill_pattern=dict(type="str", choices=list(MATCH_FC_FILL_PATTERN_MAPPING.keys())), buffer_credits=dict(type="int"), - speed=dict(type="str", choices=["auto", "unknown", "2G", "4G", "8G", "16G", "32G"]), + speed=dict(type="str", choices=INTERFACE_POLICY_FC_SPEED_LIST), trunk_mode=dict(type="str", choices=["auto", "trunk-off", "trunk-on", "un-init"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index 7a89f376c..1e5fefe0d 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -44,12 +44,14 @@ - The APIC defaults to C(untriggered) when unset during creation. type: str choices: [ triggered, untriggered ] + aliases: [ adminSt ] download_state: description: - The download state of the executable policies. - The APIC defaults to C(untriggered) when unset during creation. type: str choices: [ triggered, untriggered ] + aliases: [ downloadSt ] notify_condition: description: - Specifies under what pause condition will admin be notified via email/text as configured. @@ -89,7 +91,7 @@ - The version check override is a one-time override that performs the install whether or not the versions match. - The APIC defaults to C(untriggered) when unset during creation. type: str - choices: [ trigger, trigger-immediate, triggered, untriggered ] + choices: [ trigger, trigger_immediate, triggered, untriggered ] ignore_compat: description: - To check whether compatibility checks should be ignored @@ -275,14 +277,12 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec from ansible.module_utils.basic import AnsibleModule - - -MATCH_RUN_MODE_MAPPING = dict(pause_always_between_sets="pauseAlwaysBetweenSets", pause_only_on_failures="pauseOnlyOnFailures", pause_never="pauseNever") -MATCH_NOTIFY_CONDITION_MAPPING = dict( - notify_always_between_sets="notifyAlwaysBetweenSets", notify_never="notifyNever", notify_only_on_failures="notifyOnlyOnFailures" +from ansible_collections.cisco.aci.plugins.module_utils.constants import ( + MATCH_RUN_MODE_MAPPING, MATCH_NOTIFY_CONDITION_MAPPING, + MATCH_SMU_OPERATION_MAPPING, + MATCH_SMU_OPERATION_FLAGS_MAPPING, + MATCH_TRIGGER_MAPPING ) -MATCH_SMU_OPERATION_MAPPING = dict(smu_install="smuInstall", smu_uninstall="smuUninstall") -MATCH_SMU_OPERATION_FLAGS_MAPPING = dict(smu_reload_immediate="smuReloadImmediate", smu_reload_skip="smuReloadSkip") def main(): @@ -294,15 +294,15 @@ def main(): graceful=dict(type="bool"), scheduler=dict(type="str"), ignore_compat=dict(type="bool"), - admin_state=dict(type="str", choices=["triggered", "untriggered"]), - download_state=dict(type="str", choices=["triggered", "untriggered"]), + admin_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["adminSt"]), + download_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["downloadSt"]), notify_condition=dict(type="str", choices=list(MATCH_NOTIFY_CONDITION_MAPPING.keys())), smu_operation=dict(type="str", choices=list(MATCH_SMU_OPERATION_MAPPING.keys())), smu_operation_flags=dict(type="str", choices=list(MATCH_SMU_OPERATION_FLAGS_MAPPING.keys())), sr_upgrade=dict(type="bool"), sr_version=dict(type="str"), version=dict(type="str"), - version_check_override=dict(type="str", choices=["trigger", "trigger-immediate", "triggered", "untriggered"]), + version_check_override=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())), description=dict(type="str", aliases=["descr"]), state=dict(type="str", default="present", choices=["absent", "present", "query"]), name_alias=dict(type="str"), @@ -322,6 +322,7 @@ def main(): state = module.params.get("state") name = module.params.get("name") run_mode = MATCH_RUN_MODE_MAPPING.get(module.params.get("run_mode")) + graceful = aci.boolean(module.params.get("graceful"), "yes", "no") scheduler = module.params.get("scheduler") admin_state = module.params.get("admin_state") download_state = module.params.get("download_state") @@ -331,8 +332,7 @@ def main(): sr_version = module.params.get("sr_version") sr_upgrade = module.params.get("sr_upgrade") version = module.params.get("version") - version_check_override = module.params.get("version_check_override") - graceful = aci.boolean(module.params.get("graceful")) + version_check_override = MATCH_TRIGGER_MAPPING.get(module.params.get("version_check_override")) ignore_compat = aci.boolean(module.params.get("ignore_compat")) description = module.params.get("description") name_alias = module.params.get("name_alias") diff --git a/tests/integration/inventory.networking b/tests/integration/inventory.networking index f3d5d1a29..357f58758 100644 --- a/tests/integration/inventory.networking +++ b/tests/integration/inventory.networking @@ -3,8 +3,8 @@ 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-v60 ansible_host=173.36.219.70 aci_hostname=173.36.219.70 cn-dmz-apic-m1-07-v32 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 aci_password="sJ94G92#8dq2hx*K4qh" 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 aci_password="sJ94G92#8dq2hx*K4qh" cloud_type=azure region=westus region_2=westus2 vnet_gateway=true +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 [aci:vars] aci_username=ansible_github_ci From 77ed551873f27a3725d647b5d52b1a2e83e3b96c Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 8 Aug 2023 11:55:23 -0400 Subject: [PATCH 28/31] [ignore] Apply Black for formating - after adding constants. --- plugins/modules/aci_maintenance_policy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index 1e5fefe0d..bbac1331c 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -278,10 +278,11 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.aci.plugins.module_utils.constants import ( - MATCH_RUN_MODE_MAPPING, MATCH_NOTIFY_CONDITION_MAPPING, + MATCH_RUN_MODE_MAPPING, + MATCH_NOTIFY_CONDITION_MAPPING, MATCH_SMU_OPERATION_MAPPING, MATCH_SMU_OPERATION_FLAGS_MAPPING, - MATCH_TRIGGER_MAPPING + MATCH_TRIGGER_MAPPING, ) From 8e1734da6ab5023198cb254f5c22b98f9fb47cc6 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 9 Aug 2023 14:39:03 -0400 Subject: [PATCH 29/31] [ignore] Add aliases for attribute input ignore_compat in maintenance and firmware policy. --- plugins/modules/aci_firmware_policy.py | 3 ++- plugins/modules/aci_maintenance_policy.py | 3 ++- .../targets/aci_bd_to_l3out/tasks/main.yml | 16 ++++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/plugins/modules/aci_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index 7f40819fe..50b41a960 100644 --- a/plugins/modules/aci_firmware_policy.py +++ b/plugins/modules/aci_firmware_policy.py @@ -32,6 +32,7 @@ description: - Check if compatibility checks should be ignored type: bool + aliases: [ ignoreCompat ] sr_upgrade: description: - The SR firware upgrade. @@ -247,7 +248,7 @@ def main(): description=dict(type="str", aliases=["descr"]), version=dict(type="str"), effective_on_reboot=dict(type="bool"), - ignore_compat=dict(type="bool"), + ignore_compat=dict(type="bool", aliases=["ignoreCompat"]), sr_upgrade=dict(type="bool"), sr_version=dict(type="str"), version_check_override=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())), diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index bbac1331c..f78a390e7 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -97,6 +97,7 @@ - To check whether compatibility checks should be ignored - The APIC defaults to C(false) when unset during creation. type: bool + aliases: [ ignoreCompat ] description: description: - Description for the maintenance policy. @@ -294,7 +295,7 @@ def main(): run_mode=dict(type="str", choices=list(MATCH_RUN_MODE_MAPPING.keys())), graceful=dict(type="bool"), scheduler=dict(type="str"), - ignore_compat=dict(type="bool"), + ignore_compat=dict(type="bool", aliases=["ignoreCompat"]), admin_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["adminSt"]), download_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["downloadSt"]), notify_condition=dict(type="str", choices=list(MATCH_NOTIFY_CONDITION_MAPPING.keys())), diff --git a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml index 487767668..7d1313fb2 100644 --- a/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml +++ b/tests/integration/targets/aci_bd_to_l3out/tasks/main.yml @@ -32,48 +32,48 @@ - name: Execute tasks only for non-cloud sites when: query_cloud.current == [] # This condition will execute only non-cloud sites block: # block specifies execution of tasks within, based on conditions - - name: Create tenant for tests to kick off + - name: Create tenant cisco.aci.aci_tenant: &aci_tenant_present <<: *aci_tenant_absent state: present - - name: Create vrf for tests to kick off + - name: Create vrf cisco.aci.aci_vrf: &aci_vrf_present <<: *aci_tenant_present vrf: anstest - - name: Create first L3out for tests to kick off + - name: Create first L3out cisco.aci.aci_l3out: &aci_l3_out_present <<: *aci_vrf_present l3out: ansible_l3out domain: ansible_dom state: present - - name: Create second L3out for tests to kick off + - name: Create second L3out cisco.aci.aci_l3out: &aci_l3_out_present_2 <<: *aci_vrf_present l3out: ansible_l3out_2 domain: ansible_dom state: present - - name: Create first bd for tests to kick off + - name: Create first bd cisco.aci.aci_bd: &aci_bd_present <<: *aci_tenant_present bd: anstest - - name: Create second bd for tests to kick off + - name: Create second bd cisco.aci.aci_bd: &aci_bd_present_2 <<: *aci_tenant_present bd: anstest_2 - - name: Ensure first binding bd_to_l3out does not exist for tests to kick off + - name: Ensure first binding bd_to_l3out does not exist cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_absent <<: *aci_tenant_present bd: anstest l3out: ansible_l3out state: absent - - name: Ensure second binding bd_to_l3out does not exist for tests to kick off + - name: Ensure second binding bd_to_l3out does not exist cisco.aci.aci_bd_to_l3out: &aci_bd_to_l3out_absent_2 <<: *aci_tenant_present bd: anstest_2 From 319641c01638719e6fa79cb801995368e50f8366 Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Wed, 16 Aug 2023 15:07:54 -0400 Subject: [PATCH 30/31] [ignore] modify run_mode attributes for aci_maintenance_policy.py --- plugins/modules/aci_maintenance_policy.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index f78a390e7..a1aae01d2 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -27,7 +27,8 @@ - Whether the system pauses on error or just continues through it. - The APIC defaults to C(pauseOnlyOnFailures) when unset during creation. type: str - choices: [ pause_always_between_sets, pause_only_on_failures, pause_never ] + choices: [ pause_always_between_sets, pause_only_on_failures, pause_never, pauseOnlyOnFailures, pauseNever ] + aliases: [ runmode ] graceful: description: - Whether the system will bring down the nodes gracefully during an upgrade, which reduces traffic lost. @@ -44,14 +45,13 @@ - The APIC defaults to C(untriggered) when unset during creation. type: str choices: [ triggered, untriggered ] - aliases: [ adminSt ] + aliases: [ adminst ] download_state: description: - The download state of the executable policies. - The APIC defaults to C(untriggered) when unset during creation. type: str choices: [ triggered, untriggered ] - aliases: [ downloadSt ] notify_condition: description: - Specifies under what pause condition will admin be notified via email/text as configured. @@ -292,12 +292,12 @@ def main(): argument_spec.update(aci_annotation_spec()) argument_spec.update( name=dict(type="str", aliases=["maintenance_policy"]), # Not required for querying all objects - run_mode=dict(type="str", choices=list(MATCH_RUN_MODE_MAPPING.keys())), + run_mode=dict(type="str", choices=list(MATCH_RUN_MODE_MAPPING.keys()).extend(["pauseOnlyOnFailures", "pauseNever"]), aliases=["runmode"]), graceful=dict(type="bool"), scheduler=dict(type="str"), ignore_compat=dict(type="bool", aliases=["ignoreCompat"]), - admin_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["adminSt"]), - download_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["downloadSt"]), + admin_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:], aliases=["adminst"]), + download_state=dict(type="str", choices=list(MATCH_TRIGGER_MAPPING.keys())[2:]), notify_condition=dict(type="str", choices=list(MATCH_NOTIFY_CONDITION_MAPPING.keys())), smu_operation=dict(type="str", choices=list(MATCH_SMU_OPERATION_MAPPING.keys())), smu_operation_flags=dict(type="str", choices=list(MATCH_SMU_OPERATION_FLAGS_MAPPING.keys())), @@ -323,7 +323,7 @@ def main(): state = module.params.get("state") name = module.params.get("name") - run_mode = MATCH_RUN_MODE_MAPPING.get(module.params.get("run_mode")) + run_mode = module.params.get("run_mode") graceful = aci.boolean(module.params.get("graceful"), "yes", "no") scheduler = module.params.get("scheduler") admin_state = module.params.get("admin_state") @@ -339,6 +339,9 @@ def main(): description = module.params.get("description") name_alias = module.params.get("name_alias") + if run_mode not in ["pauseOnlyOnFailures", "pauseNever"]: + run_mode = MATCH_RUN_MODE_MAPPING.get(run_mode) + aci.construct_url( root_class=dict( aci_class="maintMaintP", From ad05c91f317525bafe687d74f70b66aef2787aed Mon Sep 17 00:00:00 2001 From: Gaspard Micol Date: Tue, 22 Aug 2023 07:39:08 -0400 Subject: [PATCH 31/31] [ignore] Modify run_mode choices to check sanity test in aci_maintenance_policy. --- plugins/modules/aci_maintenance_policy.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index a1aae01d2..987dc2e35 100644 --- a/plugins/modules/aci_maintenance_policy.py +++ b/plugins/modules/aci_maintenance_policy.py @@ -288,11 +288,13 @@ def main(): + list_run_mode_choices = list(MATCH_RUN_MODE_MAPPING.keys()) + list_run_mode_choices.extend(["pauseOnlyOnFailures", "pauseNever"]) argument_spec = aci_argument_spec() argument_spec.update(aci_annotation_spec()) argument_spec.update( name=dict(type="str", aliases=["maintenance_policy"]), # Not required for querying all objects - run_mode=dict(type="str", choices=list(MATCH_RUN_MODE_MAPPING.keys()).extend(["pauseOnlyOnFailures", "pauseNever"]), aliases=["runmode"]), + run_mode=dict(type="str", choices=list_run_mode_choices, aliases=["runmode"]), graceful=dict(type="bool"), scheduler=dict(type="str"), ignore_compat=dict(type="bool", aliases=["ignoreCompat"]),