diff --git a/plugins/module_utils/constants.py b/plugins/module_utils/constants.py index 4147d0f35..2a6a3e883 100644 --- a/plugins/module_utils/constants.py +++ b/plugins/module_utils/constants.py @@ -46,3 +46,45 @@ 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", +} + +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_fabric_scheduler.py b/plugins/modules/aci_fabric_scheduler.py index c0297d846..364bbc7f5 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 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: @@ -32,44 +28,44 @@ 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 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: - - This is the name for your what recurring or oneTime execution + - The name of the schedule window. + - This is 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 maximum 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'] + 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 ] @@ -82,56 +78,63 @@ - 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 = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success @@ -285,6 +288,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 +332,7 @@ def main(): target_filter={"name": name}, module_object=name, ), + child_classes=child_classes, ) aci.get_existing() diff --git a/plugins/modules/aci_firmware_group.py b/plugins/modules/aci_firmware_group.py index 1a9db1a6c..9687b05f3 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,61 @@ 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 + - Name of the firmware group. + type: str + policy: + description: + - 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 + aliases: [ firmwarepol ] + type_group: + 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 of 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 +notes: +- 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 +- 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 +75,7 @@ username: admin password: SomeSecretPassword group: fmgroup - firmwarepol: fmpolicy1 + policy: fmpolicy1 state: present delegate_to: localhost @@ -88,7 +108,7 @@ register: query_result """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success @@ -195,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(): @@ -203,7 +224,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", 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"), ) @@ -213,13 +236,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_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) @@ -240,13 +265,15 @@ def main(): aci_class="firmwareFwGrp", class_config=dict( name=group, + descr=description, + type=type_group, 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 b41a2601b..893eaa867 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 adds/deletes a node to the firmware group. 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 @@ -221,6 +225,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 +240,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_firmware_policy.py b/plugins/modules/aci_firmware_policy.py index bbe37ecfd..50b41a960 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,69 +11,124 @@ 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 compatibility check can be explicitly ignored while assigning the firmware. 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 + aliases: [ ignoreCompat ] + 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: - - 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 - 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. - - 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: - 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 = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success @@ -180,6 +236,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(): @@ -188,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", aliases=["ignoreCompat"]), + sr_upgrade=dict(type="bool"), + sr_version=dict(type="str"), + 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"), ) @@ -202,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 = MATCH_TRIGGER_MAPPING.get(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", @@ -230,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_interface_policy_fc.py b/plugins/modules/aci_interface_policy_fc.py index eaf8e1249..2e61a177d 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""" @@ -202,6 +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, INTERFACE_POLICY_FC_SPEED_LIST def main(): @@ -212,6 +244,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=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=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"), ) @@ -227,6 +264,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 = 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") description = module.params.get("description") state = module.params.get("state") name_alias = module.params.get("name_alias") @@ -250,6 +292,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_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..41f802e24 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,9 @@ 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 +249,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 +273,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 +300,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/plugins/modules/aci_maintenance_group.py b/plugins/modules/aci_maintenance_group.py index 98b0df9f2..d4d249e25 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,65 @@ 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 + 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: [ 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 ] + description: + description: + - Description of 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: +- 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 + 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 +111,7 @@ register: query_result """ -RETURN = """ +RETURN = r""" current: description: The existing configuration from the APIC after the module has finished returned: success @@ -191,6 +217,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 @@ -200,7 +227,10 @@ 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 + 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"), ) @@ -217,6 +247,9 @@ def main(): state = module.params.get("state") 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_group")) + description = module.params.get("description") name_alias = module.params.get("name_alias") aci = ACIModule(module) aci.construct_url( @@ -236,6 +269,9 @@ def main(): aci_class="maintMaintGrp", class_config=dict( name=group, + fwtype=firmware_nodes_type, + type=type_group, + 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 272143410..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""" @@ -218,6 +226,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 +241,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/plugins/modules/aci_maintenance_policy.py b/plugins/modules/aci_maintenance_policy.py index ddc62df09..987dc2e35 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: @@ -21,12 +22,13 @@ - 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: [ 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. @@ -36,17 +38,71 @@ 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: + 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 ] + 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: [ notify_always_between_sets, notify_never, notify_only_on_failures ] + smu_operation: + description: + - Specifies SMU operation. + type: str + 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: [ smu_reload_immediate, smu_reload_skip ] + 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 + aliases: [ ignoreCompat ] + description: + description: + - Description for the maintenance policy. + type: str + aliases: [ descr ] state: description: - Use C(present) or C(absent) for adding or removing. @@ -64,8 +120,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""" @@ -216,18 +278,36 @@ 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_SMU_OPERATION_MAPPING, + MATCH_SMU_OPERATION_FLAGS_MAPPING, + MATCH_TRIGGER_MAPPING, +) 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 - runmode=dict(type="str", default="pauseOnlyOnFailures", choices=["pauseOnlyOnFailures", "pauseNever"]), + run_mode=dict(type="str", choices=list_run_mode_choices, aliases=["runmode"]), 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", 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:]), + 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=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"), ) @@ -245,13 +325,25 @@ def main(): state = module.params.get("state") name = module.params.get("name") - runmode = module.params.get("runmode") + run_mode = module.params.get("run_mode") + graceful = aci.boolean(module.params.get("graceful"), "yes", "no") scheduler = module.params.get("scheduler") - adminst = module.params.get("adminst") - graceful = aci.boolean(module.params.get("graceful")) - ignoreCompat = aci.boolean(module.params.get("ignoreCompat")) + admin_state = module.params.get("admin_state") + download_state = module.params.get("download_state") + 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") + sr_upgrade = module.params.get("sr_upgrade") + version = module.params.get("version") + 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") + 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", @@ -269,10 +361,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=notify_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/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_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..7d1313fb2 --- /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: Create tenant + cisco.aci.aci_tenant: &aci_tenant_present + <<: *aci_tenant_absent + state: present + + - name: Create vrf + cisco.aci.aci_vrf: &aci_vrf_present + <<: *aci_tenant_present + vrf: anstest + + - 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 + 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 + cisco.aci.aci_bd: &aci_bd_present + <<: *aci_tenant_present + bd: anstest + + - 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 + 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 + 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 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..5cf88997c --- /dev/null +++ b/tests/integration/targets/aci_firmware_group/tasks/main.yml @@ -0,0 +1,154 @@ +# 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 firmware policy + 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 + policy: anstest_policy + type_group: 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 + policy: 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.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 + + - 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.attributes.type == "ALL" + - 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..8da20a7ca --- /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: Create firmware policy exists + aci_firmware_policy: &aci_firmware_policy_present + <<: *aci_info + name: anstest_policy + version: n9000-15.2(7) + state: present + + - name: Create first firmware group + 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..ec0bb88ae --- /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) + ignore_compat: 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_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..5e039380e --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_fc/tasks/main.yml @@ -0,0 +1,160 @@ +# 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 + 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 + 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" + - 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: + <<: *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" + - 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: + <<: *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..f52b74fdb --- /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 l2 interface 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 == [] 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..7255c14ad --- /dev/null +++ b/tests/integration/targets/aci_interface_policy_mcp/tasks/main.yml @@ -0,0 +1,255 @@ +# 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 - 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 + name: anstest_policy + 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 + <<: *aci_info + name: anstest_policy_2 + state: absent + + - 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) - 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 - 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 + <<: *aci_interface_policy_mcp_2_absent + state: present + register: nm_add_interface_policy_mcp_2 + + - 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 + - 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 + 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" + + - 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_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: + 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' + + - 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 (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) - 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 - 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: + <<: *aci_interface_policy_mcp_2_present + state: absent + register: nm_delete_interface_policy_mcp_2 + + - 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 + - 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 == [] + 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 == [] 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 == [] 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 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..12284c8a6 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_group/tasks/main.yml @@ -0,0 +1,175 @@ +# 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 Scheduler + aci_fabric_scheduler: &aci_fabric_scheduler_present + <<: *aci_info + name: anstest_scheduler + state: present + + - 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 group does not exist + aci_maintenance_group: &aci_maintenance_group_absent + <<: *aci_info + group: anstest_group + policy: anstest_policy + firmware_nodes_type: controller + type_group: all + description: test for maintenance group + 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.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 + 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" + - 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: + <<: *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..9be9ecbe8 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_group_node/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: Create Scheduler + aci_fabric_scheduler: &aci_fabric_scheduler_present + <<: *aci_info + name: anstest_scheduler + state: present + + - name: Create maintenance policy + aci_maintenance_policy: &aci_maintenance_policy_present + <<: *aci_info + name: anstest_policy + scheduler: anstest_scheduler + state: present + + - name: Create maintenance groupe + 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 + - 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 + 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_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: + <<: *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..8628c2a84 --- /dev/null +++ b/tests/integration/targets/aci_maintenance_policy/tasks/main.yml @@ -0,0 +1,184 @@ +# 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 Scheduler + 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 + description: test for maintenance policy + run_mode: pause_never + graceful: True + scheduler: anstest_scheduler + ignore_compat: true + admin_state: untriggered + download_state: untriggered + notify_condition: notify_always_between_sets + smu_operation: smu_install + smu_operation_flags: smu_reload_skip + 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.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" + - 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.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" + + - 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.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" + - 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 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