From 6861a8751c465aeb9c8c7bae57a113923734882c Mon Sep 17 00:00:00 2001 From: akinross Date: Tue, 22 Nov 2022 15:30:09 +0100 Subject: [PATCH 1/3] [minor_change] source span sources support --- .../modules/aci_tenant_span_src_group_src.py | 322 ++++++++++++++++++ .../targets/aci_tenant_span_src_group/aliases | 2 + .../aci_tenant_span_src_group/tasks/main.yml | 171 ++++++++++ .../aci_tenant_span_src_group_src/aliases | 2 + .../tasks/main.yml | 191 +++++++++++ .../aliases | 2 + .../tasks/main.yml | 189 ++++++++++ 7 files changed, 879 insertions(+) create mode 100644 plugins/modules/aci_tenant_span_src_group_src.py create mode 100644 tests/integration/targets/aci_tenant_span_src_group/aliases create mode 100644 tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml create mode 100644 tests/integration/targets/aci_tenant_span_src_group_src/aliases create mode 100644 tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml create mode 100644 tests/integration/targets/aci_tenant_span_src_group_to_dst_group/aliases create mode 100644 tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml diff --git a/plugins/modules/aci_tenant_span_src_group_src.py b/plugins/modules/aci_tenant_span_src_group_src.py new file mode 100644 index 000000000..59f99478b --- /dev/null +++ b/plugins/modules/aci_tenant_span_src_group_src.py @@ -0,0 +1,322 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright: (c) 2022, Akini Ross (@akinross) + +# 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": "certified"} + +DOCUMENTATION = r""" +--- +module: aci_tenant_span_src_group_src +short_description: Manage SPAN source group sources (span:Src) +description: +- Manage SPAN source group sources on Cisco ACI fabrics. +options: + name: + description: + - The name of the Span source. + type: str + description: + description: + - The description for Span source. + type: str + aliases: [ descr ] + src_group: + description: + - The name of the Span source group. + type: str + aliases: [ name ] + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + direction: + description: + - The direction of the SPAN source. + type: str + choices: [ incoming, outgoing, both ] + src_epg: + description: + - The name of the Span source epg. + type: str + aliases: [ epg ] + src_ap: + description: + - The name of the Span source ap. + type: str + aliases: [ ap ] + state: + description: + - 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 + +extends_documentation_fragment: +- cisco.aci.aci +- cisco.aci.annotation +- cisco.aci.owner + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(span:SrcGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Akini Ross (@akinross) +""" + +EXAMPLES = r""" +- name: Create a SPAN source + cisco.aci.aci_tenant_span_src_group_src: + host: apic + username: admin + password: SomeSecretPassword + src_group: my_span_source_group + tenant: prod + name: test + direction: incoming + src_epg: epg1 + state: present + delegate_to: localhost + +- name: Delete a SPAN source + cisco.aci.aci_tenant_span_src_group_src: + host: apic + username: admin + password: SomeSecretPassword + src_group: my_span_source_group + tenant: prod + name: test + state: absent + delegate_to: localhost + +- name: Query all SPAN sources + cisco.aci.aci_tenant_span_src_group_src: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific SPAN source + cisco.aci.aci_tenant_span_src_group_src: + host: apic + username: admin + password: SomeSecretPassword + src_group: my_span_source_group + tenant: prod + name: test + state: query + delegate_to: localhost + register: query_result +""" + +RETURN = r""" +current: + description: The existing configuration from the APIC after the module has finished + returned: success + type: list + sample: + [ + { + "fvTenant": { + "attributes": { + "descr": "Production environment", + "dn": "uni/tn-production", + "name": "production", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "" + } + } + } + ] +error: + description: The error information as returned from the APIC + returned: failure + type: dict + sample: + { + "code": "122", + "text": "unknown managed object class foo" + } +raw: + description: The raw output returned by the APIC REST API (xml or json) + returned: parse error + type: str + sample: '' +sent: + description: The actual/minimal configuration pushed to the APIC + returned: info + type: list + sample: + { + "fvTenant": { + "attributes": { + "descr": "Production environment" + } + } + } +previous: + description: The original configuration from the APIC before the module has started + returned: info + type: list + sample: + [ + { + "fvTenant": { + "attributes": { + "descr": "Production", + "dn": "uni/tn-production", + "name": "production", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "" + } + } + } + ] +proposed: + description: The assembled configuration from the user-provided parameters + returned: info + type: dict + sample: + { + "fvTenant": { + "attributes": { + "descr": "Production environment", + "name": "production" + } + } + } +filter_string: + description: The filter string used for the request + returned: failure or debug + type: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + sample: OK (30 bytes) +status: + description: The HTTP status from the APIC + returned: failure or debug + type: int + sample: 200 +url: + description: The HTTP url used for the request to the APIC + returned: failure or debug + type: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +""" + +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 + +DIRECTION_MAP = { + "incoming": "in", "outgoing": "out", "both": "both" +} + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update(aci_annotation_spec()) + argument_spec.update(aci_owner_spec()) + argument_spec.update( + description=dict(type="str", aliases=["descr"]), + direction=dict(type="str", choices=["incoming", "outgoing", "both"]), + name=dict(type="str"), # Not required for querying all objects + src_ap=dict(type="str", aliases=["ap"]), + src_epg=dict(type="str", aliases=["epg"]), + src_group=dict(type="str"), # Not required for querying all objects + state=dict(type="str", default="present", choices=["absent", "present", "query"]), + tenant=dict(type="str", aliases=["tenant_name"]), # Not required for querying all objects + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ["state", "absent", ["name", "src_group", "tenant"]], + ["state", "present", ["name", "direction", "src_group", "tenant"]], + ], + required_together=[('src_ap', 'src_epg')], + ) + + aci = ACIModule(module) + + description = module.params.get("description") + direction = module.params.get("direction") + name = module.params.get("name") + src_ap = module.params.get("src_ap") + src_epg = module.params.get("src_epg") + src_group = module.params.get("src_group") + state = module.params.get("state") + tenant = module.params.get("tenant") + + aci.construct_url( + root_class=dict( + aci_class="fvTenant", + aci_rn="tn-{0}".format(tenant), + module_object=tenant, + target_filter={"name": tenant}, + ), + subclass_1=dict( + aci_class="spanSrcGrp", + aci_rn="srcgrp-{0}".format(src_group), + module_object=src_group, + target_filter={"name": src_group}, + ), + subclass_2=dict( + aci_class="spanSrc", + aci_rn="src-{0}".format(name), + module_object=name, + target_filter={"name": name}, + ), + child_classes=["spanRsSrcToEpg"], + ) + + aci.get_existing() + + if state == "present": + + tdn = None + if src_epg: + tdn = "uni/tn-{0}/ap-{1}/epg-{2}".format(tenant, src_ap, src_epg) + + aci.payload( + aci_class="spanSrc", + class_config=dict(descr=description, name=name, dir=DIRECTION_MAP.get(direction)), + child_configs=[{"spanRsSrcToEpg": {"attributes": {"tDn": tdn}}}] + ) + + aci.get_diff(aci_class="spanSrc") + + aci.post_config() + + elif state == "absent": + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/aci_tenant_span_src_group/aliases b/tests/integration/targets/aci_tenant_span_src_group/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_tenant_span_src_group/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml new file mode 100644 index 000000000..0be7d4b1f --- /dev/null +++ b/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml @@ -0,0 +1,171 @@ +# Test code for the ACI modules +# Copyright: (c) 2022, Akini Ross (@akinross) + +# 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: '{{ aci_output_level | default("info") }}' + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + tenant: ansible_tenant + state: absent + +- name: Add a new tenant + cisco.aci.aci_tenant: &aci_tenant + <<: *aci_info + tenant: ansible_tenant + state: present + +- name: Add new bd + cisco.aci.aci_bd: &aci_bd + <<: *aci_tenant + bd: anstest + register: bd_present + +- name: Add a new source ap + cisco.aci.aci_ap: + <<: *aci_tenant + ap: ansible_source_ap + +- name: Add a new dest ap + cisco.aci.aci_ap: + <<: *aci_tenant + ap: ansible_dest_ap + +- name: Add a new dest epg + cisco.aci.aci_epg: + <<: *aci_bd + ap: ansible_dest_ap + epg: ansible_dest_epg + +- name: Add a new source epg + cisco.aci.aci_epg: + <<: *aci_bd + ap: ansible_dest_ap + epg: ansible_source_epg + +- name: Add span dest group + cisco.aci.aci_tenant_span_dst_group: + <<: *aci_info + destination_group: ansible_dest_group + destination_ip: 10.0.0.1 + source_ip: 10.0.2.1 + tenant: ansible_tenant + ttl: 2 + mtu: 1500 + flow_id: 1 + dscp: "CS1" + destination_epg: + tenant: ansible_tenant + ap: ansible_dest_ap + epg: ansible_dest_epg + state: present + +- name: Create a source group (check mode) + cisco.aci.aci_tenant_span_src_group: &aci_span + <<: *aci_tenant + name: ansible_span + description: ansible test description + dst_group: ansible_dest_group + check_mode: yes + register: cm_create_with_dest + +- name: Create a source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_span + register: nm_create_with_dest + +- name: Create a source group again + cisco.aci.aci_tenant_span_src_group: + <<: *aci_span + register: nm_create_with_dest_again + +- name: Create second source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_tenant + name: ansible_span_2 + description: ansible test description + register: create_without_dest + +- name: Change second source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_tenant + name: ansible_span_2 + description: ansible test description 2 + register: change_without_dest + +- name: Verify create + ansible.builtin.assert: + that: + - cm_create_with_dest is changed + - nm_create_with_dest is changed + - nm_create_with_dest.current.0.spanSrcGrp.attributes.name == "ansible_span" + - nm_create_with_dest.current.0.spanSrcGrp.attributes.descr == "ansible test description" + - nm_create_with_dest.current.0.spanSrcGrp.children.0.spanSpanLbl.attributes.name == "ansible_dest_group" + - nm_create_with_dest_again is not changed + - nm_create_with_dest_again.current.0.spanSrcGrp.attributes.name == "ansible_span" + - nm_create_with_dest_again.current.0.spanSrcGrp.attributes.descr == "ansible test description" + - nm_create_with_dest_again.current.0.spanSrcGrp.children.0.spanSpanLbl.attributes.name == "ansible_dest_group" + - create_without_dest is changed + - create_without_dest.current.0.spanSrcGrp.attributes.name == "ansible_span_2" + - create_without_dest.current.0.spanSrcGrp.attributes.descr == "ansible test description" + - '"children" not in create_without_dest.current.0.spanSrcGrp' + - change_without_dest is changed + - change_without_dest.current.0.spanSrcGrp.attributes.name == "ansible_span_2" + - change_without_dest.current.0.spanSrcGrp.attributes.descr == "ansible test description 2" + - '"children" not in change_without_dest.current.0.spanSrcGrp' + +- name: Query a source groups + cisco.aci.aci_tenant_span_src_group: + <<: *aci_span + state: query + register: query_one + +- name: Query all source groups + cisco.aci.aci_tenant_span_src_group: + <<: *aci_info + state: query + register: query_all + +- name: Verify query + ansible.builtin.assert: + that: + - query_one is not changed + - query_one.current.0.spanSrcGrp.attributes.name == "ansible_span" + - query_one.current.0.spanSrcGrp.attributes.descr == "ansible test description" + - query_one.current.0.spanSrcGrp.children.0.spanSpanLbl.attributes.name == "ansible_dest_group" + - query_all is not changed + - query_all.current | length == 2 + +- name: Delete a source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_span + state: absent + register: delete + +- name: Verify delete + ansible.builtin.assert: + that: + - delete is changed + - delete.current == [] + +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_tenant + state: absent \ No newline at end of file diff --git a/tests/integration/targets/aci_tenant_span_src_group_src/aliases b/tests/integration/targets/aci_tenant_span_src_group_src/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_tenant_span_src_group_src/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml new file mode 100644 index 000000000..9dbce9c86 --- /dev/null +++ b/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml @@ -0,0 +1,191 @@ +# Test code for the ACI modules +# Copyright: (c) 2022, Akini Ross (@akinross) + +# 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: '{{ aci_output_level | default("info") }}' + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + tenant: ansible_tenant + state: absent + +- name: Add a new tenant + cisco.aci.aci_tenant: &aci_tenant + <<: *aci_info + tenant: ansible_tenant + state: present + +- name: Add new bd + cisco.aci.aci_bd: &aci_bd + <<: *aci_tenant + bd: anstest + register: bd_present + +- name: Add a new source ap + cisco.aci.aci_ap: + <<: *aci_tenant + ap: ansible_source_ap + +- name: Add a new dest ap + cisco.aci.aci_ap: + <<: *aci_tenant + ap: ansible_dest_ap + +- name: Add a new dest epg + cisco.aci.aci_epg: + <<: *aci_bd + ap: ansible_dest_ap + epg: ansible_dest_epg + +- name: Add a new source epg + cisco.aci.aci_epg: + <<: *aci_bd + ap: ansible_dest_ap + epg: ansible_source_epg + +- name: Add span dest group + cisco.aci.aci_tenant_span_dst_group: + <<: *aci_info + destination_group: ansible_dest_group + destination_ip: 10.0.0.1 + source_ip: 10.0.2.1 + tenant: ansible_tenant + ttl: 2 + mtu: 1500 + flow_id: 1 + dscp: "CS1" + destination_epg: + tenant: ansible_tenant + ap: ansible_dest_ap + epg: ansible_dest_epg + state: present + +- name: Create a source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_tenant + name: ansible_span + description: ansible test description + dst_group: ansible_dest_group + register: nm_create_with_dest + +- name: Create a source (check mode) + cisco.aci.aci_tenant_span_src_group_src: &aci_src + <<: *aci_tenant + name: ansible_source + description: ansible test description + direction: incoming + src_ap: ansible_source_ap + src_epg: ansible_source_epg + src_group: ansible_span + check_mode: yes + register: cm_create_with_epg + +- name: Create a source + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_src + register: nm_create_with_epg + +- name: Create a source again + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_src + register: nm_create_with_epg_again + +- name: Create second source + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_tenant + name: ansible_source_2 + description: ansible test description 2 + direction: outgoing + src_group: ansible_span + register: create_without_epg_direction_outgoing + +- name: Change second source + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_tenant + name: ansible_source_2 + description: ansible test description 3 + direction: both + src_group: ansible_span + register: change_without_epg_direction_both + +- name: Verify create + ansible.builtin.assert: + that: + - cm_create_with_epg is changed + - nm_create_with_epg is changed + - nm_create_with_epg.current.0.spanSrc.attributes.name == "ansible_source" + - nm_create_with_epg.current.0.spanSrc.attributes.descr == "ansible test description" + - nm_create_with_epg.current.0.spanSrc.attributes.dir == "in" + - nm_create_with_epg.current.0.spanSrc.children.0.spanRsSrcToEpg.attributes.tDn == "uni/tn-ansible_tenant/ap-ansible_source_ap/epg-ansible_source_epg" + - nm_create_with_epg_again is not changed + - nm_create_with_epg_again.current.0.spanSrc.attributes.name == "ansible_source" + - nm_create_with_epg_again.current.0.spanSrc.attributes.descr == "ansible test description" + - nm_create_with_epg_again.current.0.spanSrc.attributes.dir == "in" + - nm_create_with_epg_again.current.0.spanSrc.children.0.spanRsSrcToEpg.attributes.tDn == "uni/tn-ansible_tenant/ap-ansible_source_ap/epg-ansible_source_epg" + - create_without_epg_direction_outgoing is changed + - create_without_epg_direction_outgoing.current.0.spanSrc.attributes.name == "ansible_source_2" + - create_without_epg_direction_outgoing.current.0.spanSrc.attributes.descr == "ansible test description 2" + - create_without_epg_direction_outgoing.current.0.spanSrc.attributes.dir == "out" + - '"children" not in create_without_epg_direction_outgoing.current.0.spanSrc' + - change_without_epg_direction_both is changed + - change_without_epg_direction_both.current.0.spanSrc.attributes.name == "ansible_source_2" + - change_without_epg_direction_both.current.0.spanSrc.attributes.descr == "ansible test description 3" + - change_without_epg_direction_both.current.0.spanSrc.attributes.dir == "both" + - '"children" not in change_without_epg_direction_both.current.0.spanSrc' + +- name: Query a source + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_src + state: query + register: query_one + +- name: Query all sources + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_info + state: query + register: query_all + +- name: Verify query + ansible.builtin.assert: + that: + - query_one is not changed + - query_one.current.0.spanSrc.attributes.name == "ansible_source" + - query_one.current.0.spanSrc.attributes.descr == "ansible test description" + - query_one.current.0.spanSrc.attributes.dir == "in" + - query_one.current.0.spanSrc.children.0.spanRsSrcToEpg.attributes.tDn == "uni/tn-ansible_tenant/ap-ansible_source_ap/epg-ansible_source_epg" + - query_all is not changed + - query_all.current | length == 2 + +- name: Delete a source + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_src + state: absent + register: delete + +- name: Verify delete + ansible.builtin.assert: + that: + - delete is changed + - delete.current == [] + +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_tenant + state: absent \ No newline at end of file diff --git a/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/aliases b/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/aliases new file mode 100644 index 000000000..209b793f9 --- /dev/null +++ b/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/aliases @@ -0,0 +1,2 @@ +# No ACI simulator yet, so not enabled +# unsupported diff --git a/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml new file mode 100644 index 000000000..c45db90ef --- /dev/null +++ b/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml @@ -0,0 +1,189 @@ +# Test code for the ACI modules +# Copyright: (c) 2022, Akini Ross (@akinross) + +# 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: '{{ aci_output_level | default("info") }}' + +# CLEAN ENVIRONMENT +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_info + tenant: ansible_tenant + state: absent + +- name: Add a new tenant + cisco.aci.aci_tenant: &aci_tenant + <<: *aci_info + tenant: ansible_tenant + state: present + +- name: Add new bd + cisco.aci.aci_bd: &aci_bd + <<: *aci_tenant + bd: anstest + register: bd_present + +- name: Add a new source ap + cisco.aci.aci_ap: + <<: *aci_tenant + ap: ansible_source_ap + +- name: Add a new dest ap + cisco.aci.aci_ap: + <<: *aci_tenant + ap: ansible_dest_ap + +- name: Add a new dest epg + cisco.aci.aci_epg: + <<: *aci_bd + ap: ansible_dest_ap + epg: ansible_dest_epg + +- name: Add a new source epg + cisco.aci.aci_epg: + <<: *aci_bd + ap: ansible_dest_ap + epg: ansible_source_epg + +- name: Add span dest group + cisco.aci.aci_tenant_span_dst_group: + <<: *aci_info + destination_group: ansible_dest_group + destination_ip: 10.0.0.1 + source_ip: 10.0.2.1 + tenant: ansible_tenant + ttl: 2 + mtu: 1500 + flow_id: 1 + dscp: "CS1" + destination_epg: + tenant: ansible_tenant + ap: ansible_dest_ap + epg: ansible_dest_epg + state: present + +- name: Add span dest group + cisco.aci.aci_tenant_span_dst_group: + <<: *aci_info + destination_group: ansible_dest_group_2 + destination_ip: 20.0.0.1 + source_ip: 20.0.2.1 + tenant: ansible_tenant + ttl: 2 + mtu: 1500 + flow_id: 1 + dscp: "CS1" + destination_epg: + tenant: ansible_tenant + ap: ansible_dest_ap + epg: ansible_dest_epg + state: present + +- name: Create a source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_tenant + name: ansible_span + description: ansible test description + +- name: Create another source group + cisco.aci.aci_tenant_span_src_group: + <<: *aci_tenant + name: ansible_span_2 + description: ansible test description + +- name: Create a source group to destination (check mode) + cisco.aci.aci_tenant_span_src_group_to_dst_group: &aci_source_to_dest + <<: *aci_tenant + src_group: ansible_span + dst_group: ansible_dest_group + check_mode: yes + register: cm_create + +- name: Create a source group to destination + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_source_to_dest + register: nm_create + +- name: Create a source group to destination again + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_source_to_dest + register: nm_create_again + +- name: Create another source group to destination + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_tenant + src_group: ansible_span_2 + dst_group: ansible_dest_group_2 + register: nm_create_another + +- name: Change a source group to destination (error not allowed) + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_source_to_dest + dst_group: ansible_dest_group_2 + ignore_errors: yes + register: error_change + +- name: Verify create + ansible.builtin.assert: + that: + - cm_create is changed + - nm_create is changed + - nm_create.current.0.spanSpanLbl.attributes.name == "ansible_dest_group" + - nm_create_again is not changed + - nm_create_again.current.0.spanSpanLbl.attributes.name == "ansible_dest_group" + - nm_create_another is changed + - nm_create_another.current.0.spanSpanLbl.attributes.name == "ansible_dest_group_2" + - error_change is not changed + - 'error_change.msg == "APIC Error 105: Only one span destination is supported per session"' + +- name: Query a a source group to destination + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_source_to_dest + state: query + register: query_one + +- name: Query all a source group to destinations + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_info + state: query + register: query_all + +- name: Verify query + ansible.builtin.assert: + that: + - query_one is not changed + - query_one.current.0.spanSpanLbl.attributes.name == "ansible_dest_group" + - query_all is not changed + - query_all.current | length == 2 + +- name: Delete a source groups + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_source_to_dest + state: absent + register: delete + +- name: Verify delete + ansible.builtin.assert: + that: + - delete is changed + - delete.current == [] + +- name: Remove the ansible_tenant + cisco.aci.aci_tenant: + <<: *aci_tenant + state: absent \ No newline at end of file From b511e0a1c1f743da765b6d3829364c2aa7670dc2 Mon Sep 17 00:00:00 2001 From: akinross Date: Sat, 10 Dec 2022 11:00:36 +0100 Subject: [PATCH 2/3] [minor_change] doc update andmore specific naming for tests --- plugins/modules/aci_tenant_span_src_group_src.py | 2 -- .../aci_tenant_span_src_group/tasks/main.yml | 13 ++++++++++--- .../aci_tenant_span_src_group_src/tasks/main.yml | 13 ++++++++++--- .../tasks/main.yml | 15 +++++++++++---- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/plugins/modules/aci_tenant_span_src_group_src.py b/plugins/modules/aci_tenant_span_src_group_src.py index 59f99478b..3b3d56b93 100644 --- a/plugins/modules/aci_tenant_span_src_group_src.py +++ b/plugins/modules/aci_tenant_span_src_group_src.py @@ -115,8 +115,6 @@ host: apic username: admin password: SomeSecretPassword - src_group: my_span_source_group - tenant: prod name: test state: query delegate_to: localhost diff --git a/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml index 0be7d4b1f..1af587cd0 100644 --- a/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml +++ b/tests/integration/targets/aci_tenant_span_src_group/tasks/main.yml @@ -110,7 +110,7 @@ description: ansible test description 2 register: change_without_dest -- name: Verify create +- name: Verify create of source groups ansible.builtin.assert: that: - cm_create_with_dest is changed @@ -143,7 +143,7 @@ state: query register: query_all -- name: Verify query +- name: Verify queries to source groups ansible.builtin.assert: that: - query_one is not changed @@ -159,10 +159,17 @@ state: absent register: delete -- name: Verify delete +- name: Delete a source group again + cisco.aci.aci_tenant_span_src_group: + <<: *aci_span + state: absent + register: delete_again + +- name: Verify delete of source group ansible.builtin.assert: that: - delete is changed + - delete_again is not changed - delete.current == [] - name: Remove the ansible_tenant diff --git a/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml index 9dbce9c86..6b747f96f 100644 --- a/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml +++ b/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml @@ -125,7 +125,7 @@ src_group: ansible_span register: change_without_epg_direction_both -- name: Verify create +- name: Verify create and changes of sources ansible.builtin.assert: that: - cm_create_with_epg is changed @@ -162,7 +162,7 @@ state: query register: query_all -- name: Verify query +- name: Verify queries of sources ansible.builtin.assert: that: - query_one is not changed @@ -179,10 +179,17 @@ state: absent register: delete -- name: Verify delete +- name: Delete a source again + cisco.aci.aci_tenant_span_src_group_src: + <<: *aci_src + state: absent + register: delete_again + +- name: Verify delete of source ansible.builtin.assert: that: - delete is changed + - delete_again is not changed - delete.current == [] - name: Remove the ansible_tenant diff --git a/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml index c45db90ef..3390b86c1 100644 --- a/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml +++ b/tests/integration/targets/aci_tenant_span_src_group_to_dst_group/tasks/main.yml @@ -138,7 +138,7 @@ ignore_errors: yes register: error_change -- name: Verify create +- name: Verify create source groups to destination ansible.builtin.assert: that: - cm_create is changed @@ -163,7 +163,7 @@ state: query register: query_all -- name: Verify query +- name: Verify queries of source group to destination ansible.builtin.assert: that: - query_one is not changed @@ -171,16 +171,23 @@ - query_all is not changed - query_all.current | length == 2 -- name: Delete a source groups +- name: Delete a source group to destination cisco.aci.aci_tenant_span_src_group_to_dst_group: <<: *aci_source_to_dest state: absent register: delete -- name: Verify delete +- name: Delete a source group to destination again + cisco.aci.aci_tenant_span_src_group_to_dst_group: + <<: *aci_source_to_dest + state: absent + register: delete_again + +- name: Verify delete of source group to destinations ansible.builtin.assert: that: - delete is changed + - delete_again is not changed - delete.current == [] - name: Remove the ansible_tenant From d02ccd5251d1e2d8f3f840882e8234473b308065 Mon Sep 17 00:00:00 2001 From: akinross Date: Fri, 13 Jan 2023 16:37:39 +0100 Subject: [PATCH 3/3] [minor_change] documentation and task name more detailed --- .../modules/aci_tenant_span_src_group_src.py | 1 - .../tasks/main.yml | 22 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/plugins/modules/aci_tenant_span_src_group_src.py b/plugins/modules/aci_tenant_span_src_group_src.py index 3b3d56b93..ff490f08c 100644 --- a/plugins/modules/aci_tenant_span_src_group_src.py +++ b/plugins/modules/aci_tenant_span_src_group_src.py @@ -30,7 +30,6 @@ description: - The name of the Span source group. type: str - aliases: [ name ] tenant: description: - The name of the Tenant. diff --git a/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml b/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml index 6b747f96f..35268e814 100644 --- a/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml +++ b/tests/integration/targets/aci_tenant_span_src_group_src/tasks/main.yml @@ -85,7 +85,7 @@ dst_group: ansible_dest_group register: nm_create_with_dest -- name: Create a source (check mode) +- name: Create a ansible_source SPAN Source (check mode) cisco.aci.aci_tenant_span_src_group_src: &aci_src <<: *aci_tenant name: ansible_source @@ -97,17 +97,17 @@ check_mode: yes register: cm_create_with_epg -- name: Create a source +- name: Create a ansible_source SPAN Source cisco.aci.aci_tenant_span_src_group_src: <<: *aci_src register: nm_create_with_epg -- name: Create a source again +- name: Create a ansible_source SPAN Source again cisco.aci.aci_tenant_span_src_group_src: <<: *aci_src register: nm_create_with_epg_again -- name: Create second source +- name: Create second ansible_source SPAN Source cisco.aci.aci_tenant_span_src_group_src: <<: *aci_tenant name: ansible_source_2 @@ -116,7 +116,7 @@ src_group: ansible_span register: create_without_epg_direction_outgoing -- name: Change second source +- name: Change second ansible_source SPAN Source cisco.aci.aci_tenant_span_src_group_src: <<: *aci_tenant name: ansible_source_2 @@ -150,19 +150,19 @@ - change_without_epg_direction_both.current.0.spanSrc.attributes.dir == "both" - '"children" not in change_without_epg_direction_both.current.0.spanSrc' -- name: Query a source +- name: Query a ansible_source SPAN Source cisco.aci.aci_tenant_span_src_group_src: <<: *aci_src state: query register: query_one -- name: Query all sources +- name: Query all ansible_source SPAN Sources cisco.aci.aci_tenant_span_src_group_src: <<: *aci_info state: query register: query_all -- name: Verify queries of sources +- name: Verify queries of ansible_source SPAN Sources ansible.builtin.assert: that: - query_one is not changed @@ -173,19 +173,19 @@ - query_all is not changed - query_all.current | length == 2 -- name: Delete a source +- name: Delete a ansible_source SPAN Source cisco.aci.aci_tenant_span_src_group_src: <<: *aci_src state: absent register: delete -- name: Delete a source again +- name: Delete a ansible_source SPAN Source again cisco.aci.aci_tenant_span_src_group_src: <<: *aci_src state: absent register: delete_again -- name: Verify delete of source +- name: Verify delete of ansible_source SPAN Source ansible.builtin.assert: that: - delete is changed