diff --git a/plugins/modules/ndo_mcp_global_policy.py b/plugins/modules/ndo_mcp_global_policy.py new file mode 100644 index 00000000..078ef63e --- /dev/null +++ b/plugins/modules/ndo_mcp_global_policy.py @@ -0,0 +1,323 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2024, Samita Bhattacharjee (@samiib) + +# 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 = r""" +--- +module: ndo_mcp_global_policy +short_description: Manage the MCP Global Policy in a Fabric Policy Template on Cisco Nexus Dashboard Orchestrator (NDO). +description: +- Manage the MisCabling Protocol (MCP) Global Policy in a Fabric Policy Template on Cisco Nexus Dashboard Orchestrator (NDO). +- There can only be a single MCP Global Policy in a Fabric Policy Template. +- This module is only supported on ND v3.1 (NDO v4.3) and later. +author: +- Samita Bhattacharjee (@samiib) +options: + template: + description: + - The name of the template. + - The template must be a Fabric Policy template. + type: str + aliases: [ fabric_template ] + required: true + name: + description: + - The name of the MCP Global Policy. + type: str + aliases: [ mcp_global_policy ] + uuid: + description: + - The UUID of the MCP Global Policy. + type: str + aliases: [ mcp_global_policy_uuid ] + description: + description: + - The description of the MCP Global Policy. + - Providing an empty string will remove the O(description="") from the MCP Global Policy. + type: str + admin_state: + description: + - The administrative state of the MCP Global Policy. + - Defaults to C(enabled) when unset during creation. + type: str + choices: [ enabled, disabled ] + key: + description: + - The key of the MCP Global Policy. + type: str + per_vlan: + description: + - When enabled MCP will send packets on a per End Point Group (EPG) basis. + - If disabled, the packets will only be sent on untagged EPGs which allows detecting loops in the native VLAN only. + - Defaults to C(disabled) when unset during creation. + type: str + choices: [ enabled, disabled ] + aliases: [ per_epg, mcp_pdu_per_vlan ] + loop_detection_factor: + description: + - The amount of MCP packets that will be received before port disable loop protection action takes place. + - Defaults to 3 when unset during creation. + - The value must be between 1 and 255. + type: int + aliases: [ loop_factor, loop_detection_mult_factor ] + port_disable: + description: + - Enable or disable port disabling when MCP packets are received. + - Defaults to C(enabled) when unset during creation. + type: str + choices: [ enabled, disabled ] + aliases: [ port_disable_protection ] + initial_delay_time: + description: + - The MCP initial delay time in seconds. + - Defaults to 180 when unset during creation. + - The value must be between 0 and 1800. + type: int + aliases: [ initial_delay ] + transmission_frequency_sec: + description: + - The MCP transmission frequency in seconds. + - Defaults to 2 when unset during creation. + - The value must be between 0 and 300. + type: int + aliases: [ tx_freq ] + transmission_frequency_msec: + description: + - The MCP transmission frequency in milliseconds. + - Defaults to 0 when unset during creation. + - The value must be between 0 and 999. + type: int + aliases: [ tx_freq_ms ] + state: + description: + - Use C(absent) for removing. + - Use C(query) for listing an object or multiple objects. + - Use C(present) for creating or updating. + type: str + choices: [ absent, query, present ] + default: query +notes: +- The O(template) must exist before using this module in your playbook. + Use M(cisco.mso.ndo_template) to create the Fabric Policy template. +- Attempts to create any additional MCP Global Policies will only update the existing + object in the Fabric Policy template. +seealso: +- module: cisco.mso.ndo_template +extends_documentation_fragment: cisco.mso.modules +""" + +EXAMPLES = r""" +- name: Create the MCP Global Policy object + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + name: example_mcp_global_policy + state: present + register: mcp_global_policy_new + +- name: Create the MCP Global Policy object with all attributes + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + name: example_mcp_global_policy + description: A Global MCP Policy + key: cisco + admin_state: enabled + per_vlan: enabled + loop_detection_factor: 3 + port_disable: enabled + initial_delay_time: 180 + transmission_frequency_sec: 2 + transmission_frequency_msec: 10 + state: present + register: mcp_global_policy_all + +- name: Update the MCP Global Policy object with UUID + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + name: mcp_global_policy_update + uuid: "{{ mcp_global_policy_all.current.uuid }}" + state: present + +- name: Query the MCP Global Policy object with name + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + name: example_mcp_global_policy + state: query + register: query_name + +- name: Query the MCP Global Policy object with UUID + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + uuid: "{{ mcp_global_policy_all.current.uuid }}" + state: query + register: query_uuid + +- name: Query the MCP Global Policy object in a Fabric Template + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + state: query + register: query_all + +- name: Delete the MCP Global Policy object with name + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + name: example_mcp_global_policy + state: absent + +- name: Delete the MCP Global Policy object with UUID + cisco.mso.ndo_mcp_global_policy: + host: mso_host + username: admin + password: SomeSecretPassword + template: fabric_template + uuid: "{{ mcp_global_policy_all.current.uuid }}" + state: absent +""" + +RETURN = r""" +""" + +import copy +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.mso.plugins.module_utils.mso import MSOModule, mso_argument_spec +from ansible_collections.cisco.mso.plugins.module_utils.constants import ENABLED_OR_DISABLED_TO_BOOL_STRING_MAP +from ansible_collections.cisco.mso.plugins.module_utils.template import MSOTemplate +from ansible_collections.cisco.mso.plugins.module_utils.utils import append_update_ops_data + + +def main(): + argument_spec = mso_argument_spec() + argument_spec.update( + template=dict(type="str", required=True, aliases=["fabric_template"]), + name=dict(type="str", aliases=["mcp_global_policy"]), + uuid=dict(type="str", aliases=["mcp_global_policy_uuid"]), + description=dict(type="str"), + admin_state=dict(type="str", choices=["enabled", "disabled"]), + key=dict(type="str", no_log=False), + per_vlan=dict( + type="str", + aliases=["per_epg", "mcp_pdu_per_vlan"], + choices=["enabled", "disabled"], + ), + loop_detection_factor=dict(type="int", aliases=["loop_factor", "loop_detection_mult_factor"]), + port_disable=dict( + type="str", + aliases=["port_disable_protection"], + choices=["enabled", "disabled"], + ), + initial_delay_time=dict(type="int", aliases=["initial_delay"]), + transmission_frequency_sec=dict(type="int", aliases=["tx_freq"]), + transmission_frequency_msec=dict(type="int", aliases=["tx_freq_ms"]), + state=dict(type="str", default="query", choices=["absent", "query", "present"]), + ) + + # Enforcing that a user must specify a name or uuid when + # adding, updating or removing even though there is only one policy per template. + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "absent", ["name", "uuid"], True], + ["state", "present", ["name", "uuid"], True], + ], + ) + + mso = MSOModule(module) + + name = module.params.get("name") + uuid = module.params.get("uuid") + state = module.params.get("state") + per_vlan = module.params.get("per_vlan") + port_disable = module.params.get("port_disable") + + mso_values = { + "name": name, + "description": module.params.get("description"), + "adminState": module.params.get("admin_state"), + "key": module.params.get("key"), + "enablePduPerVlan": ENABLED_OR_DISABLED_TO_BOOL_STRING_MAP.get(per_vlan), + "loopDetectMultFactor": module.params.get("loop_detection_factor"), + "protectPortDisable": ENABLED_OR_DISABLED_TO_BOOL_STRING_MAP.get(port_disable), + "initialDelayTime": module.params.get("initial_delay_time"), + "txFreq": module.params.get("transmission_frequency_sec"), + "txFreqMsec": module.params.get("transmission_frequency_msec"), + } + + ops = [] + + mso_template = MSOTemplate(mso, "fabric_policy", module.params.get("template")) + mso_template.validate_template("fabricPolicy") + + object_description = "MCP Global Policy" + object_base_path = "/fabricPolicyTemplate/template/mcpGlobalPolicy" + + existing_mcp_global_policy = mso_template.template.get("fabricPolicyTemplate", {}).get("template", {}).get("mcpGlobalPolicy", {}) + + if state in ["query", "absent"] and existing_mcp_global_policy == {}: + mso.exit_json() + + elif state == "query" and not (name or uuid): + mso.existing = [existing_mcp_global_policy] + + elif existing_mcp_global_policy and (name or uuid): + mso.existing = mso.previous = copy.deepcopy(existing_mcp_global_policy) + if uuid and mso.existing.get("uuid") != uuid: + mso.fail_json(msg="{0} with the UUID: '{1}' not found".format(object_description, uuid)) + + if state == "present": + if mso.existing: + proposed_payload = copy.deepcopy(mso.existing) + append_update_ops_data(ops, proposed_payload, object_base_path, mso_values) + mso.sanitize(proposed_payload, collate=True) + else: + if uuid: + mso.fail_json(msg="{0} cannot be created with a UUID".format(object_description)) + mso.sanitize(mso_values) + ops.append(dict(op="add", path=object_base_path, value=mso.sent)) + + mso.existing = mso.proposed + + elif state == "absent": + if mso.existing: + ops.append(dict(op="remove", path=object_base_path)) + + if not module.check_mode and ops: + response_object = mso.request(mso_template.template_path, method="PATCH", data=ops) + mso.existing = response_object.get("fabricPolicyTemplate", {}).get("template", {}).get("mcpGlobalPolicy", {}) + elif module.check_mode and state != "query": # When the state is present/absent with check mode + mso.existing = mso.proposed if state == "present" else {} + + mso.exit_json() + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/ndo_mcp_global_policy/aliases b/tests/integration/targets/ndo_mcp_global_policy/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/tests/integration/targets/ndo_mcp_global_policy/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/tests/integration/targets/ndo_mcp_global_policy/tasks/main.yml b/tests/integration/targets/ndo_mcp_global_policy/tasks/main.yml new file mode 100644 index 00000000..5449813f --- /dev/null +++ b/tests/integration/targets/ndo_mcp_global_policy/tasks/main.yml @@ -0,0 +1,320 @@ +# Test code for the MSO modules +# Copyright: (c) 2024, Samita Bhattacharjee (@samiib) + +# 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 MultiSite host, username and password + ansible.builtin.fail: + msg: 'Please define the following variables: mso_hostname, mso_username and mso_password.' + when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined + +# CLEAN ENVIRONMENT +- name: Set vars + ansible.builtin.set_fact: + mso_info: &mso_info + host: '{{ mso_hostname }}' + username: '{{ mso_username }}' + password: '{{ mso_password }}' + validate_certs: '{{ mso_validate_certs | default(false) }}' + use_ssl: '{{ mso_use_ssl | default(true) }}' + use_proxy: '{{ mso_use_proxy | default(true) }}' + output_level: '{{ mso_output_level | default("debug") }}' + +# QUERY VERSION +- name: Query MSO version + cisco.mso.mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version >= 4.3 + when: version.current.version is version('4.3', '>=') + block: + - name: Remove fabric template + cisco.mso.ndo_template: &template_absent + <<: *mso_info + name: ansible_fabric_policy_template + type: fabric_policy + state: absent + + - name: Create a fabric template + cisco.mso.ndo_template: + <<: *template_absent + state: present + + # CREATE + - name: Create the MCP Global Policy (check mode) + cisco.mso.ndo_mcp_global_policy: &add_mcp_global_policy + <<: *mso_info + template: ansible_fabric_policy_template + name: ansible_mcp_global_policy + state: present + check_mode: true + register: cm_add_mcp_global_policy + + - name: Create the MCP Global Policy + cisco.mso.ndo_mcp_global_policy: + <<: *add_mcp_global_policy + register: nm_add_mcp_global_policy + + - name: Create the MCP Global Policy again + cisco.mso.ndo_mcp_global_policy: + <<: *add_mcp_global_policy + register: nm_add_mcp_global_policy_again + + - name: Assert the MCP Global Policy was created + ansible.builtin.assert: + that: + - cm_add_mcp_global_policy is changed + - nm_add_mcp_global_policy is changed + - cm_add_mcp_global_policy.previous == nm_add_mcp_global_policy.previous == {} + - cm_add_mcp_global_policy.current == cm_add_mcp_global_policy.proposed + - cm_add_mcp_global_policy.current.name == nm_add_mcp_global_policy.current.name == "ansible_mcp_global_policy" + - nm_add_mcp_global_policy.current.description == "" + - nm_add_mcp_global_policy.current.adminState == "disabled" + - nm_add_mcp_global_policy.current.enablePduPerVlan == false + - nm_add_mcp_global_policy.current.loopDetectMultFactor == 3 + - nm_add_mcp_global_policy.current.protectPortDisable == true + - nm_add_mcp_global_policy.current.initialDelayTime == 180 + - nm_add_mcp_global_policy.current.txFreq == 2 + - nm_add_mcp_global_policy.current.txFreqMsec == 0 + - nm_add_mcp_global_policy.current.uuid is defined + - nm_add_mcp_global_policy.current.key is undefined + - nm_add_mcp_global_policy_again is not changed + - nm_add_mcp_global_policy_again.previous.name == nm_add_mcp_global_policy_again.current.name == "ansible_mcp_global_policy" + - nm_add_mcp_global_policy_again.previous.description == nm_add_mcp_global_policy.current.description == "" + - nm_add_mcp_global_policy_again.previous.adminState == nm_add_mcp_global_policy.current.adminState == "disabled" + - nm_add_mcp_global_policy_again.previous.enablePduPerVlan == nm_add_mcp_global_policy.current.enablePduPerVlan == false + - nm_add_mcp_global_policy_again.previous.loopDetectMultFactor == nm_add_mcp_global_policy.current.loopDetectMultFactor == 3 + - nm_add_mcp_global_policy_again.previous.protectPortDisable == nm_add_mcp_global_policy.current.protectPortDisable == true + - nm_add_mcp_global_policy_again.previous.initialDelayTime == nm_add_mcp_global_policy.current.initialDelayTime == 180 + - nm_add_mcp_global_policy_again.previous.txFreq == nm_add_mcp_global_policy.current.txFreq == 2 + - nm_add_mcp_global_policy_again.previous.txFreqMsec == nm_add_mcp_global_policy.current.txFreqMsec == 0 + - nm_add_mcp_global_policy_again.previous.uuid is defined + - nm_add_mcp_global_policy_again.current.uuid is defined + + # Update + - name: Update the MCP Global Policy (check mode) + cisco.mso.ndo_mcp_global_policy: &update_mcp_global_policy + <<: *mso_info + template: ansible_fabric_policy_template + name: ansible_mcp_global_policy_new + description: A Global MCP Policy + key: cisco + admin_state: enabled + per_vlan: enabled + loop_detection_factor: 4 + port_disable: disabled + initial_delay_time: 200 + transmission_frequency_sec: 3 + transmission_frequency_msec: 10 + state: present + check_mode: true + register: cm_update_mcp_global_policy + + - name: Update the MCP Global Policy + cisco.mso.ndo_mcp_global_policy: + <<: *update_mcp_global_policy + register: nm_update_mcp_global_policy + + - name: Update the MCP Global Policy again + cisco.mso.ndo_mcp_global_policy: + <<: *update_mcp_global_policy + register: update_mcp_global_policy_again + + - name: Update the MCP Global Policy with incorrect UUID + cisco.mso.ndo_mcp_global_policy: + <<: *update_mcp_global_policy + uuid: bad-uuid + ignore_errors: true + register: nm_update_mcp_global_policy_no_uuid + + - name: Assert the MCP Global Policy updated + ansible.builtin.assert: + that: + - cm_update_mcp_global_policy is changed + - nm_update_mcp_global_policy is changed + - cm_update_mcp_global_policy.previous == nm_update_mcp_global_policy.previous + - cm_update_mcp_global_policy.previous.name == nm_update_mcp_global_policy.previous.name == "ansible_mcp_global_policy" + - cm_update_mcp_global_policy.previous.adminState == nm_update_mcp_global_policy.previous.adminState == "disabled" + - cm_update_mcp_global_policy.previous.description == nm_update_mcp_global_policy.previous.description == "" + - cm_update_mcp_global_policy.previous.enablePduPerVlan == nm_update_mcp_global_policy.previous.enablePduPerVlan == false + - cm_update_mcp_global_policy.previous.key is undefined + - nm_update_mcp_global_policy.previous.key is undefined + - cm_update_mcp_global_policy.previous.loopDetectMultFactor == nm_update_mcp_global_policy.previous.loopDetectMultFactor == 3 + - cm_update_mcp_global_policy.previous.protectPortDisable == nm_update_mcp_global_policy.previous.protectPortDisable == true + - cm_update_mcp_global_policy.previous.txFreq == nm_update_mcp_global_policy.previous.txFreq == 2 + - cm_update_mcp_global_policy.previous.txFreqMsec == nm_update_mcp_global_policy.previous.txFreqMsec == 0 + - cm_update_mcp_global_policy.current == cm_update_mcp_global_policy.proposed + - cm_update_mcp_global_policy.current.name == nm_update_mcp_global_policy.current.name == "ansible_mcp_global_policy_new" + - cm_update_mcp_global_policy.current.adminState == nm_update_mcp_global_policy.current.adminState == "enabled" + - cm_update_mcp_global_policy.current.description == nm_update_mcp_global_policy.current.description == "A Global MCP Policy" + - cm_update_mcp_global_policy.current.enablePduPerVlan == nm_update_mcp_global_policy.current.enablePduPerVlan == true + - cm_update_mcp_global_policy.current.key == nm_update_mcp_global_policy.current.key == "cisco" + - cm_update_mcp_global_policy.current.loopDetectMultFactor == nm_update_mcp_global_policy.current.loopDetectMultFactor == 4 + - cm_update_mcp_global_policy.current.protectPortDisable == nm_update_mcp_global_policy.current.protectPortDisable == false + - cm_update_mcp_global_policy.current.txFreq == nm_update_mcp_global_policy.current.txFreq == 3 + - cm_update_mcp_global_policy.current.txFreqMsec == nm_update_mcp_global_policy.current.txFreqMsec == 10 + - update_mcp_global_policy_again is not changed + - update_mcp_global_policy_again.previous == update_mcp_global_policy_again.current + - nm_update_mcp_global_policy_no_uuid is failed + - nm_update_mcp_global_policy_no_uuid.msg == "MCP Global Policy with the UUID{{":"}} 'bad-uuid' not found" + + # QUERY + - name: Query the MCP Global Policy with name + cisco.mso.ndo_mcp_global_policy: + <<: *mso_info + template: ansible_fabric_policy_template + name: ansible_mcp_global_policy_new + state: query + register: query_mcp_policy_with_name + + - name: Query the MCP Global Policy with UUID + cisco.mso.ndo_mcp_global_policy: + <<: *mso_info + template: ansible_fabric_policy_template + uuid: '{{update_mcp_global_policy_again.current.uuid}}' + state: query + register: query_mcp_policy_with_uuid + + - name: Query the MCP Global Policy without name or UUID + cisco.mso.ndo_mcp_global_policy: &query_mcp_global_policy + <<: *mso_info + template: ansible_fabric_policy_template + state: query + register: query_all_mcp_policy + + - name: Assert MCP Global Policy is queried + ansible.builtin.assert: + that: + - query_mcp_policy_with_name is not changed + - query_mcp_policy_with_uuid is not changed + - query_all_mcp_policy is not changed + - query_mcp_policy_with_uuid.current == query_mcp_policy_with_name.current + - query_mcp_policy_with_name.current.name == "ansible_mcp_global_policy_new" + - query_mcp_policy_with_name.current.key == "cisco" + - query_mcp_policy_with_name.current.description == "A Global MCP Policy" + - query_mcp_policy_with_name.current.adminState == "enabled" + - query_mcp_policy_with_name.current.enablePduPerVlan == true + - query_mcp_policy_with_name.current.protectPortDisable == false + - query_mcp_policy_with_name.current.loopDetectMultFactor == 4 + - query_mcp_policy_with_name.current.txFreq == 3 + - query_mcp_policy_with_name.current.txFreqMsec == 10 + - query_mcp_policy_with_name.current.uuid is defined + - query_all_mcp_policy.current | length == 1 # Can only be one + + # DELETE + - name: Delete MCP Global Policy with name (check mode) + cisco.mso.ndo_mcp_global_policy: &delete_mcp_global_policy + <<: *mso_info + template: ansible_fabric_policy_template + name: ansible_mcp_global_policy_changed + state: absent + check_mode: true + register: cm_delete_mcp_global_policy + + - name: Delete MCP Global Policy with name + cisco.mso.ndo_mcp_global_policy: + <<: *delete_mcp_global_policy + register: nm_delete_mcp_global_policy + + - name: Delete MCP Global Policy with name again + cisco.mso.ndo_mcp_global_policy: + <<: *delete_mcp_global_policy + register: nm_delete_mcp_global_policy_again + + - name: Assert that the MCP Global Policy was deleted with name + ansible.builtin.assert: + that: + - cm_delete_mcp_global_policy is changed + - nm_delete_mcp_global_policy is changed + - cm_delete_mcp_global_policy.current == nm_delete_mcp_global_policy.current == {} + - cm_delete_mcp_global_policy.previous.name == nm_delete_mcp_global_policy.previous.name == "ansible_mcp_global_policy_new" + - cm_delete_mcp_global_policy.previous.key == nm_delete_mcp_global_policy.previous.key == "cisco" + - cm_delete_mcp_global_policy.previous.description == nm_delete_mcp_global_policy.previous.description == "A Global MCP Policy" + - nm_delete_mcp_global_policy.previous.uuid is defined + - nm_delete_mcp_global_policy_again is not changed + - nm_delete_mcp_global_policy_again.previous == nm_delete_mcp_global_policy_again.current == {} + + - name: Create the MCP Global Policy + cisco.mso.ndo_mcp_global_policy: + <<: *add_mcp_global_policy + name: ansible_mcp_global_policy_again + description: An MCP Global policy to delete with UUID + register: new_mcp_global_policy + + - name: Delete the MCP Global Policy with UUID + cisco.mso.ndo_mcp_global_policy: + <<: *mso_info + template: ansible_fabric_policy_template + uuid: '{{ new_mcp_global_policy.current.uuid }}' + state: absent + register: nm_delete_mcp_global_policy_uuid + + - name: Assert that the MCP Global Policy was deleted with UUID + ansible.builtin.assert: + that: + - nm_delete_mcp_global_policy_uuid is changed + - nm_delete_mcp_global_policy_uuid.previous.uuid is defined + - nm_delete_mcp_global_policy_uuid.previous.name == "ansible_mcp_global_policy_again" + - nm_delete_mcp_global_policy_uuid.previous.description == "An MCP Global policy to delete with UUID" + - nm_delete_mcp_global_policy_uuid.current == {} + + # Errors and no policy found + - name: Query the MCP Global Policy in the template when its deleted + cisco.mso.ndo_mcp_global_policy: + <<: *query_mcp_global_policy + register: query_none + + - name: Create the MCP Global Policy with a UUID + cisco.mso.ndo_mcp_global_policy: + <<: *mso_info + template: ansible_fabric_policy_template + uuid: not-possible + state: present + ignore_errors: true + register: create_with_uuid + + - name: Create the MCP Global Policy + cisco.mso.ndo_mcp_global_policy: + <<: *add_mcp_global_policy + + - name: Update the MCP Global Policy with incorrect UUID + cisco.mso.ndo_mcp_global_policy: + <<: *mso_info + template: ansible_fabric_policy_template + uuid: non-existing-uuid + state: present + ignore_errors: true + register: update_non_existing_uuid + + - name: Delete the MCP Global Policy with incorrect UUID + cisco.mso.ndo_mcp_global_policy: + <<: *mso_info + template: ansible_fabric_policy_template + uuid: does-not-exist + state: absent + ignore_errors: true + register: delete_non_existing_uuid + + - name: Delete the MCP Global Policy + cisco.mso.ndo_mcp_global_policy: + <<: *add_mcp_global_policy + state: absent + + - name: Assert errors and no MCP Global Policy found + ansible.builtin.assert: + that: + - query_none is not changed + - query_none.current == {} + - update_non_existing_uuid is failed + - update_non_existing_uuid.msg == "MCP Global Policy with the UUID{{":"}} 'non-existing-uuid' not found" + - delete_non_existing_uuid is failed + - delete_non_existing_uuid.msg == "MCP Global Policy with the UUID{{":"}} 'does-not-exist' not found" + - create_with_uuid is failed + - create_with_uuid.msg == "MCP Global Policy cannot be created with a UUID" + + # CLEANUP TEMPLATE + - name: Ensure fabric resource policy template do not exist + cisco.mso.ndo_template: + <<: *template_absent