From d7c3ddfe4b5881d9e1511144df51f65d80d14d1f Mon Sep 17 00:00:00 2001 From: samitab Date: Tue, 31 Oct 2023 12:30:21 +1000 Subject: [PATCH] [ignore] aci_rest add annotation to children and fix some tests --- plugins/modules/aci_rest.py | 11 +++- .../targets/aci_rest/tasks/json_inline.yml | 58 +++++++++++++++++- .../targets/aci_rest/tasks/json_string.yml | 60 ++++++++++++++++++- .../targets/aci_rest/tasks/xml_file.yml | 31 +++++++++- .../tn-ans_test_annotation_children.xml | 6 ++ .../targets/aci_rest/tasks/xml_string.yml | 38 ++++++++++-- .../targets/aci_rest/tasks/yaml_inline.yml | 38 ++++++++++++ .../targets/aci_rest/tasks/yaml_string.yml | 40 ++++++++++++- 8 files changed, 267 insertions(+), 15 deletions(-) create mode 100644 tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml diff --git a/plugins/modules/aci_rest.py b/plugins/modules/aci_rest.py index 2029330de..43986592a 100644 --- a/plugins/modules/aci_rest.py +++ b/plugins/modules/aci_rest.py @@ -312,13 +312,18 @@ def update_qsl(url, params): def add_annotation(annotation, payload): """Add annotation to payload only if it has not already been added""" - if annotation: + if annotation and isinstance(payload, dict): for key, val in payload.items(): if key in ANNOTATION_UNSUPPORTED: - return + continue att = val.get("attributes", {}) if "annotation" not in att.keys(): att["annotation"] = annotation + # Recursively add annotation to children + children = val.get("children", None) + if children: + for child in children: + add_annotation(annotation, child) def add_annotation_xml(annotation, tree): @@ -326,7 +331,7 @@ def add_annotation_xml(annotation, tree): if annotation: for element in tree.iter(): if element.tag in ANNOTATION_UNSUPPORTED: - return + continue ann = element.get("annotation") if ann is None: element.set("annotation", annotation) diff --git a/tests/integration/targets/aci_rest/tasks/json_inline.yml b/tests/integration/targets/aci_rest/tasks/json_inline.yml index 0260d588e..854950af6 100644 --- a/tests/integration/targets/aci_rest/tasks/json_inline.yml +++ b/tests/integration/targets/aci_rest/tasks/json_inline.yml @@ -275,10 +275,66 @@ } register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + 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") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test" + }, + "children": [ + { + "fvCtx": { + "attributes": { + "name": "VRF1" + } + } + }, + { + "fvAp": { + "attributes": { + "name": "Application1" + }, + "children": [ + { + "fvAEPg": { + "attributes": { + "name": "WebTier", + "annotation": "test:inchild" + } + } + } + ] + } + } + ] + } + } + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/json_string.yml b/tests/integration/targets/aci_rest/tasks/json_string.yml index 23e9900fe..2135c0219 100644 --- a/tests/integration/targets/aci_rest/tasks/json_string.yml +++ b/tests/integration/targets/aci_rest/tasks/json_string.yml @@ -263,7 +263,7 @@ use_ssl: '{{ aci_use_ssl | default(true) }}' use_proxy: '{{ aci_use_proxy | default(true) }}' output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-ansible_test_annotation1/tagKey-foo.json + path: /api/mo/uni/tn-ansible_test/tagKey-foo.json method: post annotation: test:inoption content: | @@ -276,10 +276,66 @@ } register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + 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") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test" + }, + "children": [ + { + "fvCtx": { + "attributes": { + "name": "VRF1" + } + } + }, + { + "fvAp": { + "attributes": { + "name": "Application1" + }, + "children": [ + { + "fvAEPg": { + "attributes": { + "name": "WebTier", + "annotation": "test:inchild" + } + } + } + ] + } + } + ] + } + } + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_file.yml b/tests/integration/targets/aci_rest/tasks/xml_file.yml index 52b67fc7c..0da42b009 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_file.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_file.yml @@ -17,7 +17,7 @@ output_path: "/tmp/ansible_output_file.log" - name: Ensure tenant does not exists using ans_test_delete xml template - cisco.aci.aci_rest: + cisco.aci.aci_rest: &tenant_delete <<: *aci_info path: /api/mo/uni.xml src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_delete.xml" @@ -260,6 +260,9 @@ src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml" register: nm_add_tenant_annotation_content +- name: Remove tenant + cisco.aci.aci_rest: *tenant_delete + - name: Add tenant with annotation in content and option cisco.aci.aci_rest: host: '{{ aci_hostname }}' @@ -290,10 +293,32 @@ src: "./targets/aci_rest/tasks/xml_files/tag.xml" register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_delete + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + 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") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml" + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.1.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml b/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml new file mode 100644 index 000000000..78be376be --- /dev/null +++ b/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_string.yml b/tests/integration/targets/aci_rest/tasks/xml_string.yml index d4a4304bc..34e43abb7 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_string.yml @@ -259,7 +259,7 @@ method: post annotation: test:inoption content: - + register: nm_add_tenant_annotation_option - name: Add tenant with annotation in content @@ -274,7 +274,7 @@ path: /api/mo/uni.xml method: post content: - + register: nm_add_tenant_annotation_content - name: Add tenant with annotation in content and option @@ -290,7 +290,7 @@ method: post annotation: test:inoption content: - + register: nm_add_tenant_annotation_option_content - name: Add tag to tenant with annotation unsupported @@ -302,17 +302,45 @@ use_ssl: '{{ aci_use_ssl | default(true) }}' use_proxy: '{{ aci_use_proxy | default(true) }}' output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-ansible_test/tagKey-foo.json + path: /api/mo/uni/tn-ansible_test/tagKey-foo.xml method: post annotation: test:inoption content: register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + 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") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + content: + + + + + + + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.1.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/yaml_inline.yml b/tests/integration/targets/aci_rest/tasks/yaml_inline.yml index 50549aa7c..8f4bbef04 100644 --- a/tests/integration/targets/aci_rest/tasks/yaml_inline.yml +++ b/tests/integration/targets/aci_rest/tasks/yaml_inline.yml @@ -251,6 +251,40 @@ value: bar register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + 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") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + children: + - fvCtx: + attributes: + name: VRF1 + - fvAp: + attributes: + name: Application1 + children: + - fvAEPg: + attributes: + name: WebTier + annotation: test:inchild + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: @@ -258,3 +292,7 @@ - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" diff --git a/tests/integration/targets/aci_rest/tasks/yaml_string.yml b/tests/integration/targets/aci_rest/tasks/yaml_string.yml index beb1fad54..f1b6c847b 100644 --- a/tests/integration/targets/aci_rest/tasks/yaml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/yaml_string.yml @@ -251,10 +251,48 @@ value: bar register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + 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") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + children: + - fvCtx: + attributes: + name: VRF1 + - fvAp: + attributes: + name: Application1 + children: + - fvAEPg: + attributes: + name: WebTier + annotation: test:inchild + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file