diff --git a/plugins/doc_fragments/aci.py b/plugins/doc_fragments/aci.py index aaedff669..e428197e7 100644 --- a/plugins/doc_fragments/aci.py +++ b/plugins/doc_fragments/aci.py @@ -98,12 +98,21 @@ class ModuleDocFragment(object): suppress_verification: description: - If C(true), a verifying GET will not be sent after a POST update to APIC. - - If the value is not specified in the task, the value of environment variable C(ACI_NO_VERIFICATION) will be used instead. + - If the value is not specified in the task, the value of environment variable C(ACI_SUPPRESS_VERIFICATION) will be used instead. - The default value is C(false). - WARNING - This causes the current return value to be set to the proposed value. - The current object including default values will be unverifiable in a single task. type: bool - aliases: [ no_verification, no_verify, suppress_verify ] + aliases: [ no_verification, no_verify, suppress_verify, ignore_verify, ignore_verification ] + suppress_previous: + description: + - If C(true), a GET to check previous will not be sent before a POST update to APIC. + - If the value is not specified in the task, the value of environment variable C(ACI_SUPPRESS_PREVIOUS) will be used instead. + - The default value is C(false). + - WARNING - This causes the previous return value to be empty. + - The previous state of the object will not be checked and the POST update will contain all properties. + type: bool + aliases: [ no_previous, ignore_previous ] seealso: - ref: aci_guide description: Detailed information on how to manage your ACI infrastructure using Ansible. diff --git a/plugins/module_utils/aci.py b/plugins/module_utils/aci.py index 88b49cd6e..c21830017 100644 --- a/plugins/module_utils/aci.py +++ b/plugins/module_utils/aci.py @@ -136,7 +136,12 @@ def aci_argument_spec(): use_ssl=dict(type="bool", fallback=(env_fallback, ["ACI_USE_SSL"])), validate_certs=dict(type="bool", fallback=(env_fallback, ["ACI_VALIDATE_CERTS"])), output_path=dict(type="str", fallback=(env_fallback, ["ACI_OUTPUT_PATH"])), - suppress_verification=dict(type="bool", aliases=["no_verification", "no_verify", "suppress_verify"], fallback=(env_fallback, ["ACI_NO_VERIFICATION"])), + suppress_verification=dict( + type="bool", + aliases=["no_verification", "no_verify", "suppress_verify", "ignore_verify", "ignore_verification"], + fallback=(env_fallback, ["ACI_SUPPRESS_VERIFICATION"]), + ), + suppress_previous=dict(type="bool", aliases=["no_previous", "ignore_previous"], fallback=(env_fallback, ["ACI_SUPPRESS_PREVIOUS"])), ) @@ -420,6 +425,9 @@ def __init__(self, module): # get no verify flag self.suppress_verification = self.params.get("suppress_verification") + # get suppress previous flag + self.suppress_previous = self.params.get("suppress_previous") + # Ensure protocol is set self.define_protocol() @@ -1302,7 +1310,7 @@ def delete_config(self): """ self.proposed = dict() - if not self.existing: + if not self.existing and not self.suppress_previous: return elif not self.module.check_mode: # Sign and encode request as to APIC's wishes @@ -1429,10 +1437,30 @@ def get_existing(self): that this method can be used to supply the existing configuration when using the get_diff method. The response, status, and existing configuration will be added to the self.result dictionary. """ - uri = self.url + self.filter_string + if self.suppress_previous: + self.existing = [] + return + uri = self.url + self.filter_string self.api_call("GET", uri, data=None, return_response=False) + def __get_existing_validation(self, changed): + """ + This method is used to get the existing object(s) state after a config change has been completed. + It will not get the object(s) state if there is no change or suppress_verification is enabled. + When suppress_verification is enabled, the existing will be set to proposed if there was a change or suppress_previous is enabled. + """ + if self.suppress_verification: + if changed or self.suppress_previous: + self.result["current_verified"] = False + self.existing = [self.proposed] if self.proposed != {} else [] + else: + # existing already equals the previous + self.result["current_verified"] = True + elif changed: + uri = self.url + self.filter_string + self.api_call("GET", uri, data=None, return_response=False) + @staticmethod def get_nested_config(proposed_child, existing_children): """ @@ -1597,15 +1625,7 @@ def exit_json(self, filter_existing=None, **kwargs): if "state" in self.params: self.original = self.existing if self.params.get("state") in ("absent", "present"): - if self.suppress_verification: - if self.result["changed"]: - self.result["current_verified"] = False - self.existing = [self.proposed] - else: - self.result["current_verified"] = True - # exisiting already equals the previous - else: - self.get_existing() + self.__get_existing_validation(self.result["changed"]) # if self.module._diff and self.original != self.existing: # self.result['diff'] = dict( diff --git a/tests/integration/targets/aci_bd_subnet/tasks/main.yml b/tests/integration/targets/aci_bd_subnet/tasks/main.yml index 8d05b2e16..68953e4e7 100644 --- a/tests/integration/targets/aci_bd_subnet/tasks/main.yml +++ b/tests/integration/targets/aci_bd_subnet/tasks/main.yml @@ -171,6 +171,149 @@ - create_subnet2_5.sent.fvSubnet.children.0.fvRsBDSubnetToProfile.attributes.tnRtctrlProfileName == 'default' when: version.current.0.topSystem.attributes.version is version('5', '>=') + # TEST NO PREVIOUS + - name: create bd subnet with no previous (check mode) + cisco.aci.aci_bd_subnet: &aci_bd_subnet_no_previous + <<: *aci_subnet_present + subnet_name: anstest_no_previous + gateway: 10.101.101.10 + mask: 25 + no_previous: true + check_mode: true + register: bd_subnet_present_no_previous_cm + + - name: create bd subnet with no previous + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_previous + register: bd_subnet_present_no_previous + + - name: create bd subnet with no previous again + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_previous + register: bd_subnet_present_no_previous_again + + - name: update bd subnet with no previous + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_previous + descr: Ansible Test no previous + register: update_bd_subnet_present_no_previous + + - name: delete bd subnet with no previous + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_previous + state: absent + register: delete_bd_subnet_present_no_previous + + - name: delete bd subnet with no previous again + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_previous + state: absent + register: delete_bd_subnet_present_no_previous_again + + - name: no previous asserts + ansible.builtin.assert: + that: + - bd_subnet_present_no_previous_cm is changed + - bd_subnet_present_no_previous_cm.current == [] + - bd_subnet_present_no_previous_cm.previous == [] + - bd_subnet_present_no_previous_cm.proposed.fvSubnet.attributes.dn == "uni/tn-ansible_test/BD-anstest/subnet-[10.101.101.10/25]" + - bd_subnet_present_no_previous_cm.proposed.fvSubnet.attributes.descr == "Ansible Test" + - bd_subnet_present_no_previous_cm.proposed.fvSubnet.attributes.annotation == "orchestrator:ansible" + - bd_subnet_present_no_previous is changed + - bd_subnet_present_no_previous.current.0.fvSubnet.attributes.dn == "uni/tn-ansible_test/BD-anstest/subnet-[10.101.101.10/25]" + - bd_subnet_present_no_previous.current.0.fvSubnet.attributes.annotation == "orchestrator:ansible" + - bd_subnet_present_no_previous.current.0.fvSubnet.attributes.descr == "Ansible Test" + - bd_subnet_present_no_previous.proposed.fvSubnet.attributes.dn == "uni/tn-ansible_test/BD-anstest/subnet-[10.101.101.10/25]" + - bd_subnet_present_no_previous.proposed.fvSubnet.attributes.annotation == "orchestrator:ansible" + - bd_subnet_present_no_previous.proposed.fvSubnet.attributes.descr == "Ansible Test" + - bd_subnet_present_no_previous.previous == [] + - bd_subnet_present_no_previous_again is changed + - bd_subnet_present_no_previous_again.current == bd_subnet_present_no_previous.current + - bd_subnet_present_no_previous_again.proposed == bd_subnet_present_no_previous.proposed + - bd_subnet_present_no_previous_again.previous == [] + - update_bd_subnet_present_no_previous is changed + - update_bd_subnet_present_no_previous.current.0.fvSubnet.attributes.dn == "uni/tn-ansible_test/BD-anstest/subnet-[10.101.101.10/25]" + - update_bd_subnet_present_no_previous.current.0.fvSubnet.attributes.annotation == "orchestrator:ansible" + - update_bd_subnet_present_no_previous.current.0.fvSubnet.attributes.descr == "Ansible Test no previous" + - delete_bd_subnet_present_no_previous is changed + - delete_bd_subnet_present_no_previous.current == [] + - delete_bd_subnet_present_no_previous.previous == [] + - delete_bd_subnet_present_no_previous.proposed == {} + - delete_bd_subnet_present_no_previous_again is changed + - delete_bd_subnet_present_no_previous_again.current == [] + - delete_bd_subnet_present_no_previous_again.previous == [] + - delete_bd_subnet_present_no_previous_again.proposed == {} + + # TEST NO PREVIOUS & NO VERIFICATION + - name: create bd subnet with no previous & no verify (check mode) + cisco.aci.aci_bd_subnet: &aci_bd_subnet_no_lb_no_v + <<: *aci_subnet_present + subnet_name: anstest_no_lb_no_v + gateway: 10.102.101.12 + mask: 25 + no_previous: true + no_verify: true + check_mode: true + register: bd_subnet_present_no_lb_no_v_cm + + - name: create bd subnet with no previous & no verify + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_lb_no_v + register: bd_subnet_present_no_lb_no_v + + - name: create bd subnet with no previous again & no verify + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_lb_no_v + register: bd_subnet_present_no_lb_no_v_again + + - name: update bd subnet with no previous & no verify + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_lb_no_v + descr: Ansible Test no previous & no verify + register: update_bd_subnet_present_no_lb_no_v + + - name: delete bd subnet with no previous & no verify + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_lb_no_v + state: absent + register: delete_bd_subnet_present_no_lb_no_v + + - name: delete bd subnet with no previous again & no verify + cisco.aci.aci_bd_subnet: + <<: *aci_bd_subnet_no_lb_no_v + state: absent + register: delete_bd_subnet_present_no_lb_no_v_again + + - name: no previous & no verify asserts + ansible.builtin.assert: + that: + - bd_subnet_present_no_lb_no_v_cm is changed + - bd_subnet_present_no_lb_no_v_cm.current.0 == bd_subnet_present_no_lb_no_v_cm.proposed + - bd_subnet_present_no_lb_no_v_cm.previous == [] + - bd_subnet_present_no_lb_no_v_cm.proposed.fvSubnet.attributes.dn == "uni/tn-ansible_test/BD-anstest/subnet-[10.102.101.12/25]" + - bd_subnet_present_no_lb_no_v_cm.proposed.fvSubnet.attributes.descr == "Ansible Test" + - bd_subnet_present_no_lb_no_v_cm.proposed.fvSubnet.attributes.annotation == "orchestrator:ansible" + - bd_subnet_present_no_lb_no_v is changed + - bd_subnet_present_no_lb_no_v.current.0 == bd_subnet_present_no_lb_no_v.proposed + - bd_subnet_present_no_lb_no_v.previous == [] + - bd_subnet_present_no_lb_no_v_again is changed + - bd_subnet_present_no_lb_no_v_again.current == bd_subnet_present_no_lb_no_v.current + - bd_subnet_present_no_lb_no_v_again.proposed == bd_subnet_present_no_lb_no_v.proposed + - bd_subnet_present_no_lb_no_v_again.previous == [] + - update_bd_subnet_present_no_lb_no_v is changed + - update_bd_subnet_present_no_lb_no_v.current.0 == update_bd_subnet_present_no_lb_no_v.proposed + - update_bd_subnet_present_no_lb_no_v.current.0.fvSubnet.attributes.dn == "uni/tn-ansible_test/BD-anstest/subnet-[10.102.101.12/25]" + - update_bd_subnet_present_no_lb_no_v.current.0.fvSubnet.attributes.annotation == "orchestrator:ansible" + - update_bd_subnet_present_no_lb_no_v.current.0.fvSubnet.attributes.descr == "Ansible Test no previous & no verify" + - delete_bd_subnet_present_no_lb_no_v is changed + - delete_bd_subnet_present_no_lb_no_v.current == [] + - delete_bd_subnet_present_no_lb_no_v.previous == [] + - delete_bd_subnet_present_no_lb_no_v.proposed == {} + - delete_bd_subnet_present_no_lb_no_v_again is changed + - delete_bd_subnet_present_no_lb_no_v_again.current == [] + - delete_bd_subnet_present_no_lb_no_v_again.previous == [] + - delete_bd_subnet_present_no_lb_no_v_again.proposed == {} + - name: get all subnets cisco.aci.aci_bd_subnet: &aci_query <<: *aci_tenant_present diff --git a/tests/integration/targets/aci_epg_to_contract/tasks/main.yml b/tests/integration/targets/aci_epg_to_contract/tasks/main.yml index f7213c1e6..0fd2ce9fe 100644 --- a/tests/integration/targets/aci_epg_to_contract/tasks/main.yml +++ b/tests/integration/targets/aci_epg_to_contract/tasks/main.yml @@ -54,7 +54,7 @@ cisco.aci.aci_contract: <<: *aci_tenant_present contract: "{{ item }}" - with_items: ["anstest_http", "anstest_https", "anstest_db"] + with_items: ["anstest_http", "anstest_https", "anstest_db", "anstest_no_previous", "anstest_no_lb_no_v"] - name: ensure ap exists cisco.aci.aci_ap: &aci_ap_present @@ -207,6 +207,141 @@ - err_subject_and_contract_label is failed - err_subject_and_contract_label.msg == "the 'contract_label' and 'subject_label' are not configurable for intra_epg contracts" + # TEST NO PREVIOUS + - name: create epg contract to epg with no previous (check mode) + cisco.aci.aci_epg_to_contract: &aci_epg_to_contract_no_previous + <<: *aci_epg_consume_present + contract: anstest_no_previous + no_previous: true + check_mode: true + register: epg_to_contract_present_no_previous_cm + + - name: create epg contract to epg with no previous + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_previous + register: epg_to_contract_present_no_previous + + - name: create epg contract to epg with no previous again + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_previous + register: epg_to_contract_present_no_previous_again + + - name: update epg contract to epg with no previous + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_previous + priority: level1 + register: update_epg_to_contract_present_no_previous + + - name: delete epg contract to epg with no previous + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_previous + state: absent + register: delete_epg_to_contract_present_no_previous + + - name: delete epg contract to epg with no previous again + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_previous + state: absent + register: delete_epg_to_contract_present_no_previous_again + + - name: no previous asserts + ansible.builtin.assert: + that: + - epg_to_contract_present_no_previous_cm is changed + - epg_to_contract_present_no_previous_cm.current == [] + - epg_to_contract_present_no_previous_cm.previous == [] + - epg_to_contract_present_no_previous_cm.proposed.fvRsCons.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rscons-anstest_no_previous" + - epg_to_contract_present_no_previous_cm.proposed.fvRsCons.attributes.annotation == "orchestrator:ansible" + - epg_to_contract_present_no_previous is changed + - epg_to_contract_present_no_previous.current.0.fvRsCons.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rscons-anstest_no_previous" + - epg_to_contract_present_no_previous.current.0.fvRsCons.attributes.annotation == "orchestrator:ansible" + - epg_to_contract_present_no_previous.current.0.fvRsCons.attributes.prio == "unspecified" + - epg_to_contract_present_no_previous.proposed.fvRsCons.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rscons-anstest_no_previous" + - epg_to_contract_present_no_previous.proposed.fvRsCons.attributes.annotation == "orchestrator:ansible" + - epg_to_contract_present_no_previous.previous == [] + - epg_to_contract_present_no_previous_again is changed + - epg_to_contract_present_no_previous_again.current == epg_to_contract_present_no_previous.current + - epg_to_contract_present_no_previous_again.proposed == epg_to_contract_present_no_previous.proposed + - epg_to_contract_present_no_previous_again.previous == [] + - update_epg_to_contract_present_no_previous is changed + - update_epg_to_contract_present_no_previous.current.0.fvRsCons.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rscons-anstest_no_previous" + - update_epg_to_contract_present_no_previous.current.0.fvRsCons.attributes.annotation == "orchestrator:ansible" + - update_epg_to_contract_present_no_previous.current.0.fvRsCons.attributes.prio == "level1" + - delete_epg_to_contract_present_no_previous is changed + - delete_epg_to_contract_present_no_previous.current == [] + - delete_epg_to_contract_present_no_previous.previous == [] + - delete_epg_to_contract_present_no_previous.proposed == {} + - delete_epg_to_contract_present_no_previous_again is changed + - delete_epg_to_contract_present_no_previous_again.current == [] + - delete_epg_to_contract_present_no_previous_again.previous == [] + - delete_epg_to_contract_present_no_previous_again.proposed == {} + + # TEST NO PREVIOUS & NO VERIFICATION + - name: create epg contract to epg with no previous & no verify (check mode) + cisco.aci.aci_epg_to_contract: &aci_epg_to_contract_no_lb_no_v + <<: *aci_epg_consume_present + contract: anstest_no_lb_no_v + no_previous: true + no_verify: true + check_mode: true + register: epg_to_contract_present_no_lb_no_v_cm + + - name: create epg contract to epg with no look bac & no verify + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_lb_no_v + register: epg_to_contract_present_no_lb_no_v + + - name: create epg contract to epg with no previous again & no verify + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_lb_no_v + register: epg_to_contract_present_no_lb_no_v_again + + - name: update epg contract to epg with no previous & no verify + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_lb_no_v + priority: level1 + register: update_epg_to_contract_present_no_lb_no_v + + - name: delete epg contract to epg with no previous & no verify + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_lb_no_v + state: absent + register: delete_epg_to_contract_present_no_lb_no_v + + - name: delete epg contract to epg with no previous again & no verify + cisco.aci.aci_epg_to_contract: + <<: *aci_epg_to_contract_no_lb_no_v + state: absent + register: delete_epg_to_contract_present_no_lb_no_v_again + + - name: no previous & no verify asserts + ansible.builtin.assert: + that: + - epg_to_contract_present_no_lb_no_v_cm is changed + - epg_to_contract_present_no_lb_no_v_cm.current.0 == epg_to_contract_present_no_lb_no_v_cm.proposed + - epg_to_contract_present_no_lb_no_v_cm.previous == [] + - epg_to_contract_present_no_lb_no_v_cm.proposed.fvRsCons.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rscons-anstest_no_lb_no_v" + - epg_to_contract_present_no_lb_no_v_cm.proposed.fvRsCons.attributes.annotation == "orchestrator:ansible" + - epg_to_contract_present_no_lb_no_v is changed + - epg_to_contract_present_no_lb_no_v.current.0 == epg_to_contract_present_no_lb_no_v.proposed + - epg_to_contract_present_no_lb_no_v.previous == [] + - epg_to_contract_present_no_lb_no_v_again is changed + - epg_to_contract_present_no_lb_no_v_again.current == epg_to_contract_present_no_lb_no_v.current + - epg_to_contract_present_no_lb_no_v_again.proposed == epg_to_contract_present_no_lb_no_v.proposed + - epg_to_contract_present_no_lb_no_v_again.previous == [] + - update_epg_to_contract_present_no_lb_no_v is changed + - update_epg_to_contract_present_no_lb_no_v.current.0.fvRsCons.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rscons-anstest_no_lb_no_v" + - update_epg_to_contract_present_no_lb_no_v.current.0.fvRsCons.attributes.annotation == "orchestrator:ansible" + - update_epg_to_contract_present_no_lb_no_v.current.0.fvRsCons.attributes.prio == "level1" + - delete_epg_to_contract_present_no_lb_no_v is changed + - delete_epg_to_contract_present_no_lb_no_v.current == [] + - delete_epg_to_contract_present_no_lb_no_v.previous == [] + - delete_epg_to_contract_present_no_lb_no_v.proposed == {} + - delete_epg_to_contract_present_no_lb_no_v_again is changed + - delete_epg_to_contract_present_no_lb_no_v_again.current == [] + - delete_epg_to_contract_present_no_lb_no_v_again.previous == [] + - delete_epg_to_contract_present_no_lb_no_v_again.proposed == {} + - name: get binding cisco.aci.aci_epg_to_contract: <<: *aci_epg_provide_present2 @@ -313,7 +448,7 @@ <<: *aci_tenant_present state: absent contract: "{{ item }}" - with_items: ["anstest_http", "anstest_https", "anstest_db"] + with_items: ["anstest_http", "anstest_https", "anstest_db", "anstest_no_previous", "anstest_no_lb_no_v"] - name: cleanup epg cisco.aci.aci_epg: diff --git a/tests/integration/targets/aci_l3out_static_routes/tasks/main.yml b/tests/integration/targets/aci_l3out_static_routes/tasks/main.yml index 90f8c4cbb..9fe249ee5 100644 --- a/tests/integration/targets/aci_l3out_static_routes/tasks/main.yml +++ b/tests/integration/targets/aci_l3out_static_routes/tasks/main.yml @@ -129,6 +129,146 @@ - cm_add_route_again.proposed.ipRouteP.attributes.ip == "10.1.0.1/24" - nm_add_route_again.current[0].ipRouteP.attributes.ip == "10.1.0.1/24" + # TEST NO PREVIOUS + - name: create static route with no previous (check mode) + cisco.aci.aci_l3out_static_routes: &aci_l3out_static_routes_no_previous + <<: *route_present + prefix: 10.1.0.2/24 + preference: 10 + no_previous: true + check_mode: true + register: static_route_present_no_previous_cm + + - name: create static route with no previous + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_previous + register: static_route_present_no_previous + + - name: create static route with no previous again + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_previous + register: static_route_present_no_previous_again + + - name: update static route with no previous + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_previous + preference: 20 + register: update_static_route_present_no_previous + + - name: delete static route with no previous + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_previous + state: absent + register: delete_static_route_present_no_previous + + - name: delete static route with no previous again + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_previous + state: absent + register: delete_static_route_present_no_previous_again + + - name: no previous asserts + ansible.builtin.assert: + that: + - static_route_present_no_previous_cm is changed + - static_route_present_no_previous_cm.current == [] + - static_route_present_no_previous_cm.previous == [] + - static_route_present_no_previous_cm.proposed.ipRouteP.attributes.dn == "uni/tn-ansible_tenant/out-ansible_l3out/lnodep-lNode/rsnodeL3OutAtt-[topology/pod-1/node-101]/rt-[10.1.0.2/24]" + - static_route_present_no_previous_cm.proposed.ipRouteP.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_previous is changed + - static_route_present_no_previous.current.0.ipRouteP.attributes.dn == "uni/tn-ansible_tenant/out-ansible_l3out/lnodep-lNode/rsnodeL3OutAtt-[topology/pod-1/node-101]/rt-[10.1.0.2/24]" + - static_route_present_no_previous.current.0.ipRouteP.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_previous.current.0.ipRouteP.attributes.pref == "10" + - static_route_present_no_previous.proposed.ipRouteP.attributes.dn == "uni/tn-ansible_tenant/out-ansible_l3out/lnodep-lNode/rsnodeL3OutAtt-[topology/pod-1/node-101]/rt-[10.1.0.2/24]" + - static_route_present_no_previous.proposed.ipRouteP.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_previous.proposed.ipRouteP.attributes.pref == "10" + - static_route_present_no_previous.previous == [] + - static_route_present_no_previous_again is changed + - static_route_present_no_previous_again.current == static_route_present_no_previous.current + - static_route_present_no_previous_again.proposed == static_route_present_no_previous.proposed + - static_route_present_no_previous_again.previous == [] + - update_static_route_present_no_previous is changed + - update_static_route_present_no_previous.current.0.ipRouteP.attributes.dn == "uni/tn-ansible_tenant/out-ansible_l3out/lnodep-lNode/rsnodeL3OutAtt-[topology/pod-1/node-101]/rt-[10.1.0.2/24]" + - update_static_route_present_no_previous.current.0.ipRouteP.attributes.annotation == "orchestrator:ansible" + - update_static_route_present_no_previous.current.0.ipRouteP.attributes.pref == "20" + - delete_static_route_present_no_previous is changed + - delete_static_route_present_no_previous.current == [] + - delete_static_route_present_no_previous.previous == [] + - delete_static_route_present_no_previous.proposed == {} + - delete_static_route_present_no_previous_again is changed + - delete_static_route_present_no_previous_again.current == [] + - delete_static_route_present_no_previous_again.previous == [] + - delete_static_route_present_no_previous_again.proposed == {} + + # TEST NO PREVIOUS & NO VERIFICATION + - name: create static route with no previous & no verify (check mode) + cisco.aci.aci_l3out_static_routes: &aci_l3out_static_routes_no_lb_no_v + <<: *route_present + prefix: 10.1.0.2/24 + preference: 10 + no_previous: true + no_verify: true + check_mode: true + register: static_route_present_no_lb_no_v_cm + + - name: create static route with no previous & no verify + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_lb_no_v + register: static_route_present_no_lb_no_v + + - name: create static route with no previous again & no verify + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_lb_no_v + register: static_route_present_no_lb_no_v_again + + - name: update static route with no previous & no verify + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_lb_no_v + preference: 20 + register: update_static_route_present_no_lb_no_v + + - name: delete static route with no previous & no verify + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_lb_no_v + state: absent + register: delete_static_route_present_no_lb_no_v + + - name: delete static route with no previous again & no verify + cisco.aci.aci_l3out_static_routes: + <<: *aci_l3out_static_routes_no_lb_no_v + state: absent + register: delete_static_route_present_no_lb_no_v_again + + - name: no previous & no verify asserts + ansible.builtin.assert: + that: + - static_route_present_no_lb_no_v_cm is changed + - static_route_present_no_lb_no_v_cm.current.0 == static_route_present_no_lb_no_v_cm.proposed + - static_route_present_no_lb_no_v_cm.previous == [] + - static_route_present_no_lb_no_v_cm.proposed.ipRouteP.attributes.dn == "uni/tn-ansible_tenant/out-ansible_l3out/lnodep-lNode/rsnodeL3OutAtt-[topology/pod-1/node-101]/rt-[10.1.0.2/24]" + - static_route_present_no_lb_no_v_cm.proposed.ipRouteP.attributes.pref == "10" + - static_route_present_no_lb_no_v_cm.proposed.ipRouteP.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_lb_no_v is changed + - static_route_present_no_lb_no_v.current.0 == static_route_present_no_lb_no_v.proposed + - static_route_present_no_lb_no_v.previous == [] + - static_route_present_no_lb_no_v_again is changed + - static_route_present_no_lb_no_v_again.current == static_route_present_no_lb_no_v.current + - static_route_present_no_lb_no_v_again.proposed == static_route_present_no_lb_no_v.proposed + - static_route_present_no_lb_no_v_again.previous == [] + - update_static_route_present_no_lb_no_v is changed + - update_static_route_present_no_lb_no_v.current.0 == update_static_route_present_no_lb_no_v.proposed + - update_static_route_present_no_lb_no_v.current.0.ipRouteP.attributes.dn == "uni/tn-ansible_tenant/out-ansible_l3out/lnodep-lNode/rsnodeL3OutAtt-[topology/pod-1/node-101]/rt-[10.1.0.2/24]" + - update_static_route_present_no_lb_no_v.current.0.ipRouteP.attributes.annotation == "orchestrator:ansible" + - update_static_route_present_no_lb_no_v.current.0.ipRouteP.attributes.pref == "20" + - delete_static_route_present_no_lb_no_v is changed + - delete_static_route_present_no_lb_no_v.current == [] + - delete_static_route_present_no_lb_no_v.previous == [] + - delete_static_route_present_no_lb_no_v.proposed == {} + - delete_static_route_present_no_lb_no_v_again is changed + - delete_static_route_present_no_lb_no_v_again.current == [] + - delete_static_route_present_no_lb_no_v_again.previous == [] + - delete_static_route_present_no_lb_no_v_again.proposed == {} + - name: Query system information cisco.aci.aci_system: <<: *aci_info diff --git a/tests/integration/targets/aci_static_binding_to_epg/tasks/main.yml b/tests/integration/targets/aci_static_binding_to_epg/tasks/main.yml index 7917551ad..bbbd13b83 100644 --- a/tests/integration/targets/aci_static_binding_to_epg/tasks/main.yml +++ b/tests/integration/targets/aci_static_binding_to_epg/tasks/main.yml @@ -185,6 +185,146 @@ - missing_required_present is failed - primary_encap_id_invalid is failed + # TEST NO PREVIOUS + - name: create static-binding to epg with no previous (check mode) + cisco.aci.aci_static_binding_to_epg: &aci_static_binding_to_epg_no_previous + <<: *aci_static_binding_to_epg_present + interface: '1/8' + description: Ansible test + no_previous: true + check_mode: true + register: static_route_present_no_previous_cm + + - name: create static-binding to epg with no previous + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_previous + register: static_route_present_no_previous + + - name: create static-binding to epg with no previous again + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_previous + register: static_route_present_no_previous_again + + - name: update static-binding to epg with no previous + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_previous + description: Ansible test 2 + register: update_static_route_present_no_previous + + - name: delete static-binding to epg with no previous + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_previous + state: absent + register: delete_static_route_present_no_previous + + - name: delete static-binding to epg with no previous again + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_previous + state: absent + register: delete_static_route_present_no_previous_again + + - name: no previous asserts + ansible.builtin.assert: + that: + - static_route_present_no_previous_cm is changed + - static_route_present_no_previous_cm.current == [] + - static_route_present_no_previous_cm.previous == [] + - static_route_present_no_previous_cm.proposed.fvRsPathAtt.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/8]]" + - static_route_present_no_previous_cm.proposed.fvRsPathAtt.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_previous is changed + - static_route_present_no_previous.current.0.fvRsPathAtt.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/8]]" + - static_route_present_no_previous.current.0.fvRsPathAtt.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_previous.current.0.fvRsPathAtt.attributes.descr == "Ansible test" + - static_route_present_no_previous.proposed.fvRsPathAtt.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/8]]" + - static_route_present_no_previous.proposed.fvRsPathAtt.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_previous.proposed.fvRsPathAtt.attributes.descr == "Ansible test" + - static_route_present_no_previous.previous == [] + - static_route_present_no_previous_again is changed + - static_route_present_no_previous_again.current == static_route_present_no_previous.current + - static_route_present_no_previous_again.proposed == static_route_present_no_previous.proposed + - static_route_present_no_previous_again.previous == [] + - update_static_route_present_no_previous is changed + - update_static_route_present_no_previous.current.0.fvRsPathAtt.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/8]]" + - update_static_route_present_no_previous.current.0.fvRsPathAtt.attributes.annotation == "orchestrator:ansible" + - update_static_route_present_no_previous.current.0.fvRsPathAtt.attributes.descr == "Ansible test 2" + - delete_static_route_present_no_previous is changed + - delete_static_route_present_no_previous.current == [] + - delete_static_route_present_no_previous.previous == [] + - delete_static_route_present_no_previous.proposed == {} + - delete_static_route_present_no_previous_again is changed + - delete_static_route_present_no_previous_again.current == [] + - delete_static_route_present_no_previous_again.previous == [] + - delete_static_route_present_no_previous_again.proposed == {} + + # TEST NO PREVIOUS & NO VERIFICATION + - name: create static-binding to epg with no previous & no verify (check mode) + cisco.aci.aci_static_binding_to_epg: &aci_static_binding_to_epg_no_lb_no_v + <<: *aci_static_binding_to_epg_present + interface: '1/8' + description: Ansible test + no_previous: true + no_verify: true + check_mode: true + register: static_route_present_no_lb_no_v_cm + + - name: create static-binding to epg with no previous & no verify + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_lb_no_v + register: static_route_present_no_lb_no_v + + - name: create static-binding to epg with no previous again & no verify + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_lb_no_v + register: static_route_present_no_lb_no_v_again + + - name: update static-binding to epg with no previous & no verify + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_lb_no_v + description: Ansible test 2 + register: update_static_route_present_no_lb_no_v + + - name: delete static-binding to epg with no previous & no verify + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_lb_no_v + state: absent + register: delete_static_route_present_no_lb_no_v + + - name: delete static-binding to epg with no previous again & no verify + cisco.aci.aci_static_binding_to_epg: + <<: *aci_static_binding_to_epg_no_lb_no_v + state: absent + register: delete_static_route_present_no_lb_no_v_again + + - name: no previous & no verify asserts + ansible.builtin.assert: + that: + - static_route_present_no_lb_no_v_cm is changed + - static_route_present_no_lb_no_v_cm.current.0 == static_route_present_no_lb_no_v_cm.proposed + - static_route_present_no_lb_no_v_cm.previous == [] + - static_route_present_no_lb_no_v_cm.proposed.fvRsPathAtt.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/8]]" + - static_route_present_no_lb_no_v_cm.proposed.fvRsPathAtt.attributes.descr == "Ansible test" + - static_route_present_no_lb_no_v_cm.proposed.fvRsPathAtt.attributes.annotation == "orchestrator:ansible" + - static_route_present_no_lb_no_v is changed + - static_route_present_no_lb_no_v.current.0 == static_route_present_no_lb_no_v.proposed + - static_route_present_no_lb_no_v.previous == [] + - static_route_present_no_lb_no_v_again is changed + - static_route_present_no_lb_no_v_again.current == static_route_present_no_lb_no_v.current + - static_route_present_no_lb_no_v_again.proposed == static_route_present_no_lb_no_v.proposed + - static_route_present_no_lb_no_v_again.previous == [] + - update_static_route_present_no_lb_no_v is changed + - update_static_route_present_no_lb_no_v.current.0 == update_static_route_present_no_lb_no_v.proposed + - update_static_route_present_no_lb_no_v.current.0.fvRsPathAtt.attributes.dn == "uni/tn-ansible_test/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/8]]" + - update_static_route_present_no_lb_no_v.current.0.fvRsPathAtt.attributes.annotation == "orchestrator:ansible" + - update_static_route_present_no_lb_no_v.current.0.fvRsPathAtt.attributes.descr == "Ansible test 2" + - delete_static_route_present_no_lb_no_v is changed + - delete_static_route_present_no_lb_no_v.current == [] + - delete_static_route_present_no_lb_no_v.previous == [] + - delete_static_route_present_no_lb_no_v.proposed == {} + - delete_static_route_present_no_lb_no_v_again is changed + - delete_static_route_present_no_lb_no_v_again.current == [] + - delete_static_route_present_no_lb_no_v_again.previous == [] + - delete_static_route_present_no_lb_no_v_again.proposed == {} + - name: Query specific binding cisco.aci.aci_static_binding_to_epg: <<: *primary_encap_id_present