summaryrefslogtreecommitdiffstats
path: root/ansible_collections/cisco/mso
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
commit38b7c80217c4e72b1d8988eb1e60bb6e77334114 (patch)
tree356e9fd3762877d07cde52d21e77070aeff7e789 /ansible_collections/cisco/mso
parentAdding upstream version 7.7.0+dfsg. (diff)
downloadansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.tar.xz
ansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.zip
Adding upstream version 9.4.0+dfsg.upstream/9.4.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--ansible_collections/cisco/mso/.DS_Storebin6148 -> 6148 bytes
-rw-r--r--ansible_collections/cisco/mso/CHANGELOG.rst21
-rw-r--r--ansible_collections/cisco/mso/FILES.json111
-rw-r--r--ansible_collections/cisco/mso/MANIFEST.json4
-rw-r--r--ansible_collections/cisco/mso/changelogs/.plugin-cache.yaml19
-rw-r--r--ansible_collections/cisco/mso/changelogs/changelog.yaml608
-rw-r--r--ansible_collections/cisco/mso/changelogs/config.yaml32
-rw-r--r--ansible_collections/cisco/mso/meta/runtime.yml4
-rw-r--r--ansible_collections/cisco/mso/plugins/.DS_Storebin6148 -> 6148 bytes
-rw-r--r--ansible_collections/cisco/mso/plugins/doc_fragments/modules.py3
-rw-r--r--ansible_collections/cisco/mso/plugins/httpapi/mso.py117
-rw-r--r--ansible_collections/cisco/mso/plugins/module_utils/constants.py16
-rw-r--r--ansible_collections/cisco/mso/plugins/module_utils/mso.py117
-rw-r--r--ansible_collections/cisco/mso/plugins/module_utils/schema.py30
-rw-r--r--ansible_collections/cisco/mso/plugins/modules/mso_schema_site_anp_epg_useg_attribute.py276
-rw-r--r--ansible_collections/cisco/mso/plugins/modules/mso_schema_template_anp_epg_useg_attribute.py258
-rw-r--r--ansible_collections/cisco/mso/plugins/modules/mso_tenant_site.py8
-rw-r--r--ansible_collections/cisco/mso/tests/.DS_Storebin6148 -> 6148 bytes
-rw-r--r--ansible_collections/cisco/mso/tests/integration/inventory.networking2
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/aliases2
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/tasks/main.yml812
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/aliases2
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/tasks/main.yml743
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/tasks/main.yml23
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/connection.yml135
-rw-r--r--ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/main.yml9
26 files changed, 2914 insertions, 438 deletions
diff --git a/ansible_collections/cisco/mso/.DS_Store b/ansible_collections/cisco/mso/.DS_Store
index 9538dd02f..3406b7dd0 100644
--- a/ansible_collections/cisco/mso/.DS_Store
+++ b/ansible_collections/cisco/mso/.DS_Store
Binary files differ
diff --git a/ansible_collections/cisco/mso/CHANGELOG.rst b/ansible_collections/cisco/mso/CHANGELOG.rst
index b7b32a9e4..56fdfe5ee 100644
--- a/ansible_collections/cisco/mso/CHANGELOG.rst
+++ b/ansible_collections/cisco/mso/CHANGELOG.rst
@@ -6,6 +6,27 @@ Cisco MSO Ansible Collection Release Notes
This changelog describes changes after version 0.0.4.
+v2.5.0
+======
+
+Release Summary
+---------------
+
+Release v2.5.0 of the ``ansible-mso`` collection on 2023-08-04.
+This changelog describes all changes made to the modules and plugins included in this collection since v2.4.0.
+
+
+Minor Changes
+-------------
+
+- Add login domain attribute to mso httpapi connection plugin with restructure of connection parameter handling
+- Add mso_schema_template_anp_epg_useg_attribute and mso_schema_site_anp_epg_useg_attribute modules to manage EPG uSeg attributes (#370)
+
+Bugfixes
+--------
+
+- Fix mso_tenant_site "site not found" issue on absent (#368)
+
v2.4.0
======
diff --git a/ansible_collections/cisco/mso/FILES.json b/ansible_collections/cisco/mso/FILES.json
index 1d891e57b..b721a6242 100644
--- a/ansible_collections/cisco/mso/FILES.json
+++ b/ansible_collections/cisco/mso/FILES.json
@@ -18,7 +18,7 @@
"name": ".DS_Store",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f675a3307852ecd3abb2cce8e8f2f39c607937538cc9a55749ddaac6154a4d9a",
+ "chksum_sha256": "08aa120beef9259c40f0dd617a3ac8f759ef7760f9a34ad58d3ceb310a889081",
"format": 1
},
{
@@ -46,7 +46,7 @@
"name": "plugins/.DS_Store",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2cac03b3d027d06cc80e205126f9229303c5947e78f05fe29be390740df07f88",
+ "chksum_sha256": "f1b715c1525a4cda95ca30d9f3f14ec2b2a8574d43f98f6e5316581eec425e23",
"format": 1
},
{
@@ -60,7 +60,7 @@
"name": "plugins/doc_fragments/modules.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "05e4cbb55e517d30ceb130dcc7c920b3ead10d31b3ae993d018c1364b7f17dfc",
+ "chksum_sha256": "3140cb147397aaedea624cc5263e724f09e1aed800c1a08c8d4279be90421390",
"format": 1
},
{
@@ -74,7 +74,7 @@
"name": "plugins/httpapi/mso.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e31f980274cce2fd620e627313d88c0b848e616956c747772f768c99a002e9b2",
+ "chksum_sha256": "ecb6f4f715e9c43053c68a28ceb9c446ed00e327c44fa9aeafee9a33adb33cf5",
"format": 1
},
{
@@ -88,21 +88,21 @@
"name": "plugins/module_utils/mso.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c6ee1a1c7fe26b4ebbf7d11442a429eee577cc59e6340b96e119dba10961bfdf",
+ "chksum_sha256": "365ed0c9e88643e9282f6ed37ecb70438c0a8a8bca6140c23d394c57e40cd8e9",
"format": 1
},
{
"name": "plugins/module_utils/constants.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9521675e783e3ec3ae79f42c20225a79fdfd295840ef38aca2f7579f401dec12",
+ "chksum_sha256": "2f1ef5582a8aadb1f63c9764a1569c37f35c4f3771362645e2c1d37893ad0b58",
"format": 1
},
{
"name": "plugins/module_utils/schema.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "faf68907d23381a03c29a50a12dd24243cfec96e3830b2bd477d445356b3d3dc",
+ "chksum_sha256": "666a8b807cc281fb6b20571e8181356150b540b310538dae977fb34c98b065f2",
"format": 1
},
{
@@ -120,6 +120,13 @@
"format": 1
},
{
+ "name": "plugins/modules/mso_schema_template_anp_epg_useg_attribute.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8ed6ceddad626de74e9a017e479c2a9668c8e460c705611958b0e810ea03654f",
+ "format": 1
+ },
+ {
"name": "plugins/modules/mso_schema_site_anp_epg_staticport.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -291,7 +298,7 @@
"name": "plugins/modules/mso_tenant_site.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8ab681658fcdc71ce3e0dee372959d3e3c816833cbc64f78e2ca64e406495876",
+ "chksum_sha256": "30b1ce3e3c94d3b6fb9c8de815b1b02eef9d2ef1b2add0d26057802a5d211f64",
"format": 1
},
{
@@ -337,6 +344,13 @@
"format": 1
},
{
+ "name": "plugins/modules/mso_schema_site_anp_epg_useg_attribute.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e6cd229643ea78515528641359ee0dea24bbff6a6a7f76fe23f81c9abc02c430",
+ "format": 1
+ },
+ {
"name": "plugins/modules/mso_schema_site_external_epg.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -585,7 +599,7 @@
"name": "tests/.DS_Store",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c43950b0d43cfc92663c93c4106c8265af0878a180281af56a27b402dbe04258",
+ "chksum_sha256": "8f5933085695f47c8025ecc90fa5c4e5a9b9fd9ba06dd98310e682d8efec8949",
"format": 1
},
{
@@ -1716,10 +1730,17 @@
"format": 1
},
{
+ "name": "tests/integration/targets/mso_version/tasks/connection.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "fb0137c81fc07de5b1f7c515869d58c29c6b1140cb3c396f2e7f5082d9779633",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/mso_version/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "82ab83bd4bea802e0816502ad436051701ebf7ad413979fafaf48a89a9f373a6",
+ "chksum_sha256": "e12f785897861f1ddb8774ca5decd418c4cfb07cea9d3f7d17b82e702c90c6e9",
"format": 1
},
{
@@ -2006,7 +2027,7 @@
"name": "tests/integration/targets/mso_tenant_site/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "62050f4750b7759d9ffe9fb05eb907652902632e60bab409dd5046ed295aa32e",
+ "chksum_sha256": "47f6b866deb362cc0f408b86ce5c35d130b2020d1a9c1b417619e72e5a53eaf7",
"format": 1
},
{
@@ -2185,6 +2206,34 @@
"format": 1
},
{
+ "name": "tests/integration/targets/mso_schema_site_anp_epg_useg_attribute",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "37ede5ad61f45ac3ade6efa497636f6a60d3c53c84a018acd8381455d8bb62f0",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4e674607496d01ce032bfdbcc3e77ecdcde02f3e9d57080a95682a0cdff6809a",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/mso_schema_template_anp_epg_contract",
"ftype": "dir",
"chksum_type": null,
@@ -2367,6 +2416,34 @@
"format": 1
},
{
+ "name": "tests/integration/targets/mso_schema_template_anp_epg_useg_attribute",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "366babbe8a312685256b3034cb45e56c0bb3fb31347df60f368dd8d704b5ef16",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4e674607496d01ce032bfdbcc3e77ecdcde02f3e9d57080a95682a0cdff6809a",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/mso_service_node_type",
"ftype": "dir",
"chksum_type": null,
@@ -2440,7 +2517,7 @@
"name": "tests/integration/inventory.networking",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8279ccd9d9f069814c4799fe859517982de7fdef62f6844c86ce3d43f1eb75b1",
+ "chksum_sha256": "d3f3ffdd2f2ba13a4c77372a057605170c0480c7766a1b7ee626cdac9a11bbd5",
"format": 1
},
{
@@ -2475,7 +2552,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d6216481ba4478b00a1c7dd50630465ebdfeb69257a3203cb1bd78243b57e5e2",
+ "chksum_sha256": "205a2ae640e2768827a4bf733001d5294da4301f3413b1aac640fbb2a6155d03",
"format": 1
},
{
@@ -2496,7 +2573,7 @@
"name": "changelogs/config.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "43206e71b00b28f61464ff729ee7c096a6babe481924585846dc0ad75f4e5ae0",
+ "chksum_sha256": "61124366fa12fadf669a0d8d879c82d51db6214fca56c454593190f0433780d9",
"format": 1
},
{
@@ -2510,14 +2587,14 @@
"name": "changelogs/.plugin-cache.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "63e4189122f605bc252cee64b0e2a606ba71624e4efeef2f0b345aba2b137d52",
+ "chksum_sha256": "0e39bdaa5b1012ce06db1c6e59c9c3a09bb9ea6956647d966c93d2792de5819a",
"format": 1
},
{
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "add2fb84a8fccaa2a670024fd29718afab7e6001ffebbbbf5e8a5fd48b50c3e7",
+ "chksum_sha256": "aaefd32a4575f9258e66e377433698ba78c07d641a54c47092e1064edd676036",
"format": 1
},
{
@@ -2615,7 +2692,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e6387ce16814cecfb727532d8d1f0231849b4b1ccc11875af32502499af84ef8",
+ "chksum_sha256": "e4747ba584163f6422760b76eed3d11156df1c5ccf6ca6d18417140bcc214c16",
"format": 1
},
{
diff --git a/ansible_collections/cisco/mso/MANIFEST.json b/ansible_collections/cisco/mso/MANIFEST.json
index c795dd895..72c5f44d9 100644
--- a/ansible_collections/cisco/mso/MANIFEST.json
+++ b/ansible_collections/cisco/mso/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "cisco",
"name": "mso",
- "version": "2.4.0",
+ "version": "2.5.0",
"authors": [
"Dag Wieers (@dagwieers)",
"Nirav Katarmal (@nkatarmal-crest)",
@@ -36,7 +36,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "876c6bead4e943a7f2ed1b6bcc6db722a3024362587618ffccf5e7c7ec54419b",
+ "chksum_sha256": "52400ead13bbe6a4f9a3ae26b7702c3406c1463f794330adcc7bfa8aba2fca77",
"format": 1
},
"format": 1
diff --git a/ansible_collections/cisco/mso/changelogs/.plugin-cache.yaml b/ansible_collections/cisco/mso/changelogs/.plugin-cache.yaml
index c1fce4465..48e4fe51b 100644
--- a/ansible_collections/cisco/mso/changelogs/.plugin-cache.yaml
+++ b/ansible_collections/cisco/mso/changelogs/.plugin-cache.yaml
@@ -6,6 +6,7 @@ plugins:
callback: {}
cliconf: {}
connection: {}
+ filter: {}
httpapi:
mso:
description: MSO Ansible HTTPAPI Plugin.
@@ -90,6 +91,11 @@ plugins:
name: mso_schema_site_anp_epg
namespace: ''
version_added: null
+ mso_schema_site_anp_epg_bulk_staticport:
+ description: Manage site-local EPG static ports in bulk in schema template
+ name: mso_schema_site_anp_epg_bulk_staticport
+ namespace: ''
+ version_added: null
mso_schema_site_anp_epg_domain:
description: Manage site-local EPG domains in schema template
name: mso_schema_site_anp_epg_domain
@@ -115,6 +121,11 @@ plugins:
name: mso_schema_site_anp_epg_subnet
namespace: ''
version_added: null
+ mso_schema_site_anp_epg_useg_attribute:
+ description: Manage EPG Site uSeg Attributes in schema sites
+ name: mso_schema_site_anp_epg_useg_attribute
+ namespace: ''
+ version_added: null
mso_schema_site_bd:
description: Manage site-local Bridge Domains (BDs) in schema template
name: mso_schema_site_bd
@@ -205,6 +216,11 @@ plugins:
name: mso_schema_template_anp_epg_subnet
namespace: ''
version_added: null
+ mso_schema_template_anp_epg_useg_attribute:
+ description: Manage EPG uSeg Attributes in schema templates
+ name: mso_schema_template_anp_epg_useg_attribute
+ namespace: ''
+ version_added: null
mso_schema_template_bd:
description: Manage Bridge Domains (BDs) in schema templates
name: mso_schema_template_bd
@@ -339,5 +355,6 @@ plugins:
netconf: {}
shell: {}
strategy: {}
+ test: {}
vars: {}
-version: 2.2.0
+version: 2.5.0
diff --git a/ansible_collections/cisco/mso/changelogs/changelog.yaml b/ansible_collections/cisco/mso/changelogs/changelog.yaml
index 86e29d812..18ae8b912 100644
--- a/ansible_collections/cisco/mso/changelogs/changelog.yaml
+++ b/ansible_collections/cisco/mso/changelogs/changelog.yaml
@@ -3,325 +3,332 @@ releases:
0.0.5:
changes:
release_summary: New release v0.0.5
- release_date: '2020-04-07'
+ release_date: "2020-04-07"
0.0.6:
changes:
bugfixes:
- - Add aliases for backward support of permissions in role module.
- - Add integration test for mso_schema_template_db and fix un-needed push to
- API found by integration test.
- - Consistent object output on domain_associations
- - Fix EPG / External EPG Contract issue and create test for mso_schema_template_anp_epg_contract
- and mso_schema_template_external_epg_contract
- - Fix contract filter issue and add contract-filter test file
- - Fix duplicate user, add admin user to associated user list and update tenant
- test file
- - Fix intersite_multicast_source attribute issue in mso_schema_template_anp_epg
- and add the proxy_arp argument.
- - Fix mso_schema_template_anp_epg idempotancy for both EPG and EPG with contracts
- - Remove label with test domain before create it
- - Send context instead of vrf when vrf parameter is used
- - Update mso_schema_template_bd.py example for BD in another schema
+ - Add aliases for backward support of permissions in role module.
+ - Add integration test for mso_schema_template_db and fix un-needed push to
+ API found by integration test.
+ - Consistent object output on domain_associations
+ - Fix EPG / External EPG Contract issue and create test for mso_schema_template_anp_epg_contract
+ and mso_schema_template_external_epg_contract
+ - Fix contract filter issue and add contract-filter test file
+ - Fix duplicate user, add admin user to associated user list and update tenant
+ test file
+ - Fix intersite_multicast_source attribute issue in mso_schema_template_anp_epg
+ and add the proxy_arp argument.
+ - Fix mso_schema_template_anp_epg idempotancy for both EPG and EPG with contracts
+ - Remove label with test domain before create it
+ - Send context instead of vrf when vrf parameter is used
+ - Update mso_schema_template_bd.py example for BD in another schema
minor_changes:
- - ACI/MSO - Use get() dict lookups (https://github.com/ansible/ansible/pull/63074)
- - Add EPG and ANP at site level when needed
- - Add github action CI pipeline with test coverage
- - Add login domain support for authentication in all modules
- - Add support for DHCP querier to all subnet objects. Add partial test in mso_schema_template_bd
- integration test.
- - Add support for clean output if needed for debuging
- - Add test file for mso_schema_template_anp_epg
- - Added DHCP relay options and scope options to MSO schema template bd
- - Added ability to bind epg to static fex port
- - Added module to manage contracts for external EPG in Cisco MSO (https://github.com/ansible/ansible/pull/63550)
- - Added module to manage template external epg subnet for Cisco MSO (https://github.com/ansible/ansible/pull/63542)
- - Disabling tests for the role modules as API is not supported after 2.2.3i
- until further notice
- - Increased test coverage for existing module integration tests.
- - Modified fail messages for site and updated documentation
- - Moving test to Ansible v2.9.9 and increasing timelimit for mutex to 30+ min
- - Update authors.
- - Update mso_schema_site_anp.py (https://github.com/ansible/ansible/pull/67099)
- - Updated Test File Covering all conditions
- - mso_schema_site_anp_epg_staticport - Add VPC support (https://github.com/ansible/ansible/pull/62803)
+ - ACI/MSO - Use get() dict lookups (https://github.com/ansible/ansible/pull/63074)
+ - Add EPG and ANP at site level when needed
+ - Add github action CI pipeline with test coverage
+ - Add login domain support for authentication in all modules
+ - Add support for DHCP querier to all subnet objects. Add partial test in mso_schema_template_bd
+ integration test.
+ - Add support for clean output if needed for debuging
+ - Add test file for mso_schema_template_anp_epg
+ - Added DHCP relay options and scope options to MSO schema template bd
+ - Added ability to bind epg to static fex port
+ - Added module to manage contracts for external EPG in Cisco MSO (https://github.com/ansible/ansible/pull/63550)
+ - Added module to manage template external epg subnet for Cisco MSO (https://github.com/ansible/ansible/pull/63542)
+ - Disabling tests for the role modules as API is not supported after 2.2.3i
+ until further notice
+ - Increased test coverage for existing module integration tests.
+ - Modified fail messages for site and updated documentation
+ - Moving test to Ansible v2.9.9 and increasing timelimit for mutex to 30+ min
+ - Update authors.
+ - Update mso_schema_site_anp.py (https://github.com/ansible/ansible/pull/67099)
+ - Updated Test File Covering all conditions
+ - mso_schema_site_anp_epg_staticport - Add VPC support (https://github.com/ansible/ansible/pull/62803)
release_summary: New release v0.0.6
- release_date: '2020-06-13'
+ release_date: "2020-06-13"
0.0.7:
changes:
bugfixes:
- - Fix mso_schema_site_vrf_region_cidr to automatically create VRF and Region
- if not present at site level
- - Fix query condition when VRF or Region do not exist at site level
- - Remove unused regions attribute from mso_schema_template_vrf
+ - Fix mso_schema_site_vrf_region_cidr to automatically create VRF and Region
+ if not present at site level
+ - Fix query condition when VRF or Region do not exist at site level
+ - Remove unused regions attribute from mso_schema_template_vrf
minor_changes:
- - Add l3out, preferred_group and test file for mso_schema_template_externalepg
- - Add mso_schema_template_vrf_contract module and test file
- - Add new attribute choice "policy_compression" to mso_Schema_template_contract_filter
- - Add new functionality - Direct Port Channel (dpc), micro-seg-vlan and default
- values
- - Add new module for anp-epg-selector in site level
- - Add new module mso_schema_template_anp_epg_selector and its test file
- - Add new module mso_schema_vrf_contract
- - Add new module mso_tenant_site to support cloud and non-cloud sites association
- with a tenant and test file (https://github.com/CiscoDevNet/ansible-mso/pull/62)
- - Add new mso_site_external_epg_selector module and test file
- - Add site external epg and contract filter test
- - Add support for VGW attribute in mso_schema_site_vrf_region_cidr_subnet
- - Add support to set account as inactive using account_status attribute in mso_user
- - Add test for mso_schema_site_vrf_region_cidr module
- - Add test for mso_schema_site_vrf_region_cidr_subnet module
- - Add vzAny attribute in mso_schema_template_vrf
- - Automatically add ANP and EPG at site level and new test file for mso_schema_site_anp_epg_staticport
- (https://github.com/CiscoDevNet/ansible-mso/pull/55)
- - Modified External EPG module and addition of new Selector module
+ - Add l3out, preferred_group and test file for mso_schema_template_externalepg
+ - Add mso_schema_template_vrf_contract module and test file
+ - Add new attribute choice "policy_compression" to mso_Schema_template_contract_filter
+ - Add new functionality - Direct Port Channel (dpc), micro-seg-vlan and default
+ values
+ - Add new module for anp-epg-selector in site level
+ - Add new module mso_schema_template_anp_epg_selector and its test file
+ - Add new module mso_schema_vrf_contract
+ - Add new module mso_tenant_site to support cloud and non-cloud sites association
+ with a tenant and test file (https://github.com/CiscoDevNet/ansible-mso/pull/62)
+ - Add new mso_site_external_epg_selector module and test file
+ - Add site external epg and contract filter test
+ - Add support for VGW attribute in mso_schema_site_vrf_region_cidr_subnet
+ - Add support to set account as inactive using account_status attribute in mso_user
+ - Add test for mso_schema_site_vrf_region_cidr module
+ - Add test for mso_schema_site_vrf_region_cidr_subnet module
+ - Add vzAny attribute in mso_schema_template_vrf
+ - Automatically add ANP and EPG at site level and new test file for mso_schema_site_anp_epg_staticport
+ (https://github.com/CiscoDevNet/ansible-mso/pull/55)
+ - Modified External EPG module and addition of new Selector module
release_summary: New release v0.0.7
- release_date: '2020-07-08'
+ release_date: "2020-07-08"
0.0.8:
changes:
bugfixes:
- - Add login_domain to existing test.
- - Add missing tests for VRF settings and changing those settings.
- - Add test for specifying read-only roles and increase overall test coverage
- of mso_user (https://github.com/CiscoDevNet/ansible-mso/pull/77)
- - Add test to mso_schema_template_vrf, mso_schema_template_external_epg and
- mso_schema_template_anp_epg to check for API error when pushing changes to
- object with existing contract.
- - Cleanup unused imports, unused variables and branches and change a variable
- from ambiguous name to reduce warnings at Ansible Galaxy import
- - Fix API error when pushing EPG with existing contracts
- - Fix role tests to work with pre/post 2.2.4 and re-enable them
- - Fix site issue if no site present and fix test issues with MSO v3.0
- - Fixing External EPG renaming for 2.9 and later
- - Fixing L3MCast test to pass on 2.2.4
- - Fixing wrong removal of schemas
- - Test hub network module after creating region manually
- - Updating Azure site IP in inventory and add second MSO version to inventory
+ - Add login_domain to existing test.
+ - Add missing tests for VRF settings and changing those settings.
+ - Add test for specifying read-only roles and increase overall test coverage
+ of mso_user (https://github.com/CiscoDevNet/ansible-mso/pull/77)
+ - Add test to mso_schema_template_vrf, mso_schema_template_external_epg and
+ mso_schema_template_anp_epg to check for API error when pushing changes to
+ object with existing contract.
+ - Cleanup unused imports, unused variables and branches and change a variable
+ from ambiguous name to reduce warnings at Ansible Galaxy import
+ - Fix API error when pushing EPG with existing contracts
+ - Fix role tests to work with pre/post 2.2.4 and re-enable them
+ - Fix site issue if no site present and fix test issues with MSO v3.0
+ - Fixing External EPG renaming for 2.9 and later
+ - Fixing L3MCast test to pass on 2.2.4
+ - Fixing wrong removal of schemas
+ - Test hub network module after creating region manually
+ - Updating Azure site IP in inventory and add second MSO version to inventory
minor_changes:
- - Add Login Domain support to mso_site
- - Add aliases file for contract_filter module
- - Add contract information in current and previous part
- - Add new module and test file to query MSO version
- - New backup module and test file (https://github.com/CiscoDevNet/ansible-mso/pull/80)
- - Renaming mso_schema_template_externalepg module to mso_schema_template_external_epg
- while keeping both working.
- - Update cidr module, udpate attributes in hub network module and its test file
- - Use a function to reuuse duplicate part
+ - Add Login Domain support to mso_site
+ - Add aliases file for contract_filter module
+ - Add contract information in current and previous part
+ - Add new module and test file to query MSO version
+ - New backup module and test file (https://github.com/CiscoDevNet/ansible-mso/pull/80)
+ - Renaming mso_schema_template_externalepg module to mso_schema_template_external_epg
+ while keeping both working.
+ - Update cidr module, udpate attributes in hub network module and its test file
+ - Use a function to reuuse duplicate part
release_summary: New release v0.0.8
- release_date: '2020-07-21'
+ release_date: "2020-07-21"
1.0.0:
changes:
bugfixes:
- - Fix sanity issues to support 2.10.0
+ - Fix sanity issues to support 2.10.0
minor_changes:
- - Add changelog
- - Fix M() and module to use FQCN
- - Update Ansible version in CI and add 2.10.0 to sanity in CI.
- - Update Readme with supported versions
- release_summary: 'This is the first official release of the ``cisco.mso`` collection
+ - Add changelog
+ - Fix M() and module to use FQCN
+ - Update Ansible version in CI and add 2.10.0 to sanity in CI.
+ - Update Readme with supported versions
+ release_summary:
+ "This is the first official release of the ``cisco.mso`` collection
on 2020-08-18.
This changelog describes all changes made to the modules and plugins included
in this collection since Ansible 2.9.0.
- '
- release_date: '2020-08-18'
+ "
+ release_date: "2020-08-18"
1.0.1:
changes:
bugfixes:
- - Fix default value for l2Stretch in mso_schema_template_bd module
- - Fix deletion of schema when wrong template is provided in single template
- schema
- - Fix examples in documentation for mso_schema_template_l3out and mso_user
- - Fix naming issue in deploy module
- - Remove author emails due to length restriction
- - Remove dead code branch in mso_schema_template
+ - Fix default value for l2Stretch in mso_schema_template_bd module
+ - Fix deletion of schema when wrong template is provided in single template
+ schema
+ - Fix examples in documentation for mso_schema_template_l3out and mso_user
+ - Fix naming issue in deploy module
+ - Remove author emails due to length restriction
+ - Remove dead code branch in mso_schema_template
minor_changes:
- - Add delete capability to mso_schema_site
- - Add env_fallback for mso_argument_spec params
- - Add non existing template deletion test
- - Add test file for mso_schema_template
- - Add test file for site_bd_subnet
- - Bump module to v1.0.1
- - Extent mso_tenant test case coverage
- release_summary: 'Release v1.0.1 of the ``cisco.mso`` collection on 2020-10-30.
+ - Add delete capability to mso_schema_site
+ - Add env_fallback for mso_argument_spec params
+ - Add non existing template deletion test
+ - Add test file for mso_schema_template
+ - Add test file for site_bd_subnet
+ - Bump module to v1.0.1
+ - Extent mso_tenant test case coverage
+ release_summary:
+ "Release v1.0.1 of the ``cisco.mso`` collection on 2020-10-30.
This changelog describes all changes made to the modules and plugins included
in this collection since v1.0.0.
- '
- release_date: '2020-10-30'
+ "
+ release_date: "2020-10-30"
1.1.0:
changes:
bugfixes:
- - Fix anp idempotency issue
- - Fix crash issue when using irrelevant site-template
- - Fix default value for mso_schema state parameter
- - Fix examples for mso_schema
- - Fix galaxy-importer check warnings
- - Fix issue on mso_schema_site_vrf_region_cidr_subnet to allow an AWS subnet
- to be used for a TGW Attachment (Hub Network)
- - Fix module name in example of mso_schema_site_vrf_region
- - Fix mso_backup upload issue
- - Fix sanity test error mso_schema_site_bd
- - Fix some coding standard and improvements to contributed mso_dhcp_relay modules
- and test files
- - Fix space in asssertion
- - Fix space in site_anp_epg_domain
- - Fix space in test file
- - Remove space from template name in all modules
- - Remove space in template name
+ - Fix anp idempotency issue
+ - Fix crash issue when using irrelevant site-template
+ - Fix default value for mso_schema state parameter
+ - Fix examples for mso_schema
+ - Fix galaxy-importer check warnings
+ - Fix issue on mso_schema_site_vrf_region_cidr_subnet to allow an AWS subnet
+ to be used for a TGW Attachment (Hub Network)
+ - Fix module name in example of mso_schema_site_vrf_region
+ - Fix mso_backup upload issue
+ - Fix sanity test error mso_schema_site_bd
+ - Fix some coding standard and improvements to contributed mso_dhcp_relay modules
+ and test files
+ - Fix space in asssertion
+ - Fix space in site_anp_epg_domain
+ - Fix space in test file
+ - Remove space from template name in all modules
+ - Remove space in template name
minor_changes:
- - Add DHCP Policy Operations
- - Add SVI MAC Addreess option in mso_schema_site_bd
- - Add additional test file to add tenant from templated payload file
- - Add attribute virtual_ip to mso_schema_site_bd_subnet
- - Add capability for restore and download backup
- - Add capability to upload backup
- - Add check for undeploy under MSO version
- - Add error handeling test file
- - Add error message to display when yaml has failed to load
- - Add galaxy-importer check
- - Add galaxy-importer config
- - Add mso_dhcp_option_policy and mso_dhcp_option_policy_option and test files
- - Add new module mso_rest and test case files to support GET api method
- - Add new options to template bd and updated test file
- - Add notes to use region_cidr module to create region
- - Add task to undeploy the template from the site
- - Add tasks in test file to remove templates for mso_schema_template_migrate
- - Add test case for schema removing
- - Add test cases to verify GET, PUT, POST and DELETE API methods for sites in
- mso_rest.py
- - Add test file for mso_schema
- - Add test file for mso_schema_template_anp
- - Add test file for region module
- - Add test files yaml_inline and yaml_string to support YAML
- - Add userAssociations to tenants to resolve CI issues
- - Addition of cloud setting for ext epg
- - Changes made to payload of mso_schema_template_external_epg
- - Changes to options in template bd
- - Check warning
- - Documentation Corrected
- - Force arp flood to be true when l2unkwunicast is flood
- - Make changes to display correct status code
- - Modify mso library and updated test file
- - Modify mso_rest test files to make PATCH available, and test other methods
- against schemas
- - Move options for subnet from mso to the template_bd_subnet module
- - Python lint corrected
- - Redirect log to both stdout and log.txt file & Check warnings and errors
- - Remove creation example in document of mso_schema_site_vrf_region
- - Remove present state from mso_schema module
- - Removed unused variable in mso_schema_site_vrf_region_hub_network
- - Test DHCP Policy Provider added
- - Test file for mso_dhcp_relay_policy added
- - Test file for template_bd_subnet and new option foe module
- release_summary: 'Release v1.1.0 of the ``cisco.mso`` collection on 2021-01-20.
+ - Add DHCP Policy Operations
+ - Add SVI MAC Addreess option in mso_schema_site_bd
+ - Add additional test file to add tenant from templated payload file
+ - Add attribute virtual_ip to mso_schema_site_bd_subnet
+ - Add capability for restore and download backup
+ - Add capability to upload backup
+ - Add check for undeploy under MSO version
+ - Add error handeling test file
+ - Add error message to display when yaml has failed to load
+ - Add galaxy-importer check
+ - Add galaxy-importer config
+ - Add mso_dhcp_option_policy and mso_dhcp_option_policy_option and test files
+ - Add new module mso_rest and test case files to support GET api method
+ - Add new options to template bd and updated test file
+ - Add notes to use region_cidr module to create region
+ - Add task to undeploy the template from the site
+ - Add tasks in test file to remove templates for mso_schema_template_migrate
+ - Add test case for schema removing
+ - Add test cases to verify GET, PUT, POST and DELETE API methods for sites in
+ mso_rest.py
+ - Add test file for mso_schema
+ - Add test file for mso_schema_template_anp
+ - Add test file for region module
+ - Add test files yaml_inline and yaml_string to support YAML
+ - Add userAssociations to tenants to resolve CI issues
+ - Addition of cloud setting for ext epg
+ - Changes made to payload of mso_schema_template_external_epg
+ - Changes to options in template bd
+ - Check warning
+ - Documentation Corrected
+ - Force arp flood to be true when l2unkwunicast is flood
+ - Make changes to display correct status code
+ - Modify mso library and updated test file
+ - Modify mso_rest test files to make PATCH available, and test other methods
+ against schemas
+ - Move options for subnet from mso to the template_bd_subnet module
+ - Python lint corrected
+ - Redirect log to both stdout and log.txt file & Check warnings and errors
+ - Remove creation example in document of mso_schema_site_vrf_region
+ - Remove present state from mso_schema module
+ - Removed unused variable in mso_schema_site_vrf_region_hub_network
+ - Test DHCP Policy Provider added
+ - Test file for mso_dhcp_relay_policy added
+ - Test file for template_bd_subnet and new option foe module
+ release_summary:
+ "Release v1.1.0 of the ``cisco.mso`` collection on 2021-01-20.
This changelog describes all changes made to the modules and plugins included
in this collection since v1.0.1.
- '
- release_date: '2021-01-20'
+ "
+ release_date: "2021-01-20"
1.2.0:
changes:
bugfixes:
- - Add test case and small fixes to mso_schema_site_bd_l3out module
- - Fix documentation issues accross modules
- - Fix fail_json usage accross module_utils/mso.py
- - Fix mso_rest to support HTTPAPI plugin and tests to support ND platform
- - Fix mso_user to due to error in v1 API in MSO 3.2
- - Fix path issue in mso_schema_template_migrate
- - Fixes for site level external epgs and site level L3Outs
- - Fixes to support MSO 3.3
- - Remove query of all schemas to get schema ID and only query schema ID indentity
- list API
+ - Add test case and small fixes to mso_schema_site_bd_l3out module
+ - Fix documentation issues accross modules
+ - Fix fail_json usage accross module_utils/mso.py
+ - Fix mso_rest to support HTTPAPI plugin and tests to support ND platform
+ - Fix mso_user to due to error in v1 API in MSO 3.2
+ - Fix path issue in mso_schema_template_migrate
+ - Fixes for site level external epgs and site level L3Outs
+ - Fixes to support MSO 3.3
+ - Remove query of all schemas to get schema ID and only query schema ID indentity
+ list API
minor_changes:
- - Add Ansible common HTTPAPI dependancy in galaxy.yml
- - Add HTTPAPI connection plugin support and HTTPAPI MSO connection plugin
- - Add primary and unicast_routing attributes to mso_schema_template_bd
- - Add requirements.txt for Ansible Environment support
- - Add schema and template cloning modules mso_schema_clone and mso_schema_template_clone
- - Add support cisco.nd.nd connection plugin
- - Add support for multiple DCHP policies in a BD and new module mso_schema_template_bd_dhcp_policy
- - Upgrade CI to latest Ansible version and Python 3.8
- release_summary: 'Release v1.2.0 of the ``cisco.mso`` collection on 2021-06-02.
+ - Add Ansible common HTTPAPI dependancy in galaxy.yml
+ - Add HTTPAPI connection plugin support and HTTPAPI MSO connection plugin
+ - Add primary and unicast_routing attributes to mso_schema_template_bd
+ - Add requirements.txt for Ansible Environment support
+ - Add schema and template cloning modules mso_schema_clone and mso_schema_template_clone
+ - Add support cisco.nd.nd connection plugin
+ - Add support for multiple DCHP policies in a BD and new module mso_schema_template_bd_dhcp_policy
+ - Upgrade CI to latest Ansible version and Python 3.8
+ release_summary:
+ "Release v1.2.0 of the ``cisco.mso`` collection on 2021-06-02.
This changelog describes all changes made to the modules and plugins included
in this collection since v1.1.0.
- '
+ "
plugins:
httpapi:
- - description: MSO Ansible HTTPAPI Plugin.
- name: mso
- namespace: null
- release_date: '2021-06-02'
+ - description: MSO Ansible HTTPAPI Plugin.
+ name: mso
+ namespace: null
+ release_date: "2021-06-02"
1.3.0:
changes:
bugfixes:
- - Add no_log to aws_access_key and secret_key in mso_tenant_site
- - Fix MSO HTTP API to work without host, user and password module attribute
- - Fix issue with unicast_routing idemptotency in mso_schema_template_bd
- - Fix mso_schema_site_anp and mso_schema_site_anp_epg idempotency issue
- - Remove sanity ignore files and fix sanity issues that were previously ignored
+ - Add no_log to aws_access_key and secret_key in mso_tenant_site
+ - Fix MSO HTTP API to work without host, user and password module attribute
+ - Fix issue with unicast_routing idemptotency in mso_schema_template_bd
+ - Fix mso_schema_site_anp and mso_schema_site_anp_epg idempotency issue
+ - Remove sanity ignore files and fix sanity issues that were previously ignored
minor_changes:
- - Add container_overlay and underlay_context_profile support to mso_schema_site_vrf_region
- - Add description support to various modules
- - Add hosted_vrf support to mso_schema_site_vrf_region_cidr_subnet
- - Add module mso_schema_validate to check schema validations
- - Add private_link_label support to mso_schema_site_anp_epg and mso_schema_site_vrf_region_cidr_subnet
- - Add qos_level and Service EPG support to mso_schema_template_anp_epg
- - Add qos_level, action and priority support to mso_schema_template_contract_filter
- - Add schema and template description support to mso_schema_template
- - Add subnet as primary support to mso_schema_template_bd_subnet
- - Add support for automatically creating anp structure at site level when using
- mso_schema_site_anp_epg
- - Add support for encap-flood as multi_destination_flooding in mso_schema_template_bd
- - Add test file for mso_schema_site_anp, mso_schema_site_anp_epg, mso_schema_template_external_epg_subnet
- mso_schema_template_filter_entry
- - Improve scope attribute documentation in mso_schema_template_external_epg_subnet
- - Update Ansible version used in automated testing to v2.9.27, v2.10.16 and
- addition of v2.11.7 and v2.12.1
- release_summary: 'Release v1.3.0 of the ``cisco.mso`` collection on 2021-12-18.
+ - Add container_overlay and underlay_context_profile support to mso_schema_site_vrf_region
+ - Add description support to various modules
+ - Add hosted_vrf support to mso_schema_site_vrf_region_cidr_subnet
+ - Add module mso_schema_validate to check schema validations
+ - Add private_link_label support to mso_schema_site_anp_epg and mso_schema_site_vrf_region_cidr_subnet
+ - Add qos_level and Service EPG support to mso_schema_template_anp_epg
+ - Add qos_level, action and priority support to mso_schema_template_contract_filter
+ - Add schema and template description support to mso_schema_template
+ - Add subnet as primary support to mso_schema_template_bd_subnet
+ - Add support for automatically creating anp structure at site level when using
+ mso_schema_site_anp_epg
+ - Add support for encap-flood as multi_destination_flooding in mso_schema_template_bd
+ - Add test file for mso_schema_site_anp, mso_schema_site_anp_epg, mso_schema_template_external_epg_subnet
+ mso_schema_template_filter_entry
+ - Improve scope attribute documentation in mso_schema_template_external_epg_subnet
+ - Update Ansible version used in automated testing to v2.9.27, v2.10.16 and
+ addition of v2.11.7 and v2.12.1
+ release_summary:
+ "Release v1.3.0 of the ``cisco.mso`` collection on 2021-12-18.
This changelog describes all changes made to the modules and plugins included
in this collection since v1.2.0.
- '
- release_date: '2021-12-18'
+ "
+ release_date: "2021-12-18"
1.4.0:
changes:
bugfixes:
- - Fix arp_entry value issue in mso_schema_template_filter_entry
- - Fix mso_schema_site_anp idempotency when children exists
- - Fix use_ssl documentation to explain usage when used with HTTPAPI connection
- plugin
+ - Fix arp_entry value issue in mso_schema_template_filter_entry
+ - Fix mso_schema_site_anp idempotency when children exists
+ - Fix use_ssl documentation to explain usage when used with HTTPAPI connection
+ plugin
minor_changes:
- - Update mso_schema_template_clone to use new method from NDO and unrestrict
- it to earlier version
- release_summary: 'Release v1.4.0 of the ``ansible-mso`` collection on 2022-03-15.
+ - Update mso_schema_template_clone to use new method from NDO and unrestrict
+ it to earlier version
+ release_summary:
+ "Release v1.4.0 of the ``ansible-mso`` collection on 2022-03-15.
This changelog describes all changes made to the modules and plugins included
in this collection since v1.3.0.
- '
- release_date: '2022-03-15'
+ "
+ release_date: "2022-03-15"
2.1.0:
changes:
bugfixes:
- - Fix time issue when host running ansible is in a different timezone then NDO
- - Remove mso_guide from notes
+ - Fix time issue when host running ansible is in a different timezone then NDO
+ - Remove mso_guide from notes
deprecated_features:
- - The mso_schema_template_contract_filter contract_filter_type attribute is
- deprecated. The value is now deduced from filter_type.
+ - The mso_schema_template_contract_filter contract_filter_type attribute is
+ deprecated. The value is now deduced from filter_type.
minor_changes:
- - Add aci_remote_location module (#259)
- - Add mso_backup_schedule module (#250)
- - Add mso_chema_template_contract_service_graph module (#257)
- - Add mso_schema_template_service_graph, mso_schema_site_service_graph and mso_service_node_type
- modules (#243)
- - Add primary attribute to mso_schema_site_bd_subnet (#254)
- release_summary: 'Release v2.1.0 of the ``ansible-mso`` collection on 2022-10-14.
+ - Add aci_remote_location module (#259)
+ - Add mso_backup_schedule module (#250)
+ - Add mso_chema_template_contract_service_graph module (#257)
+ - Add mso_schema_template_service_graph, mso_schema_site_service_graph and mso_service_node_type
+ modules (#243)
+ - Add primary attribute to mso_schema_site_bd_subnet (#254)
+ release_summary:
+ "Release v2.1.0 of the ``ansible-mso`` collection on 2022-10-14.
This changelog describes all changes made to the modules and plugins included
in this collection since v1.4.0.
@@ -329,76 +336,97 @@ releases:
The version was bumped directly to 2.1.0 due to a previous collection upload
issue on galaxy.
- '
- release_date: '2022-10-14'
+ "
+ release_date: "2022-10-14"
2.2.0:
changes:
bugfixes:
- - Fix MSO HTTPAPI plugin login domain issue (#317)
- - Fix deploymentImmediacy key inconsistency in the API used by mso_schema_site_anp
- and mso_schema_site_anp_epg (#283)
- - Fix mso_schema_template_bd issue when created with unicast_routing as false
- (#278)
- - Fix to be able to add multiple filter and filters with "-" in their names
- (#306)
+ - Fix MSO HTTPAPI plugin login domain issue (#317)
+ - Fix deploymentImmediacy key inconsistency in the API used by mso_schema_site_anp
+ and mso_schema_site_anp_epg (#283)
+ - Fix mso_schema_template_bd issue when created with unicast_routing as false
+ (#278)
+ - Fix to be able to add multiple filter and filters with "-" in their names
+ (#306)
minor_changes:
- - Add automatic creation of site bd when not existing in mso_schema_site_bd_subnet
- module (#263)
- - Add automatic schema validation functionality to mso_schema_template_deploy
- and ndo_schema_template_deploy (#318)
- - Add ndo_schema_template_deploy to support NDO 4+ deploy functionality (#305)
- - Add support for l3out from different template or schema in mso_schema_site_bd_l3out
- (#304)
- - Add support for orchestrator_only attribute for mso_tenant with state absent
- (#268)
- release_summary: 'Release v2.2.0 of the ``ansible-mso`` collection on 2023-01-29.
+ - Add automatic creation of site bd when not existing in mso_schema_site_bd_subnet
+ module (#263)
+ - Add automatic schema validation functionality to mso_schema_template_deploy
+ and ndo_schema_template_deploy (#318)
+ - Add ndo_schema_template_deploy to support NDO 4+ deploy functionality (#305)
+ - Add support for l3out from different template or schema in mso_schema_site_bd_l3out
+ (#304)
+ - Add support for orchestrator_only attribute for mso_tenant with state absent
+ (#268)
+ release_summary:
+ "Release v2.2.0 of the ``ansible-mso`` collection on 2023-01-29.
This changelog describes all changes made to the modules and plugins included
in this collection since v2.1.0.
- '
- release_date: '2023-01-29'
+ "
+ release_date: "2023-01-29"
2.2.1:
changes:
bugfixes:
- - Fix datetime support for python2.7 in mso_backup_schedule (#323)
- release_summary: 'Release v2.2.1 of the ``ansible-mso`` collection on 2023-01-31.
+ - Fix datetime support for python2.7 in mso_backup_schedule (#323)
+ release_summary:
+ "Release v2.2.1 of the ``ansible-mso`` collection on 2023-01-31.
This changelog describes all changes made to the modules and plugins included
in this collection since v2.2.0.
- '
- release_date: '2023-01-31'
+ "
+ release_date: "2023-01-31"
2.3.0:
changes:
bugfixes:
- - Fix idempotency for mso_schema_site_bd_l3out
+ - Fix idempotency for mso_schema_site_bd_l3out
minor_changes:
- - Add module mso_schema_site_anp_epg_bulk_staticport (#330)
- - Add route_reachability attribute to mso_schema_site_external_epg module (#335)
- release_summary: 'Release v2.3.0 of the ``ansible-mso`` collection on 2023-03-30.
+ - Add module mso_schema_site_anp_epg_bulk_staticport (#330)
+ - Add route_reachability attribute to mso_schema_site_external_epg module (#335)
+ release_summary:
+ "Release v2.3.0 of the ``ansible-mso`` collection on 2023-03-30.
This changelog describes all changes made to the modules and plugins included
in this collection since v2.2.1.
- '
- release_date: '2023-03-30'
+ "
+ release_date: "2023-03-30"
2.4.0:
changes:
bugfixes:
- - Add attributes to payload for changed schema behaviour of deploymentImmediacy
- (deployImmediacy) and vmmDomainProperties (properties at domain level in payload)
- (#362)
- - Fix mso_backup for NDO and ND-based MSO v3.2+ (#333)
- - Fix validation condition for path in mso_schema_site_anp_epg_bulk_staticport
- module (#360)
+ - Add attributes to payload for changed schema behaviour of deploymentImmediacy
+ (deployImmediacy) and vmmDomainProperties (properties at domain level in payload)
+ (#362)
+ - Fix mso_backup for NDO and ND-based MSO v3.2+ (#333)
+ - Fix validation condition for path in mso_schema_site_anp_epg_bulk_staticport
+ module (#360)
minor_changes:
- - Add ip_data_plane_learning and preferred_group arguments to mso_schema_template_vrf
- module (#358)
- release_summary: 'Release v2.4.0 of the ``ansible-mso`` collection on 2023-04-19.
+ - Add ip_data_plane_learning and preferred_group arguments to mso_schema_template_vrf
+ module (#358)
+ release_summary:
+ "Release v2.4.0 of the ``ansible-mso`` collection on 2023-04-19.
This changelog describes all changes made to the modules and plugins included
in this collection since v2.3.0.
- '
- release_date: '2023-04-19'
+ "
+ release_date: "2023-04-19"
+ 2.5.0:
+ changes:
+ bugfixes:
+ - Fix mso_tenant_site "site not found" issue on absent (#368)
+ minor_changes:
+ - Add login domain attribute to mso httpapi connection plugin with restructure
+ of connection parameter handling
+ - Add mso_schema_template_anp_epg_useg_attribute and mso_schema_site_anp_epg_useg_attribute
+ modules to manage EPG uSeg attributes (#370)
+ release_summary:
+ "Release v2.5.0 of the ``ansible-mso`` collection on 2023-08-04.
+
+ This changelog describes all changes made to the modules and plugins included
+ in this collection since v2.4.0.
+
+ "
+ release_date: "2023-08-04"
diff --git a/ansible_collections/cisco/mso/changelogs/config.yaml b/ansible_collections/cisco/mso/changelogs/config.yaml
index d6a4c94a0..20cbac942 100644
--- a/ansible_collections/cisco/mso/changelogs/config.yaml
+++ b/ansible_collections/cisco/mso/changelogs/config.yaml
@@ -10,22 +10,22 @@ notesdir: fragments
prelude_section_name: release_summary
prelude_section_title: Release Summary
sections:
-- - major_changes
- - Major Changes
-- - minor_changes
- - Minor Changes
-- - breaking_changes
- - Breaking Changes / Porting Guide
-- - deprecated_features
- - Deprecated Features
-- - removed_features
- - Removed Features (previously deprecated)
-- - security_fixes
- - Security Fixes
-- - bugfixes
- - Bugfixes
-- - known_issues
- - Known Issues
+ - - major_changes
+ - Major Changes
+ - - minor_changes
+ - Minor Changes
+ - - breaking_changes
+ - Breaking Changes / Porting Guide
+ - - deprecated_features
+ - Deprecated Features
+ - - removed_features
+ - Removed Features (previously deprecated)
+ - - security_fixes
+ - Security Fixes
+ - - bugfixes
+ - Bugfixes
+ - - known_issues
+ - Known Issues
title: Cisco MSO Ansible Collection
trivial_section_name: trivial
use_fqcn: true
diff --git a/ansible_collections/cisco/mso/meta/runtime.yml b/ansible_collections/cisco/mso/meta/runtime.yml
index bbc15c503..9aeca0a48 100644
--- a/ansible_collections/cisco/mso/meta/runtime.yml
+++ b/ansible_collections/cisco/mso/meta/runtime.yml
@@ -27,6 +27,7 @@ action_groups:
- mso_schema_site_anp_epg_staticleaf
- mso_schema_site_anp_epg_staticport
- mso_schema_site_anp_epg_subnet
+ - mso_schema_site_anp_epg_useg_attribute
- mso_schema_site_bd
- mso_schema_site_bd_l3out
- mso_schema_site_bd_subnet
@@ -45,6 +46,7 @@ action_groups:
- mso_schema_template_anp_epg_contract
- mso_schema_template_anp_epg_selector
- mso_schema_template_anp_epg_subnet
+ - mso_schema_template_anp_epg_useg_attribute
- mso_schema_template_bd
- mso_schema_template_bd_dhcp_policy
- mso_schema_template_bd_subnet
@@ -95,6 +97,7 @@ action_groups:
- mso_schema_site_anp_epg_staticleaf
- mso_schema_site_anp_epg_staticport
- mso_schema_site_anp_epg_subnet
+ - mso_schema_site_anp_epg_useg_attribute
- mso_schema_site_bd
- mso_schema_site_bd_l3out
- mso_schema_site_bd_subnet
@@ -113,6 +116,7 @@ action_groups:
- mso_schema_template_anp_epg_contract
- mso_schema_template_anp_epg_selector
- mso_schema_template_anp_epg_subnet
+ - mso_schema_template_anp_epg_useg_attribute
- mso_schema_template_bd
- mso_schema_template_bd_dhcp_policy
- mso_schema_template_bd_subnet
diff --git a/ansible_collections/cisco/mso/plugins/.DS_Store b/ansible_collections/cisco/mso/plugins/.DS_Store
index 1ffed58d7..7c7d7d98b 100644
--- a/ansible_collections/cisco/mso/plugins/.DS_Store
+++ b/ansible_collections/cisco/mso/plugins/.DS_Store
Binary files differ
diff --git a/ansible_collections/cisco/mso/plugins/doc_fragments/modules.py b/ansible_collections/cisco/mso/plugins/doc_fragments/modules.py
index c7d3d81c0..36e4a84ac 100644
--- a/ansible_collections/cisco/mso/plugins/doc_fragments/modules.py
+++ b/ansible_collections/cisco/mso/plugins/doc_fragments/modules.py
@@ -47,9 +47,9 @@ options:
timeout:
description:
- The socket level timeout in seconds.
+ - The default value is 30 seconds.
- If the value is not specified in the task, the value of environment variable C(MSO_TIMEOUT) will be used instead.
type: int
- default: 30
use_proxy:
description:
- If C(false), it will not use a proxy, even if one is defined in an environment variable on the target hosts.
@@ -75,6 +75,7 @@ options:
- The login domain name to use for authentication.
- The default value is Local.
- If the value is not specified in the task, the value of environment variable C(MSO_LOGIN_DOMAIN) will be used instead.
+ - When using a HTTPAPI connection plugin the inventory variable C(ansible_httpapi_login_domain) will be used if this attribute is not specified.
type: str
requirements:
- Multi Site Orchestrator v2.1 or newer
diff --git a/ansible_collections/cisco/mso/plugins/httpapi/mso.py b/ansible_collections/cisco/mso/plugins/httpapi/mso.py
index 5d69c8a64..286e9dbd0 100644
--- a/ansible_collections/cisco/mso/plugins/httpapi/mso.py
+++ b/ansible_collections/cisco/mso/plugins/httpapi/mso.py
@@ -1,5 +1,6 @@
# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com>
# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com>
+# Copyright: (c) 2023, Akini Ross (@akinross) <akinross@cisco.com>
#
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -16,19 +17,32 @@ description:
a connection to MSO, send API requests and process the
response.
version_added: "1.2.0"
+options:
+ login_domain:
+ description:
+ - The login domain name to use for authentication.
+ - The default value is Local.
+ type: string
+ env:
+ - name: ANSIBLE_HTTPAPI_LOGIN_DOMAIN
+ vars:
+ - name: ansible_httpapi_login_domain
"""
import json
import re
-import pickle
-
-# import ipaddress
import traceback
from ansible.module_utils.six import PY3
from ansible.module_utils._text import to_text
from ansible.module_utils.connection import ConnectionError
from ansible.plugins.httpapi import HttpApiBase
+from copy import copy
+
+
+CONNECTION_MAP = {"username": "remote_user", "timeout": "persistent_command_timeout"}
+RESET_KEYS = ["username", "password", "login_domain", "host", "port"]
+CONNECTION_KEYS = RESET_KEYS + ["use_proxy", "use_ssl", "timeout", "validate_certs"]
class HttpApi(HttpApiBase):
@@ -47,6 +61,8 @@ class HttpApi(HttpApiBase):
self.status = -1
self.info = {}
+ self.connection_parameters = {}
+
def get_platform(self):
return self.platform
@@ -70,20 +86,14 @@ class HttpApi(HttpApiBase):
path = "/mso/api/v1/auth/login"
full_path = self.connection.get_option("host") + path
- if (self.params.get("login_domain") is not None) and (self.params.get("login_domain") != "Local"):
- domain_id = self._get_login_domain_id(self.params.get("login_domain"))
- payload = {"username": self.connection.get_option("remote_user"), "password": self.connection.get_option("password"), "domainId": domain_id}
- else:
- payload = {"username": self.connection.get_option("remote_user"), "password": self.connection.get_option("password")}
-
- # Override the global username/password with the ones specified per task
- if self.params.get("username") is not None:
- payload["username"] = self.params.get("username")
- if self.params.get("password") is not None:
- payload["password"] = self.params.get("password")
+ payload = {"username": username, "password": password}
+ if self.connection_parameters["login_domain"] is not None and self.connection_parameters["login_domain"] != "Local":
+ payload["domainId"] = self._get_login_domain_id(self.connection_parameters["login_domain"])
+
data = json.dumps(payload)
try:
- self.connection.queue_message("vvvv", "login() - connection.send({0}, {1}, {2}, {3})".format(path, data, method, self.headers))
+ payload.pop("password")
+ self.connection.queue_message("vvvv", "login() - connection.send({0}, {1}, {2}, {3})".format(path, payload, method, self.headers))
response, response_data = self.connection.send(path, data, method=method, headers=self.headers)
# Handle MSO response
self.status = response.getcode()
@@ -107,7 +117,7 @@ class HttpApi(HttpApiBase):
path = "/mso/api/v1/auth/logout"
try:
- response, response_data = self.connection.send(path, {}, method=method, headers=self.headers)
+ self.connection.send(path, {}, method=method, headers=self.headers)
except Exception as e:
self.error = dict(code=self.status, message="Error on attempt to logout from MSO. {0}".format(e))
raise ConnectionError(json.dumps(self._verify_response(None, method, self.connection.get_option("host") + path, None)))
@@ -126,47 +136,8 @@ class HttpApi(HttpApiBase):
data = {}
self.connection.queue_message("vvvv", "send_request method called")
- # # Case1: List of hosts is provided
- # self.backup_hosts = self.set_backup_hosts()
- # if not self.backup_hosts:
- if self.connection._connected is True and self.params.get("host") != self.connection.get_option("host"):
- self.connection._connected = False
- self.connection.queue_message(
- "vvvv",
- "send_request reseting connection as host has changed from {0} to {1}".format(self.connection.get_option("host"), self.params.get("host")),
- )
-
- if self.params.get("host") is not None:
- self.connection.set_option("host", self.params.get("host"))
-
- else:
- try:
- with open("my_hosts.pk", "rb") as fi:
- self.host_counter = pickle.load(fi)
- except FileNotFoundError:
- pass
- try:
- self.connection.set_option("host", self.backup_hosts[self.host_counter])
- except (IndexError, TypeError):
- pass
-
- if self.params.get("port") is not None:
- self.connection.set_option("port", self.params.get("port"))
-
- if self.params.get("username") is not None:
- self.connection.set_option("remote_user", self.params.get("username"))
-
- if self.params.get("password") is not None:
- self.connection.set_option("password", self.params.get("password"))
-
- if self.params.get("use_proxy") is not None:
- self.connection.set_option("use_proxy", self.params.get("use_proxy"))
-
- if self.params.get("use_ssl") is not None:
- self.connection.set_option("use_ssl", self.params.get("use_ssl"))
-
- if self.params.get("validate_certs") is not None:
- self.connection.set_option("validate_certs", self.params.get("validate_certs"))
+
+ self.set_connection_parameters()
# Perform some very basic path input validation.
path = str(path)
@@ -187,18 +158,26 @@ class HttpApi(HttpApiBase):
raise ConnectionError(json.dumps(self._verify_response(None, method, full_path, None)))
return self._verify_response(response, method, full_path, rdata)
- def handle_error(self):
- self.host_counter += 1
- if self.host_counter == len(self.backup_hosts):
- raise ConnectionError("No hosts left in cluster to continue operation")
- with open("my_hosts.pk", "wb") as host_file:
- pickle.dump(self.host_counter, host_file)
- try:
- self.connection.set_option("host", self.backup_hosts[self.host_counter])
- except IndexError:
- pass
- self.login(self.connection.get_option("remote_user"), self.connection.get_option("password"))
- return True
+ def set_connection_parameters(self):
+ connection_parameters = {}
+ for key in CONNECTION_KEYS:
+ if key == "login_domain":
+ value = self.params.get(key) if self.params.get(key) is not None else self.get_option(CONNECTION_MAP.get(key, key))
+ self.set_option(key, value)
+ else:
+ value = self.params.get(key) if self.params.get(key) is not None else self.connection.get_option(CONNECTION_MAP.get(key, key))
+ self.connection.set_option(CONNECTION_MAP.get(key, key), value)
+
+ connection_parameters[key] = value
+ if value != self.connection_parameters.get(key) and key in RESET_KEYS:
+ self.connection._connected = False
+ self.connection.queue_message("vvvv", "set_connection_parameters() - resetting connection due to '{0}' change".format(key))
+
+ if self.connection_parameters != connection_parameters:
+ self.connection_parameters = copy(connection_parameters)
+ connection_parameters.pop("password")
+ msg = "set_connection_parameters() - changed connection parameters {0}".format(connection_parameters)
+ self.connection.queue_message("vvvv", msg)
def _verify_response(self, response, method, path, data):
"""Process the return code and response object from MSO"""
diff --git a/ansible_collections/cisco/mso/plugins/module_utils/constants.py b/ansible_collections/cisco/mso/plugins/module_utils/constants.py
index ea461f76c..2f3e0d472 100644
--- a/ansible_collections/cisco/mso/plugins/module_utils/constants.py
+++ b/ansible_collections/cisco/mso/plugins/module_utils/constants.py
@@ -22,3 +22,19 @@ NDO_4_UNIQUE_IDENTIFIERS = ["templateID", "autoRouteTargetImport", "autoRouteTar
NDO_API_VERSION_FORMAT = "/mso/api/{api_version}"
NDO_API_VERSION_PATH_FORMAT = "/mso/api/{api_version}/{path}"
+
+EPG_U_SEG_ATTR_TYPE_MAP = {
+ "ip": "ip",
+ "mac": "mac",
+ "dns": "dns",
+ "vm_datacenter": "rootContName",
+ "vm_hypervisor_identifier": "hv",
+ "vm_operating_system": "guest-os",
+ "vm_tag": "tag",
+ "vm_identifier": "vm",
+ "vmm_domain": "domain",
+ "vm_name": "vm-name",
+ "vnic_dn": "vnic",
+}
+
+EPG_U_SEG_ATTR_OPERATOR_LIST = ["equals", "contains", "starts_with", "ends_with"]
diff --git a/ansible_collections/cisco/mso/plugins/module_utils/mso.py b/ansible_collections/cisco/mso/plugins/module_utils/mso.py
index 91475336b..4bc9053ef 100644
--- a/ansible_collections/cisco/mso/plugins/module_utils/mso.py
+++ b/ansible_collections/cisco/mso/plugins/module_utils/mso.py
@@ -103,7 +103,7 @@ def mso_argument_spec():
username=dict(type="str", required=False, fallback=(env_fallback, ["MSO_USERNAME", "ANSIBLE_NET_USERNAME"])),
password=dict(type="str", required=False, no_log=True, fallback=(env_fallback, ["MSO_PASSWORD", "ANSIBLE_NET_PASSWORD"])),
output_level=dict(type="str", default="normal", choices=["debug", "info", "normal"], fallback=(env_fallback, ["MSO_OUTPUT_LEVEL"])),
- timeout=dict(type="int", default=30, fallback=(env_fallback, ["MSO_TIMEOUT"])),
+ timeout=dict(type="int", fallback=(env_fallback, ["MSO_TIMEOUT"])),
use_proxy=dict(type="bool", fallback=(env_fallback, ["MSO_USE_PROXY"])),
use_ssl=dict(type="bool", fallback=(env_fallback, ["MSO_USE_SSL"])),
validate_certs=dict(type="bool", fallback=(env_fallback, ["MSO_VALIDATE_CERTS"])),
@@ -296,7 +296,7 @@ class MSOModule(object):
self.params = module.params
self.result = dict(changed=False)
self.headers = {"Content-Type": "text/json"}
- self.platform = "mso"
+ self.platform = "local"
# normal output
self.existing = dict()
@@ -333,6 +333,8 @@ class MSOModule(object):
self.params["use_proxy"] = True
if self.params.get("validate_certs") is None:
self.params["validate_certs"] = True
+ if self.params.get("timeout") is None:
+ self.params["timeout"] = 30
# Ensure protocol is set
self.params["protocol"] = "https" if self.params.get("use_ssl", True) else "http"
@@ -357,6 +359,10 @@ class MSOModule(object):
self.connection = Connection(self.module._socket_path)
if self.connection.get_platform() == "cisco.nd":
self.platform = "nd"
+ elif self.connection.get_platform() == "cisco.mso":
+ self.platform = "mso"
+ else:
+ self.fail_json(msg="Connection must be identified as platform 'cisco.nd' or 'cisco.mso'")
def get_login_domain_id(self, domain):
"""Get a domain and return its id"""
@@ -608,7 +614,10 @@ class MSOModule(object):
if self.module._socket_path:
self.connection.set_params(self.params)
if api_version is not None:
- uri = NDO_API_VERSION_PATH_FORMAT.format(api_version=api_version, path=self.path)
+ if self.platform == "nd":
+ uri = NDO_API_VERSION_PATH_FORMAT.format(api_version=api_version, path=self.path)
+ else:
+ uri = "/api/{0}/{1}".format(api_version, self.path)
else:
uri = self.path
@@ -628,6 +637,7 @@ class MSOModule(object):
error=dict(code=-1, message="Unable to parse error output as JSON. Raw error message: {0}".format(e), exception=to_text(e))
)
pass
+ self.httpapi_logs.extend(self.connection.pop_messages())
self.fail_json(msg=error_obj["error"]["message"])
else:
@@ -776,32 +786,38 @@ class MSOModule(object):
self.fail_json(msg="More than one object matches unique filter: {0}".format(kwargs))
return objs[0]
- def lookup_schema(self, schema):
+ def lookup_schema(self, schema, ignore_not_found_error=False):
"""Look up schema and return its id"""
if schema is None:
return schema
schema_summary = self.query_objs("schemas/list-identity", key="schemas", displayName=schema)
- if not schema_summary:
+ if not schema_summary and not ignore_not_found_error:
self.fail_json(msg="Provided schema '{0}' does not exist.".format(schema))
+ elif (not schema_summary or not schema_summary[0].get("id")) and ignore_not_found_error:
+ self.module.warn("Provided schema '{0}' does not exist.".format(schema))
+ return None
schema_id = schema_summary[0].get("id")
if not schema_id:
self.fail_json(msg="Schema lookup failed for schema '{0}': '{1}'".format(schema, schema_id))
return schema_id
- def lookup_domain(self, domain):
+ def lookup_domain(self, domain, ignore_not_found_error=False):
"""Look up a domain and return its id"""
if domain is None:
return domain
d = self.get_obj("auth/domains", key="domains", name=domain)
- if not d:
- self.fail_json(msg="Domain '%s' is not a valid domain name." % domain)
+ if not d and not ignore_not_found_error:
+ self.fail_json(msg="Domain '{0}' is not a valid domain name.".format(domain))
+ elif (not d or "id" not in d) and ignore_not_found_error:
+ self.module.warn("Domain '{0}' is not a valid domain name.".format(domain))
+ return None
if "id" not in d:
- self.fail_json(msg="Domain lookup failed for domain '%s': %s" % (domain, d))
+ self.fail_json(msg="Domain lookup failed for domain '{0}': {1}".format(domain, d))
return d.get("id")
- def lookup_roles(self, roles):
+ def lookup_roles(self, roles, ignore_not_found_error=False):
"""Look up roles and return their ids"""
if roles is None:
return roles
@@ -819,26 +835,32 @@ class MSOModule(object):
name = role
r = self.get_obj("roles", name=name)
- if not r:
- self.fail_json(msg="Role '%s' is not a valid role name." % name)
+ if not r and not ignore_not_found_error:
+ self.fail_json(msg="Role '{0}' is not a valid role name.".format(name))
+ elif (not r or "id" not in r) and ignore_not_found_error:
+ self.module.warn("Role '{0}' is not a valid role name.".format(name))
+ return ids
if "id" not in r:
- self.fail_json(msg="Role lookup failed for role '%s': %s" % (name, r))
+ self.fail_json(msg="Role lookup failed for role '{0}': {1}".format(name, r))
ids.append(dict(roleId=r.get("id"), accessType=access_type))
return ids
- def lookup_site(self, site):
+ def lookup_site(self, site, ignore_not_found_error=False):
"""Look up a site and return its id"""
if site is None:
return site
s = self.get_obj("sites", name=site)
- if not s:
- self.fail_json(msg="Site '%s' is not a valid site name." % site)
+ if not s and not ignore_not_found_error:
+ self.fail_json(msg="Site '{0}' is not a valid site name.".format(site))
+ elif (not s or "id" not in s) and ignore_not_found_error:
+ self.module.warn("Site '{0}' is not a valid site name.".format(site))
+ return None
if "id" not in s:
- self.fail_json(msg="Site lookup failed for site '%s': %s" % (site, s))
+ self.fail_json(msg="Site lookup failed for site '{0}': {1}".format(site, s))
return s.get("id")
- def lookup_sites(self, sites):
+ def lookup_sites(self, sites, ignore_not_found_error=False):
"""Look up sites and return their ids"""
if sites is None:
return sites
@@ -846,37 +868,46 @@ class MSOModule(object):
ids = []
for site in sites:
s = self.get_obj("sites", name=site)
- if not s:
- self.fail_json(msg="Site '%s' is not a valid site name." % site)
+ if not s and not ignore_not_found_error:
+ self.fail_json(msg="Site '{0}' is not a valid site name.".format(site))
+ elif (not s or "id" not in s) and ignore_not_found_error:
+ self.module.warn("Site '{0}' is not a valid site name.".format(site))
+ return ids
if "id" not in s:
- self.fail_json(msg="Site lookup failed for site '%s': %s" % (site, s))
+ self.fail_json(msg="Site lookup failed for site '{0}': {1}".format(site, s))
ids.append(dict(siteId=s.get("id"), securityDomains=[]))
return ids
- def lookup_tenant(self, tenant):
+ def lookup_tenant(self, tenant, ignore_not_found_error=False):
"""Look up a tenant and return its id"""
if tenant is None:
return tenant
t = self.get_obj("tenants", key="tenants", name=tenant)
- if not t:
- self.fail_json(msg="Tenant '%s' is not valid tenant name." % tenant)
+ if not t and not ignore_not_found_error:
+ self.fail_json(msg="Tenant '{0}' is not valid tenant name.".format(tenant))
+ elif (not t or "id" not in t) and ignore_not_found_error:
+ self.module.warn("Tenant '{0}' is not valid tenant name.".format(tenant))
+ return None
if "id" not in t:
- self.fail_json(msg="Tenant lookup failed for tenant '%s': %s" % (tenant, t))
+ self.fail_json(msg="Tenant lookup failed for tenant '{0}': {1}".format(tenant, t))
return t.get("id")
- def lookup_remote_location(self, remote_location):
+ def lookup_remote_location(self, remote_location, ignore_not_found_error=False):
"""Look up a remote location and return its path and id"""
if remote_location is None:
return None
remote = self.get_obj("platform/remote-locations", key="remoteLocations", name=remote_location)
- if "id" not in remote:
- self.fail_json(msg="No remote location found for remote '%s'" % (remote_location))
+ if "id" not in remote and not ignore_not_found_error:
+ self.fail_json(msg="No remote location found for remote '{0}'".format(remote_location))
+ elif "id" not in remote and ignore_not_found_error:
+ self.module.warn("No remote location found for remote '{0}'".format(remote_location))
+ return dict()
remote_info = dict(id=remote.get("id"), path=remote.get("credential")["remotePath"])
return remote_info
- def lookup_users(self, users):
+ def lookup_users(self, users, ignore_not_found_error=False):
"""Look up users and return their ids"""
# Ensure tenant has at least admin user
if users is None:
@@ -890,16 +921,19 @@ class MSOModule(object):
u = self.get_obj("users", loginID=user, api_version="v2")
else:
u = self.get_obj("users", username=user)
- if not u:
- self.fail_json(msg="User '%s' is not a valid user name." % user)
+ if not u and not ignore_not_found_error:
+ self.fail_json(msg="User '{0}' is not a valid user name.".format(user))
+ elif (not u or "id" not in u) and ignore_not_found_error:
+ self.module.warn("User '{0}' is not a valid user name.".format(user))
+ return ids
if "id" not in u:
if "userID" not in u:
- self.fail_json(msg="User lookup failed for user '%s': %s" % (user, u))
+ self.fail_json(msg="User lookup failed for user '{0}': {1}".format(user, u))
id = dict(userId=u.get("userID"))
else:
id = dict(userId=u.get("id"))
if id in ids:
- self.fail_json(msg="User '%s' is duplicate." % user)
+ self.fail_json(msg="User '{0}' is duplicate.".format(user))
ids.append(id)
return ids
@@ -908,7 +942,7 @@ class MSOModule(object):
"""Create a new label"""
return self.request("labels", method="POST", data=dict(displayName=label, type=label_type))
- def lookup_labels(self, labels, label_type):
+ def lookup_labels(self, labels, label_type, ignore_not_found_error=False):
"""Look up labels and return their ids (create if necessary)"""
if labels is None:
return None
@@ -918,8 +952,11 @@ class MSOModule(object):
label_obj = self.get_obj("labels", displayName=label)
if not label_obj:
label_obj = self.create_label(label, label_type)
- if "id" not in label_obj:
- self.fail_json(msg="Label lookup failed for label '%s': %s" % (label, label_obj))
+ if "id" not in label_obj and not ignore_not_found_error:
+ self.fail_json(msg="Label lookup failed for label '{0}': {1}".format(label, label_obj))
+ elif "id" not in label_obj and ignore_not_found_error:
+ self.module.warn("Label lookup failed for label '{0}': {1}".format(label, label_obj))
+ return ids
ids.append(label_obj.get("id"))
return ids
@@ -1292,7 +1329,7 @@ class MSOModule(object):
self.module.fail_json(msg="Service node types do not exist")
return node_objs
- def lookup_service_node_device(self, site_id, tenant, device_name=None, service_node_type=None):
+ def lookup_service_node_device(self, site_id, tenant, device_name=None, service_node_type=None, ignore_not_found_error=False):
if service_node_type is None:
node_devices = self.query_objs("sites/{0}/aci/tenants/{1}/devices".format(site_id, tenant), key="devices")
else:
@@ -1301,7 +1338,11 @@ class MSOModule(object):
for device in node_devices:
if device_name == device.get("name"):
return device
- self.module.fail_json(msg="Provided device '{0}' of type '{1}' does not exist.".format(device_name, service_node_type))
+ if ignore_not_found_error:
+ self.module.warn("Provided device '{0}' of type '{1}' does not exist.".format(device_name, service_node_type))
+ return node_devices
+ else:
+ self.module.fail_json(msg="Provided device '{0}' of type '{1}' does not exist.".format(device_name, service_node_type))
return node_devices
# Workaround function due to inconsistency in attributes REQUEST/RESPONSE API
diff --git a/ansible_collections/cisco/mso/plugins/module_utils/schema.py b/ansible_collections/cisco/mso/plugins/module_utils/schema.py
index ca08ab10b..ce1bd36c7 100644
--- a/ansible_collections/cisco/mso/plugins/module_utils/schema.py
+++ b/ansible_collections/cisco/mso/plugins/module_utils/schema.py
@@ -112,6 +112,21 @@ class MSOSchema:
self.mso.fail_json(msg=msg)
self.schema_objects["template_anp_epg"] = match
+ def set_template_anp_epg_useg_attr(self, useg_attr, fail_module=True):
+ """
+ Get template endpoint group item that matches the name of an EPG uSeg Attribute.
+ :param useg_attr: Name of the EPG uSeg Attribute to match. -> Str
+ :param fail_module: When match is not found fail the ansible module. -> Bool
+ :return: Template EPG uSeg Attribute item. -> Item(Int, Dict) | None
+ """
+ self.validate_schema_objects_present(["template_anp_epg"])
+ kv_list = [KVPair("name", useg_attr)]
+ match, existing = self.get_object_from_list(self.schema_objects["template_anp_epg"].details.get("uSegAttrs"), kv_list)
+ if not match and fail_module:
+ msg = "Provided uSeg Attribute '{0}' does not match the existing uSeg Attribute(s): {1}".format(useg_attr, ", ".join(existing))
+ self.mso.fail_json(msg=msg)
+ self.schema_objects["template_anp_epg_useg_attribute"] = match
+
def set_template_external_epg(self, external_epg, fail_module=True):
"""
Get template external epg item that matches the name of an anp.
@@ -207,3 +222,18 @@ class MSOSchema:
msg = "Provided EPG '{0}' not matching existing site anp epg(s): {1}".format(epg_name, ", ".join(existing))
self.mso.fail_json(msg=msg)
self.schema_objects["site_anp_epg"] = match
+
+ def set_site_anp_epg_useg_attr(self, useg_attr, fail_module=True):
+ """
+ Get site endpoint group item that matches the name of an EPG uSeg Attribute.
+ :param useg_attr: Name of the EPG uSeg Attribute to match. -> Str
+ :param fail_module: When match is not found fail the ansible module. -> Bool
+ :return: Site EPG uSeg Attribute item. -> Item(Int, Dict) | None
+ """
+ self.validate_schema_objects_present(["site_anp_epg"])
+ kv_list = [KVPair("name", useg_attr)]
+ match, existing = self.get_object_from_list(self.schema_objects["site_anp_epg"].details.get("uSegAttrs"), kv_list)
+ if not match and fail_module:
+ msg = "Provided Site uSeg Attribute '{0}' does not match the existing Site uSeg Attribute(s): {1}".format(useg_attr, ", ".join(existing))
+ self.mso.fail_json(msg=msg)
+ self.schema_objects["site_anp_epg_useg_attribute"] = match
diff --git a/ansible_collections/cisco/mso/plugins/modules/mso_schema_site_anp_epg_useg_attribute.py b/ansible_collections/cisco/mso/plugins/modules/mso_schema_site_anp_epg_useg_attribute.py
new file mode 100644
index 000000000..3030852f5
--- /dev/null
+++ b/ansible_collections/cisco/mso/plugins/modules/mso_schema_site_anp_epg_useg_attribute.py
@@ -0,0 +1,276 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2023, Sabari Jaganathan (@sajagana) <sajagana@cisco.com>
+# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"}
+
+DOCUMENTATION = r"""
+---
+module: mso_schema_site_anp_epg_useg_attribute
+short_description: Manage EPG Site uSeg Attributes in schema sites
+description:
+- Manage Site uSeg Attributes in the schema site EPGs on Cisco ACI Multi-Site.
+author:
+- Sabari Jaganathan (@sajagana)
+options:
+ schema:
+ description:
+ - The name of the Schema.
+ type: str
+ required: true
+ template:
+ description:
+ - The name of the Template.
+ type: str
+ required: true
+ site:
+ description:
+ - The name of the site.
+ type: str
+ required: true
+ anp:
+ description:
+ - The name of the Application Profile.
+ type: str
+ required: true
+ epg:
+ description:
+ - The name of the EPG.
+ type: str
+ required: true
+ name:
+ description:
+ - The name and display name of the uSeg Attribute.
+ type: str
+ aliases: [ useg ]
+ description:
+ description:
+ - The description of the uSeg Attribute.
+ type: str
+ aliases: [ descr ]
+ type:
+ description:
+ - The type of the uSeg Attribute.
+ type: str
+ choices: [ vm_name, ip, mac, vmm_domain, vm_operating_system, vm_tag, vm_hypervisor_identifier, dns, vm_datacenter, vm_identifier, vnic_dn ]
+ aliases: [ attribute_type ]
+ value:
+ description:
+ - The value of the uSeg Attribute.
+ type: str
+ aliases: [ attribute_value ]
+ operator:
+ description:
+ - The operator type of the uSeg Attribute.
+ type: str
+ choices: [ equals, contains, starts_with, ends_with ]
+ useg_subnet:
+ description:
+ - The uSeg Subnet can only be used when the I(attribute_type) is IP.
+ - Use C(false) to set the custom uSeg Subnet IP address to the uSeg Attribute.
+ - Use C(true) to set the uSeg Subnet IP address to 0.0.0.0.
+ type: bool
+ 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
+notes:
+- Due to restrictions of the MSO REST API concurrent modifications to EPG subnets can be dangerous and corrupt data.
+extends_documentation_fragment: cisco.mso.modules
+"""
+
+EXAMPLES = r"""
+- name: Add an uSeg attr with attribute_type - ip
+ cisco.mso.mso_schema_site_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ site: ansible_test
+ name: useg_attr_ip
+ attribute_type: ip
+ useg_subnet: false
+ value: 10.0.0.0/24
+ state: present
+ delegate_to: localhost
+
+- name: Query a specific EPG uSeg attr with name
+ cisco.mso.mso_schema_site_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ name: useg_attr_ip
+ site: ansible_test
+ state: query
+ delegate_to: localhost
+
+- name: Query all EPG uSeg attrs
+ cisco.mso.mso_schema_site_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ site: ansible_test
+ state: query
+ delegate_to: localhost
+
+- name: Remove a uSeg attr from an EPG with name
+ cisco.mso.mso_schema_site_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ site: ansible_test
+ name: useg_attr_ip
+ state: absent
+ delegate_to: localhost
+"""
+
+RETURN = r"""
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.mso.plugins.module_utils.mso import MSOModule, mso_argument_spec
+from ansible_collections.cisco.mso.plugins.module_utils.constants import EPG_U_SEG_ATTR_TYPE_MAP, EPG_U_SEG_ATTR_OPERATOR_LIST
+from ansible_collections.cisco.mso.plugins.module_utils.schema import MSOSchema
+
+
+def main():
+ argument_spec = mso_argument_spec()
+ argument_spec.update(
+ schema=dict(type="str", required=True),
+ site=dict(type="str", required=True),
+ template=dict(type="str", required=True),
+ anp=dict(type="str", required=True),
+ epg=dict(type="str", required=True),
+ name=dict(type="str", aliases=["useg"]),
+ description=dict(type="str", aliases=["descr"]),
+ type=dict(type="str", aliases=["attribute_type"], choices=list(EPG_U_SEG_ATTR_TYPE_MAP.keys())),
+ value=dict(type="str", aliases=["attribute_value"]),
+ operator=dict(type="str", choices=EPG_U_SEG_ATTR_OPERATOR_LIST),
+ useg_subnet=dict(type="bool"),
+ state=dict(type="str", default="present", choices=["absent", "present", "query"]),
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ required_if=[
+ ["state", "absent", ["name"]],
+ ["state", "present", ["name", "type"]],
+ ["useg_subnet", False, ["value"]],
+ ],
+ )
+
+ schema = module.params.get("schema")
+ site = module.params.get("site")
+ template = module.params.get("template").replace(" ", "")
+ anp = module.params.get("anp")
+ epg = module.params.get("epg")
+ name = module.params.get("name")
+ description = module.params.get("description")
+ attribute_type = module.params.get("type")
+ value = module.params.get("value")
+ operator = module.params.get("operator")
+ useg_subnet = module.params.get("useg_subnet")
+ state = module.params.get("state")
+ mso = MSOModule(module)
+
+ if state == "present":
+ if attribute_type in ["mac", "dns"] and value is None:
+ mso.fail_json(msg="Failed due to invalid 'value' and the attribute_type is: {0}.".format(attribute_type))
+ elif attribute_type not in ["mac", "dns", "ip"] and (value is None or operator is None):
+ mso.fail_json(msg="Failed due to invalid 'value' or 'operator' and the attribute_type is: {0}.".format(attribute_type))
+
+ mso_schema = MSOSchema(mso, schema, template)
+ mso_schema.set_template(template)
+ mso_schema.set_template_anp(anp)
+ mso_schema.set_template_anp_epg(epg)
+
+ mso_schema.set_site(template, site)
+ mso_schema.set_site_anp(anp, False)
+ mso_schema.set_site_anp_epg(epg, False)
+
+ # Only for NDO less than or equal to 3.7
+ if mso_schema.schema_objects["site_anp_epg"] is None:
+ mso_schema.schema_objects["site_anp_epg_useg_attribute"] = None
+
+ if mso_schema.schema_objects["template_anp_epg"].details.get("uSegEpg"):
+ mso_schema.set_site_anp_epg_useg_attr(name, fail_module=False)
+
+ if mso_schema.schema_objects["site_anp_epg_useg_attribute"] is not None:
+ site_useg_attr_path = "/sites/{0}-{1}/anps/{2}/epgs/{3}/uSegAttrs/{4}".format(
+ mso_schema.schema_objects["site"].details.get("siteId"), template, anp, epg, mso_schema.schema_objects["site_anp_epg_useg_attribute"].index
+ )
+ mso.existing = mso_schema.schema_objects["site_anp_epg_useg_attribute"].details
+ else:
+ mso.fail_json(msg="{0}: is not a valid uSeg EPG.".format(epg))
+
+ if state == "query":
+ if name is None and mso_schema.schema_objects["site_anp_epg"] is not None:
+ mso.existing = mso_schema.schema_objects["site_anp_epg"].details.get("uSegAttrs")
+ elif not mso.existing:
+ mso.fail_json(msg="The uSeg Attribute: {0} not found.".format(name))
+ mso.exit_json()
+
+ site_useg_attrs_path = "/sites/{0}-{1}/anps/{2}/epgs/{3}/uSegAttrs".format(mso_schema.schema_objects["site"].details.get("siteId"), template, anp, epg)
+ ops = []
+ mso.previous = mso.existing
+
+ if state == "absent":
+ if mso.existing:
+ mso.existing = {}
+ ops.append(dict(op="remove", path=site_useg_attr_path))
+
+ if state == "present":
+ if not mso.existing and description is None:
+ description = name
+
+ payload = dict(name=name, displayName=name, description=description, type=EPG_U_SEG_ATTR_TYPE_MAP[attribute_type], value=value)
+
+ if attribute_type == "ip":
+ if useg_subnet is False:
+ payload["fvSubnet"] = True
+ else:
+ payload["fvSubnet"] = False
+ payload["value"] = "0.0.0.0"
+
+ mso.sanitize(payload, collate=True)
+
+ if mso.existing:
+ ops.append(dict(op="replace", path=site_useg_attr_path, value=mso.sent))
+ else:
+ ops.append(dict(op="add", path=site_useg_attrs_path + "/-", value=mso.sent))
+
+ mso.existing = mso.proposed
+
+ if not module.check_mode:
+ mso.request(mso_schema.path, method="PATCH", data=ops)
+
+ mso.exit_json()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/cisco/mso/plugins/modules/mso_schema_template_anp_epg_useg_attribute.py b/ansible_collections/cisco/mso/plugins/modules/mso_schema_template_anp_epg_useg_attribute.py
new file mode 100644
index 000000000..1f61e95de
--- /dev/null
+++ b/ansible_collections/cisco/mso/plugins/modules/mso_schema_template_anp_epg_useg_attribute.py
@@ -0,0 +1,258 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2023, Sabari Jaganathan (@sajagana) <sajagana@cisco.com>
+# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"}
+
+DOCUMENTATION = r"""
+---
+module: mso_schema_template_anp_epg_useg_attribute
+short_description: Manage EPG uSeg Attributes in schema templates
+description:
+- Manage uSeg Attributes in the schema template EPGs on Cisco ACI Multi-Site.
+author:
+- Sabari Jaganathan (@sajagana)
+options:
+ schema:
+ description:
+ - The name of the Schema.
+ type: str
+ required: true
+ template:
+ description:
+ - The name of the Template.
+ type: str
+ required: true
+ anp:
+ description:
+ - The name of the Application Profile.
+ type: str
+ required: true
+ epg:
+ description:
+ - The name of the EPG.
+ type: str
+ required: true
+ name:
+ description:
+ - The name and display name of the uSeg Attribute.
+ type: str
+ aliases: [ useg ]
+ description:
+ description:
+ - The description of the uSeg Attribute.
+ type: str
+ aliases: [ descr ]
+ type:
+ description:
+ - The type of the uSeg Attribute.
+ type: str
+ choices: [ vm_name, ip, mac, vmm_domain, vm_operating_system, vm_tag, vm_hypervisor_identifier, dns, vm_datacenter, vm_identifier, vnic_dn ]
+ aliases: [ attribute_type ]
+ value:
+ description:
+ - The value of the uSeg Attribute.
+ type: str
+ aliases: [ attribute_value ]
+ operator:
+ description:
+ - The operator type of the uSeg Attribute.
+ type: str
+ choices: [ equals, contains, starts_with, ends_with ]
+ useg_subnet:
+ description:
+ - The uSeg Subnet can only be used when the I(attribute_type) is IP.
+ - Use C(false) to set the custom uSeg Subnet IP address to the uSeg Attribute.
+ - Use C(true) to set the uSeg Subnet IP address to 0.0.0.0.
+ type: bool
+ 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
+notes:
+- Due to restrictions of the MSO REST API concurrent modifications to EPG subnets can be dangerous and corrupt data.
+extends_documentation_fragment: cisco.mso.modules
+"""
+
+EXAMPLES = r"""
+- name: Add an uSeg attr with attribute_type - ip
+ cisco.mso.mso_schema_template_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ name: useg_attr_ip
+ attribute_type: ip
+ useg_subnet: false
+ value: 10.0.0.0/24
+ state: present
+ delegate_to: localhost
+
+- name: Query a specific EPG uSeg attr with name
+ cisco.mso.mso_schema_template_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ name: useg_attr_ip
+ state: query
+ delegate_to: localhost
+ register: query_result
+
+- name: Query all EPG uSeg attrs
+ cisco.mso.mso_schema_template_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ state: query
+ delegate_to: localhost
+ register: query_result
+
+- name: Remove a uSeg attr from an EPG with name
+ cisco.mso.mso_schema_template_anp_epg_useg_attribute:
+ host: mso_host
+ username: admin
+ password: SomeSecretPassword
+ schema: Schema 1
+ template: Template 1
+ anp: ANP 1
+ epg: EPG 1
+ name: useg_attr_ip
+ state: absent
+ delegate_to: localhost
+"""
+
+RETURN = r"""
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.mso.plugins.module_utils.mso import MSOModule, mso_argument_spec
+from ansible_collections.cisco.mso.plugins.module_utils.constants import EPG_U_SEG_ATTR_TYPE_MAP, EPG_U_SEG_ATTR_OPERATOR_LIST
+from ansible_collections.cisco.mso.plugins.module_utils.schema import MSOSchema
+
+
+def main():
+ argument_spec = mso_argument_spec()
+ argument_spec.update(
+ schema=dict(type="str", required=True),
+ template=dict(type="str", required=True),
+ anp=dict(type="str", required=True),
+ epg=dict(type="str", required=True),
+ name=dict(type="str", aliases=["useg"]),
+ description=dict(type="str", aliases=["descr"]),
+ type=dict(type="str", aliases=["attribute_type"], choices=list(EPG_U_SEG_ATTR_TYPE_MAP.keys())),
+ value=dict(type="str", aliases=["attribute_value"]),
+ operator=dict(type="str", choices=EPG_U_SEG_ATTR_OPERATOR_LIST),
+ useg_subnet=dict(type="bool"),
+ state=dict(type="str", default="present", choices=["absent", "present", "query"]),
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ required_if=[
+ ["state", "absent", ["name"]],
+ ["state", "present", ["name", "type"]],
+ ["useg_subnet", False, ["value"]],
+ ],
+ )
+
+ schema = module.params.get("schema")
+ template = module.params.get("template").replace(" ", "")
+ anp = module.params.get("anp")
+ epg = module.params.get("epg")
+ name = module.params.get("name")
+ description = module.params.get("description")
+ attribute_type = module.params.get("type")
+ value = module.params.get("value")
+ operator = module.params.get("operator")
+ useg_subnet = module.params.get("useg_subnet")
+ state = module.params.get("state")
+ mso = MSOModule(module)
+
+ if state == "present":
+ if attribute_type in ["mac", "dns"] and value is None:
+ mso.fail_json(msg="Failed due to invalid 'value' and the attribute_type is: {0}.".format(attribute_type))
+ elif attribute_type not in ["mac", "dns", "ip"] and (value is None or operator is None):
+ mso.fail_json(msg="Failed due to invalid 'value' or 'operator' and the attribute_type is: {0}.".format(attribute_type))
+
+ mso_schema = MSOSchema(mso, schema, template)
+ mso_schema.set_template(template)
+ mso_schema.set_template_anp(anp)
+ mso_schema.set_template_anp_epg(epg)
+
+ if mso_schema.schema_objects["template_anp_epg"].details.get("uSegEpg"):
+ mso_schema.set_template_anp_epg_useg_attr(name, fail_module=False)
+ if mso_schema.schema_objects["template_anp_epg_useg_attribute"] is not None:
+ useg_attr_path = "/templates/{0}/anps/{1}/epgs/{2}/uSegAttrs/{3}".format(
+ template, anp, epg, mso_schema.schema_objects["template_anp_epg_useg_attribute"].index
+ )
+ mso.existing = mso_schema.schema_objects["template_anp_epg_useg_attribute"].details
+ else:
+ mso.fail_json(msg="{0}: is not a valid uSeg EPG.".format(epg))
+
+ if state == "query":
+ if name is None:
+ mso.existing = mso_schema.schema_objects["template_anp_epg"].details.get("uSegAttrs")
+ elif not mso.existing:
+ mso.fail_json(msg="The uSeg Attribute: {0} not found.".format(name))
+ mso.exit_json()
+
+ useg_attrs_path = "/templates/{0}/anps/{1}/epgs/{2}/uSegAttrs".format(template, anp, epg)
+ ops = []
+
+ mso.previous = mso.existing
+ if state == "absent":
+ if mso.existing:
+ mso.existing = {}
+ ops.append(dict(op="remove", path=useg_attr_path))
+
+ if state == "present":
+ if not mso.existing and description is None:
+ description = name
+
+ payload = dict(name=name, displayName=name, description=description, type=EPG_U_SEG_ATTR_TYPE_MAP[attribute_type], value=value)
+
+ if attribute_type == "ip":
+ if useg_subnet is False:
+ payload["fvSubnet"] = True
+ else:
+ payload["fvSubnet"] = False
+ payload["value"] = "0.0.0.0"
+
+ mso.sanitize(payload, collate=True)
+
+ if mso.existing:
+ ops.append(dict(op="replace", path=useg_attr_path, value=mso.sent))
+ else:
+ ops.append(dict(op="add", path=useg_attrs_path + "/-", value=mso.sent))
+
+ mso.existing = mso.proposed
+
+ if not module.check_mode:
+ mso.request(mso_schema.path, method="PATCH", data=ops)
+
+ mso.exit_json()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/cisco/mso/plugins/modules/mso_tenant_site.py b/ansible_collections/cisco/mso/plugins/modules/mso_tenant_site.py
index 735f85b13..4b9c2af56 100644
--- a/ansible_collections/cisco/mso/plugins/modules/mso_tenant_site.py
+++ b/ansible_collections/cisco/mso/plugins/modules/mso_tenant_site.py
@@ -260,7 +260,13 @@ def main():
# Get tenant_id and site_id
tenant_id = mso.lookup_tenant(module.params.get("tenant"))
- site_id = mso.lookup_site(module.params.get("site"))
+
+ # To ignore the object not found issue for the lookup methods
+ site_id = mso.lookup_site(module.params.get("site"), True)
+
+ if state == "absent" and not site_id:
+ mso.exit_json()
+
tenants = [(t.get("id")) for t in mso.query_objs("tenants")]
tenant_idx = tenants.index((tenant_id))
diff --git a/ansible_collections/cisco/mso/tests/.DS_Store b/ansible_collections/cisco/mso/tests/.DS_Store
index 8249f4cab..ec383e680 100644
--- a/ansible_collections/cisco/mso/tests/.DS_Store
+++ b/ansible_collections/cisco/mso/tests/.DS_Store
Binary files differ
diff --git a/ansible_collections/cisco/mso/tests/integration/inventory.networking b/ansible_collections/cisco/mso/tests/integration/inventory.networking
index e39d51abb..590ee6685 100644
--- a/ansible_collections/cisco/mso/tests/integration/inventory.networking
+++ b/ansible_collections/cisco/mso/tests/integration/inventory.networking
@@ -13,7 +13,7 @@ lh-dmz1-pod1-ndo-v411 ansible_host=173.36.219.32 ansible_connection=ansible.netc
mso_username=ansible_github_ci
mso_password="sJ94G92#8dq2hx*K4qh"
ansible_user=ansible_github_ci
-ansible_ssh_pass="sJ94G92#8dq2hx*K4qh"
+ansible_httpapi_password="sJ94G92#8dq2hx*K4qh"
ansible_network_os=cisco.mso.mso
ansible_httpapi_validate_certs=False
ansible_httpapi_use_ssl=True
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/aliases
new file mode 100644
index 000000000..5042c9c09
--- /dev/null
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/aliases
@@ -0,0 +1,2 @@
+# No ACI MultiSite infrastructure, so not enabled
+# unsupported
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/tasks/main.yml
new file mode 100644
index 000000000..9ba4c846a
--- /dev/null
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_useg_attribute/tasks/main.yml
@@ -0,0 +1,812 @@
+# Test code for the MSO modules
+# Copyright: (c) 2023, Sabari Jaganathan (@sajagana) <sajagana@cisco.com>
+#
+# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+- name: Test that we have an ACI MultiSite host, username and password
+ fail:
+ msg: "Please define the following variables: mso_hostname, mso_username and mso_password."
+ when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
+
+# CLEAN ENVIRONMENT
+- name: Set vars
+ set_fact:
+ mso_info: &mso_info
+ host: "{{ mso_hostname }}"
+ username: "{{ mso_username }}"
+ password: "{{ mso_password }}"
+ validate_certs: "{{ mso_validate_certs | default(false) }}"
+ use_ssl: "{{ mso_use_ssl | default(true) }}"
+ use_proxy: "{{ mso_use_proxy | default(true) }}"
+ output_level: '{{ mso_output_level | default("info") }}'
+ ignore_errors: true
+
+# Setup Part
+- name: Remove schemas
+ mso_schema: &ansible_test_schema_absent
+ <<: *mso_info
+ schema: ansible_test
+ state: absent
+
+- name: Ensure ansible_test tenant absent
+ mso_tenant: &ansible_test_tenant_absent
+ <<: *mso_info
+ tenant: ansible_test
+ users:
+ - "{{ mso_username }}"
+ state: absent
+
+- name: Ensure ansible_test tenant present
+ mso_tenant: &ansible_test_tenant_present
+ <<: *ansible_test_tenant_absent
+ state: present
+
+- name: Ensure ansible_test schema with ans_test_template exist
+ mso_schema_template:
+ <<: *mso_info
+ schema: ansible_test
+ tenant: ansible_test
+ template: ans_test_template
+ state: present
+
+- name: Ensure ans_test_anp exist
+ mso_schema_template_anp:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ state: present
+
+- name: Add a new VRF
+ cisco.mso.mso_schema_template_vrf:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ vrf: ans_test_vrf
+ state: present
+
+- name: Add a new BD
+ cisco.mso.mso_schema_template_bd:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ bd: ans_test_bd
+ vrf:
+ name: ans_test_vrf
+ state: present
+
+- name: Ensure ans_test_epg exist
+ mso_schema_template_anp_epg:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ useg_epg: true
+ bd:
+ name: ans_test_bd
+ vrf:
+ name: ans_test_vrf
+ state: present
+
+- name: Ensure ans_test_epg_2 exist without useg_epg
+ mso_schema_template_anp_epg:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg_2
+ bd:
+ name: ans_test_bd
+ vrf:
+ name: ans_test_vrf
+ state: present
+
+- name: Associate a ansible_test site with a ansible_test tenant
+ mso_tenant_site:
+ <<: *mso_info
+ tenant: ansible_test
+ site: ansible_test
+ state: present
+
+- name: Ensure ansible_test site associated with ansible_test schema
+ mso_schema_site:
+ <<: *mso_info
+ schema: ansible_test
+ site: ansible_test
+ template: ans_test_template
+ state: present
+
+- name: Add ans_test_epg to the ansible_test site
+ mso_schema_site_anp_epg:
+ <<: *mso_info
+ site: ansible_test
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ state: present
+
+- name: Deploy a schema template
+ cisco.mso.ndo_schema_template_deploy:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ state: deploy
+
+# Test Part
+# Note: Ignore the below task, which is used to reference the attributes to other tasks
+- name: Invalid test - check for missing required attributes error message
+ mso_schema_site_anp_epg_useg_attribute: &useg_attribute_present
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ description: "uSeg Attr object created using Ansible"
+ site: ansible_test
+ state: present
+ ignore_errors: true
+ register: ans_test_uSeg_1_nt
+
+- name: ans_test_uSeg_1 present - attribute_type - ip, useg_subnet - true, without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *mso_info
+ site: ansible_test
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ name: ans_test_uSeg_1
+ attribute_type: ip
+ useg_subnet: true
+ register: ans_test_uSeg_1
+
+- name: Invalid test - ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_2
+ attribute_type: ip
+ useg_subnet: false
+ ignore_errors: true
+ register: ans_test_uSeg_2_nt
+
+- name: ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, with value - check mode
+ mso_schema_site_anp_epg_useg_attribute: &ans_test_uSeg_2_cm_present
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_2
+ attribute_type: ip
+ useg_subnet: false
+ value: 11.22.33.44/24
+ check_mode: true
+ register: ans_test_uSeg_2_cm_present
+
+- name: ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, with value - normal mode
+ mso_schema_site_anp_epg_useg_attribute: &ans_test_uSeg_2_nm_present
+ <<: *ans_test_uSeg_2_cm_present
+ register: ans_test_uSeg_2_nm_present
+
+- name: ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, with value - normal mode again
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *ans_test_uSeg_2_nm_present
+ register: ans_test_uSeg_2_nm_present_again
+
+- name: Assertions check for add ans_test_uSeg_1 and ans_test_uSeg_2 object
+ assert:
+ that:
+ - ans_test_uSeg_1 is changed
+ - ans_test_uSeg_1.current != {}
+ - ans_test_uSeg_1.current.name == "ans_test_uSeg_1"
+ - ans_test_uSeg_1.current.type == "ip"
+ - ans_test_uSeg_1.current.value == "0.0.0.0"
+ - ans_test_uSeg_1.current.fvSubnet == false
+ - ans_test_uSeg_1.current.description == "ans_test_uSeg_1"
+ - ans_test_uSeg_2_nt is not changed
+ - ans_test_uSeg_2_nt.msg == "useg_subnet is False but all of the following are missing{{':'}} value"
+ - ans_test_uSeg_2_cm_present is changed
+ - ans_test_uSeg_2_cm_present.current != {}
+ - ans_test_uSeg_2_cm_present.previous == {}
+ - ans_test_uSeg_2_cm_present.current.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_cm_present.current.type == "ip"
+ - ans_test_uSeg_2_cm_present.current.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_cm_present.current.fvSubnet == true
+ - ans_test_uSeg_2_cm_present.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_2_nm_present is changed
+ - ans_test_uSeg_2_nm_present.current != {}
+ - ans_test_uSeg_2_nm_present.previous == {}
+ - ans_test_uSeg_2_nm_present.current.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_nm_present.current.type == "ip"
+ - ans_test_uSeg_2_nm_present.current.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_nm_present.current.fvSubnet == true
+ - ans_test_uSeg_2_nm_present.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_2_nm_present_again is not changed
+ - ans_test_uSeg_2_nm_present_again.current != {}
+ - ans_test_uSeg_2_nm_present_again.previous != {}
+ - ans_test_uSeg_2_nm_present_again.current.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_nm_present_again.current.type == "ip"
+ - ans_test_uSeg_2_nm_present_again.current.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_nm_present_again.current.fvSubnet == true
+ - ans_test_uSeg_2_nm_present_again.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_2_nm_present_again.previous.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_nm_present_again.previous.type == "ip"
+ - ans_test_uSeg_2_nm_present_again.previous.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_nm_present_again.previous.fvSubnet == true
+ - ans_test_uSeg_2_nm_present_again.previous.description == "uSeg Attr object created using Ansible"
+
+- name: Invalid test - ans_test_uSeg_3 present - attribute_type - mac and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_3
+ attribute_type: mac
+ ignore_errors: true
+ register: ans_test_uSeg_3_nt
+
+- name: ans_test_uSeg_3 present - attribute_type - mac and with value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_3
+ attribute_type: mac
+ value: "aa:bb:cc:dd:ee:ff"
+ register: ans_test_uSeg_3
+
+- name: Assertions check for add ans_test_uSeg_3 object
+ assert:
+ that:
+ - ans_test_uSeg_3_nt is not changed
+ - ans_test_uSeg_3_nt.msg == "Failed due to invalid 'value' and the attribute_type is{{':'}} mac."
+ - ans_test_uSeg_3 is changed
+ - ans_test_uSeg_3.current != {}
+ - ans_test_uSeg_3.previous == {}
+ - ans_test_uSeg_3.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_3.current.name == "ans_test_uSeg_3"
+ - ans_test_uSeg_3.current.type == "mac"
+ - ans_test_uSeg_3.current.value == "aa:bb:cc:dd:ee:ff"
+
+- name: Invalid test - ans_test_uSeg_4 present - attribute_type - dns and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_4
+ attribute_type: dns
+ ignore_errors: true
+ register: ans_test_uSeg_4_nt
+
+- name: ans_test_uSeg_4 present - attribute_type - dns and with value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_4
+ attribute_type: dns
+ value: "test_dns_value"
+ register: ans_test_uSeg_4
+
+- name: Assertions check for add ans_test_uSeg_4 object
+ assert:
+ that:
+ - ans_test_uSeg_4_nt is not changed
+ - ans_test_uSeg_4_nt.msg == "Failed due to invalid 'value' and the attribute_type is{{':'}} dns."
+ - ans_test_uSeg_4 is changed
+ - ans_test_uSeg_4.current != {}
+ - ans_test_uSeg_4.previous == {}
+ - ans_test_uSeg_4.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_4.current.name == "ans_test_uSeg_4"
+ - ans_test_uSeg_4.current.type == "dns"
+ - ans_test_uSeg_4.current.value == "test_dns_value"
+
+- name: Invalid test - ans_test_uSeg_6 present - attribute_type - vm_datacenter and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ attribute_type: vm_datacenter
+ value: test_vm_datacenter_value
+ ignore_errors: true
+ register: ans_test_uSeg_6_nt
+
+- name: Invalid test - ans_test_uSeg_6 present - attribute_type - vm_datacenter, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ attribute_type: vm_datacenter
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_6_nt1
+
+- name: ans_test_uSeg_6 present - attribute_type - vm_datacenter, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ attribute_type: vm_datacenter
+ operator: equals
+ value: test_vm_datacenter_value
+ register: ans_test_uSeg_6
+
+- name: Assertions check for add ans_test_uSeg_6 object
+ assert:
+ that:
+ - ans_test_uSeg_6_nt is not changed
+ - ans_test_uSeg_6_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_datacenter."
+ - ans_test_uSeg_6_nt1 is not changed
+ - ans_test_uSeg_6_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_datacenter."
+ - ans_test_uSeg_6 is changed
+ - ans_test_uSeg_6.current != {}
+ - ans_test_uSeg_6.previous == {}
+ - ans_test_uSeg_6.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_6.current.name == "ans_test_uSeg_6"
+ - ans_test_uSeg_6.current.type == "rootContName"
+ - ans_test_uSeg_6.current.value == "test_vm_datacenter_value"
+
+- name: Invalid test - ans_test_uSeg_7 present - attribute_type - vm_hypervisor_identifier and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_7
+ attribute_type: vm_hypervisor_identifier
+ value: test_vm_hypervisor_identifier_value
+ ignore_errors: true
+ register: ans_test_uSeg_7_nt
+
+- name: Invalid test - ans_test_uSeg_7 present - attribute_type - vm_hypervisor_identifier, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_7
+ attribute_type: vm_hypervisor_identifier
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_7_nt1
+
+- name: ans_test_uSeg_7 present - attribute_type - vm_hypervisor_identifier, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_7
+ attribute_type: vm_hypervisor_identifier
+ operator: equals
+ value: test_vm_hypervisor_identifier_value
+ register: ans_test_uSeg_7
+
+- name: Assertions check for add ans_test_uSeg_7 object
+ assert:
+ that:
+ - ans_test_uSeg_7_nt is not changed
+ - ans_test_uSeg_7_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_hypervisor_identifier."
+ - ans_test_uSeg_7_nt1 is not changed
+ - ans_test_uSeg_7_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_hypervisor_identifier."
+ - ans_test_uSeg_7 is changed
+ - ans_test_uSeg_7.current != {}
+ - ans_test_uSeg_7.previous == {}
+ - ans_test_uSeg_7.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_7.current.name == "ans_test_uSeg_7"
+ - ans_test_uSeg_7.current.type == "hv"
+ - ans_test_uSeg_7.current.value == "test_vm_hypervisor_identifier_value"
+
+- name: Invalid test - ans_test_uSeg_8 present - attribute_type - vm_operating_system and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_8
+ attribute_type: vm_operating_system
+ value: test_vm_operating_system_value
+ ignore_errors: true
+ register: ans_test_uSeg_8_nt
+
+- name: Invalid test - ans_test_uSeg_8 present - attribute_type - vm_operating_system, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_8
+ attribute_type: vm_operating_system
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_8_nt1
+
+- name: ans_test_uSeg_8 present - attribute_type - vm_operating_system, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_8
+ attribute_type: vm_operating_system
+ operator: equals
+ value: test_vm_operating_system_value
+ register: ans_test_uSeg_8
+
+- name: Assertions check for add ans_test_uSeg_8 object
+ assert:
+ that:
+ - ans_test_uSeg_8_nt is not changed
+ - ans_test_uSeg_8_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_operating_system."
+ - ans_test_uSeg_8_nt1 is not changed
+ - ans_test_uSeg_8_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_operating_system."
+ - ans_test_uSeg_8 is changed
+ - ans_test_uSeg_8.current != {}
+ - ans_test_uSeg_8.previous == {}
+ - ans_test_uSeg_8.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_8.current.name == "ans_test_uSeg_8"
+ - ans_test_uSeg_8.current.type == "guest-os"
+ - ans_test_uSeg_8.current.value == "test_vm_operating_system_value"
+
+- name: Invalid test - ans_test_uSeg_9 present - attribute_type - vm_tag and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_9
+ attribute_type: vm_tag
+ value: test_vm_tag_value
+ ignore_errors: true
+ register: ans_test_uSeg_9_nt
+
+- name: Invalid test - ans_test_uSeg_9 present - attribute_type - vm_tag, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_9
+ attribute_type: vm_tag
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_9_nt1
+
+- name: ans_test_uSeg_9 present - attribute_type - vm_tag, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_9
+ attribute_type: vm_tag
+ operator: equals
+ value: test_vm_tag_value
+ register: ans_test_uSeg_9
+
+- name: Assertions check for add ans_test_uSeg_9 object
+ assert:
+ that:
+ - ans_test_uSeg_9_nt is not changed
+ - ans_test_uSeg_9_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_tag."
+ - ans_test_uSeg_9_nt1 is not changed
+ - ans_test_uSeg_9_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_tag."
+ - ans_test_uSeg_9 is changed
+ - ans_test_uSeg_9.current != {}
+ - ans_test_uSeg_9.previous == {}
+ - ans_test_uSeg_9.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_9.current.name == "ans_test_uSeg_9"
+ - ans_test_uSeg_9.current.type == "tag"
+ - ans_test_uSeg_9.current.value == "test_vm_tag_value"
+
+- name: Invalid test - ans_test_uSeg_10 present - attribute_type - vm_identifier and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_10
+ attribute_type: vm_identifier
+ value: test_vm_identifier_value
+ ignore_errors: true
+ register: ans_test_uSeg_10_nt
+
+- name: Invalid test - ans_test_uSeg_10 present - attribute_type - vm_identifier, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_10
+ attribute_type: vm_identifier
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_10_nt1
+
+- name: ans_test_uSeg_10 present - attribute_type - vm_identifier, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_10
+ attribute_type: vm_identifier
+ operator: equals
+ value: test_vm_identifier_value
+ register: ans_test_uSeg_10
+
+- name: Assertions check for add ans_test_uSeg_10 object
+ assert:
+ that:
+ - ans_test_uSeg_10_nt is not changed
+ - ans_test_uSeg_10_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_identifier."
+ - ans_test_uSeg_10_nt1 is not changed
+ - ans_test_uSeg_10_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_identifier."
+ - ans_test_uSeg_10 is changed
+ - ans_test_uSeg_10.current != {}
+ - ans_test_uSeg_10.previous == {}
+ - ans_test_uSeg_10.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_10.current.name == "ans_test_uSeg_10"
+ - ans_test_uSeg_10.current.type == "vm"
+ - ans_test_uSeg_10.current.value == "test_vm_identifier_value"
+
+- name: Invalid test - ans_test_uSeg_11 present - attribute_type - vmm_domain and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_11
+ attribute_type: vmm_domain
+ value: test_vmm_domain_value
+ ignore_errors: true
+ register: ans_test_uSeg_11_nt
+
+- name: Invalid test - ans_test_uSeg_11 present - attribute_type - vmm_domain, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_11
+ attribute_type: vmm_domain
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_11_nt1
+
+- name: ans_test_uSeg_11 present - attribute_type - vmm_domain, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_11
+ attribute_type: vmm_domain
+ operator: equals
+ value: test_vmm_domain_value
+ register: ans_test_uSeg_11
+
+- name: Assertions check for add ans_test_uSeg_11 object
+ assert:
+ that:
+ - ans_test_uSeg_11_nt is not changed
+ - ans_test_uSeg_11_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vmm_domain."
+ - ans_test_uSeg_11_nt1 is not changed
+ - ans_test_uSeg_11_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vmm_domain."
+ - ans_test_uSeg_11 is changed
+ - ans_test_uSeg_11.current != {}
+ - ans_test_uSeg_11.previous == {}
+ - ans_test_uSeg_11.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_11.current.name == "ans_test_uSeg_11"
+ - ans_test_uSeg_11.current.type == "domain"
+ - ans_test_uSeg_11.current.value == "test_vmm_domain_value"
+
+- name: Invalid test - ans_test_uSeg_12 present - attribute_type - vm_name and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_12
+ attribute_type: vm_name
+ value: test_vm_value
+ ignore_errors: true
+ register: ans_test_uSeg_12_nt
+
+- name: Invalid test - ans_test_uSeg_12 present - attribute_type - vm_name, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_12
+ attribute_type: vm_name
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_12_nt1
+
+- name: ans_test_uSeg_12 present - attribute_type - vm_name, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_12
+ attribute_type: vm_name
+ operator: equals
+ value: test_vm_value
+ register: ans_test_uSeg_12
+
+- name: Assertions check for add ans_test_uSeg_12 object
+ assert:
+ that:
+ - ans_test_uSeg_12_nt is not changed
+ - ans_test_uSeg_12_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_name."
+ - ans_test_uSeg_12_nt1 is not changed
+ - ans_test_uSeg_12_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_name."
+ - ans_test_uSeg_12 is changed
+ - ans_test_uSeg_12.current != {}
+ - ans_test_uSeg_12.previous == {}
+ - ans_test_uSeg_12.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_12.current.name == "ans_test_uSeg_12"
+ - ans_test_uSeg_12.current.type == "vm-name"
+ - ans_test_uSeg_12.current.value == "test_vm_value"
+
+- name: Invalid test - ans_test_uSeg_13 present - attribute_type - vnic_dn and without operator
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ attribute_type: vnic_dn
+ value: test_vnic_dn_value
+ ignore_errors: true
+ register: ans_test_uSeg_13_nt
+
+- name: Invalid test - ans_test_uSeg_13 present - attribute_type - vnic_dn, operator - equals and without value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ attribute_type: vnic_dn
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_13_nt1
+
+- name: ans_test_uSeg_13 present - attribute_type - vnic_dn, operator - equals and value
+ mso_schema_site_anp_epg_useg_attribute: &ans_test_uSeg_13_present
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ attribute_type: vnic_dn
+ operator: equals
+ value: test_vnic_dn_value
+ register: ans_test_uSeg_13
+
+- name: Assertions check for add ans_test_uSeg_12 object
+ assert:
+ that:
+ - ans_test_uSeg_13_nt is not changed
+ - ans_test_uSeg_13_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vnic_dn."
+ - ans_test_uSeg_13_nt1 is not changed
+ - ans_test_uSeg_13_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vnic_dn."
+ - ans_test_uSeg_13 is changed
+ - ans_test_uSeg_13.current != {}
+ - ans_test_uSeg_13.previous == {}
+ - ans_test_uSeg_13.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_13.current.name == "ans_test_uSeg_13"
+ - ans_test_uSeg_13.current.type == "vnic"
+ - ans_test_uSeg_13.current.value == "test_vnic_dn_value"
+
+# Query Part
+- name: Invalid test - Query an uSeg Attr with name - invalid_useg_attr
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: invalid_useg_attr
+ state: query
+ register: invalid_useg_attr
+ ignore_errors: true
+
+- name: Query an uSeg Attr with name - ans_test_uSeg_1
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ state: query
+ register: query_a_useg_6
+
+- name: Query all uSeg Attrs
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ state: query
+ register: query_all_useg_objects
+
+- name: Assertions check for query uSeg Attr objects
+ assert:
+ that:
+ - invalid_useg_attr is not changed
+ - invalid_useg_attr.msg == "The uSeg Attribute{{':'}} invalid_useg_attr not found."
+ - query_a_useg_6 is not changed
+ - query_a_useg_6.current != {}
+ - query_a_useg_6.current.name == "ans_test_uSeg_6"
+ - query_a_useg_6.current.type == "rootContName"
+ - query_a_useg_6.current.value == "test_vm_datacenter_value"
+ - query_all_useg_objects is not changed
+ - query_all_useg_objects.current | length >= 12
+
+# Update Part
+- name: Update ans_test_uSeg_13 object description and value
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *ans_test_uSeg_13_present
+ description: "ans_test_uSeg_13 updated!"
+ value: test_vnic_dn_value_updated
+ register: ans_test_uSeg_13_update
+
+- name: Query an uSeg Attr with name - ans_test_uSeg_13 to check the updated changes
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ state: query
+ register: query_a_useg_object_with_name
+
+- name: Assertions check for update ans_test_uSeg_13 object
+ assert:
+ that:
+ - ans_test_uSeg_13_update is changed
+ - ans_test_uSeg_13_update.current != {}
+ - ans_test_uSeg_13_update.current.description == "ans_test_uSeg_13 updated!"
+ - ans_test_uSeg_13_update.current.name == "ans_test_uSeg_13"
+ - ans_test_uSeg_13_update.current.type == "vnic"
+ - ans_test_uSeg_13_update.current.value == "test_vnic_dn_value_updated"
+ - ans_test_uSeg_13_update.previous != {}
+ - ans_test_uSeg_13_update.previous.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_13_update.previous.name == "ans_test_uSeg_13"
+ - ans_test_uSeg_13_update.previous.type == "vnic"
+ - ans_test_uSeg_13_update.previous.value == "test_vnic_dn_value"
+ - query_a_useg_object_with_name is not changed
+ - query_a_useg_object_with_name.current != {}
+ - query_a_useg_object_with_name.current.description == "ans_test_uSeg_13 updated!"
+ - query_a_useg_object_with_name.current.name == "ans_test_uSeg_13"
+ - query_a_useg_object_with_name.current.type == "vnic"
+ - query_a_useg_object_with_name.current.value == "test_vnic_dn_value_updated"
+
+# Cleanup Part
+- name: ans_test_uSeg_1 absent with check mode
+ mso_schema_site_anp_epg_useg_attribute: &ans_test_uSeg_1_cm_absent
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_1
+ state: absent
+ check_mode: true
+ register: ans_test_uSeg_1_cm_absent
+
+- name: ans_test_uSeg_1 absent with normal mode
+ mso_schema_site_anp_epg_useg_attribute: &ans_test_uSeg_1_nm_absent
+ <<: *ans_test_uSeg_1_cm_absent
+ register: ans_test_uSeg_1_nm_absent
+
+- name: ans_test_uSeg_1 absent with normal mode again
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *ans_test_uSeg_1_nm_absent
+ register: ans_test_uSeg_1_nm_absent_again
+
+- name: Assertions check for ans_test_uSeg_1 absent
+ assert:
+ that:
+ - ans_test_uSeg_1_cm_absent is changed
+ - ans_test_uSeg_1_cm_absent.current == {}
+ - ans_test_uSeg_1_cm_absent.previous != {}
+ - ans_test_uSeg_1_nm_absent is changed
+ - ans_test_uSeg_1_nm_absent.current == {}
+ - ans_test_uSeg_1_nm_absent.previous != {}
+ - ans_test_uSeg_1_nm_absent_again is not changed
+ - ans_test_uSeg_1_nm_absent_again.current == {}
+ - ans_test_uSeg_1_nm_absent_again.previous == {}
+
+- name: Query all uSeg Attrs - invalid template name
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ template: ans_test_template_123
+ state: query
+ ignore_errors: true
+ register: query_invalid_template
+
+- name: Query all uSeg Attrs - invalid Application Profile name
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ anp: ans_test_anp_123
+ state: query
+ ignore_errors: true
+ register: query_invalid_ap
+
+- name: Query all uSeg Attrs - invalid EPG name
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ epg: ans_test_epg_123
+ state: query
+ ignore_errors: true
+ register: query_invalid_epg
+
+- name: Invalid test - ans_test_anp_123 present under ans_test_epg_2
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ epg: ans_test_epg_2
+ name: ans_test_anp_123
+ attribute_type: mac
+ value: "AA:BB:CC:DD:EE:FF"
+ ignore_errors: true
+ register: ans_test_epg_2_nt
+
+- name: Assertions check for invalid inputs
+ assert:
+ that:
+ - query_invalid_template is not changed
+ - query_invalid_template.msg is match("Provided template 'ans_test_template_123' not matching existing template.+")
+ - query_invalid_ap is not changed
+ - query_invalid_ap.msg is match("Provided ANP 'ans_test_anp_123' not matching existing anp.+")
+ - query_invalid_epg is not changed
+ - query_invalid_epg.msg is match("Provided EPG 'ans_test_epg_123' not matching existing epg.+")
+ - ans_test_epg_2_nt is not changed
+ - ans_test_epg_2_nt.msg is match("ans_test_epg_2{{':'}} is not a valid uSeg EPG.")
+
+- name: Deploy a schema template
+ cisco.mso.ndo_schema_template_deploy:
+ <<: *mso_info
+ sites:
+ - ansible_test
+ schema: ansible_test
+ template: ans_test_template
+ state: undeploy
+
+- name: Remove ansible_test schema to delete all uSeg Attr objects
+ mso_schema:
+ <<: *ansible_test_schema_absent
+ schema: ansible_test
+ state: absent
+
+# To check all uSeg Attrs removed from the machine
+- name: Query all uSeg Attrs - Cleanup Part
+ mso_schema_site_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ state: query
+ ignore_errors: true
+ register: query_useg_absent_check
+
+- name: Assertions check for query all uSeg Attrs - Cleanup Part
+ assert:
+ that:
+ - query_useg_absent_check is not changed
+ - query_useg_absent_check.current == {}
+
+- name: Remove ansible_test tenant
+ mso_tenant:
+ <<: *ansible_test_tenant_present
+ state: absent
+ <<: *mso_info
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/aliases
new file mode 100644
index 000000000..5042c9c09
--- /dev/null
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/aliases
@@ -0,0 +1,2 @@
+# No ACI MultiSite infrastructure, so not enabled
+# unsupported
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/tasks/main.yml
new file mode 100644
index 000000000..ef17edac1
--- /dev/null
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_useg_attribute/tasks/main.yml
@@ -0,0 +1,743 @@
+# Test code for the MSO modules
+# Copyright: (c) 2023, Sabari Jaganathan (@sajagana) <sajagana@cisco.com>
+#
+# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+- name: Test that we have an ACI MultiSite host, username and password
+ fail:
+ msg: "Please define the following variables: mso_hostname, mso_username and mso_password."
+ when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
+
+# CLEAN ENVIRONMENT
+- name: Set vars
+ set_fact:
+ mso_info: &mso_info
+ host: "{{ mso_hostname }}"
+ username: "{{ mso_username }}"
+ password: "{{ mso_password }}"
+ validate_certs: "{{ mso_validate_certs | default(false) }}"
+ use_ssl: "{{ mso_use_ssl | default(true) }}"
+ use_proxy: "{{ mso_use_proxy | default(true) }}"
+ output_level: '{{ mso_output_level | default("info") }}'
+ ignore_errors: true
+
+# Setup Part
+- name: Remove schemas
+ mso_schema: &ansible_schema_absent
+ <<: *mso_info
+ schema: ansible_test
+ state: absent
+
+- name: Ensure ansible_test tenant absent
+ mso_tenant: &ansible_tenant_absent
+ <<: *mso_info
+ tenant: ansible_test
+ users:
+ - "{{ mso_username }}"
+ state: absent
+
+- name: Ensure ansible_test tenant present
+ mso_tenant: &ansible_tenant_present
+ <<: *ansible_tenant_absent
+ state: present
+
+- name: Ensure ansible_test schema with ans_test_template exist
+ mso_schema_template:
+ <<: *mso_info
+ schema: ansible_test
+ tenant: ansible_test
+ template: ans_test_template
+ state: present
+
+- name: Ensure ans_test_anp exist
+ mso_schema_template_anp:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ state: present
+
+- name: Ensure ans_test_epg exist
+ mso_schema_template_anp_epg:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ useg_epg: true
+ state: present
+
+- name: Ensure ans_test_epg_2 exist without useg_epg
+ mso_schema_template_anp_epg:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg_2
+ state: present
+
+# Test Part
+# Note: Ignore the below task, which is used to reference the attributes to other tasks
+- name: Invalid test - check for missing required attributes error message
+ mso_schema_template_anp_epg_useg_attribute: &useg_attribute_present
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ description: "uSeg Attr object created using Ansible"
+ state: present
+ ignore_errors: true
+ register: ans_test_uSeg_1_nt
+
+- name: ans_test_uSeg_1 present - attribute_type - ip, useg_subnet - true, without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *mso_info
+ schema: ansible_test
+ template: ans_test_template
+ anp: ans_test_anp
+ epg: ans_test_epg
+ name: ans_test_uSeg_1
+ attribute_type: ip
+ useg_subnet: true
+ register: ans_test_uSeg_1
+
+- name: Invalid test - ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_2
+ attribute_type: ip
+ useg_subnet: false
+ ignore_errors: true
+ register: ans_test_uSeg_2_nt
+
+- name: ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, with value - check mode
+ mso_schema_template_anp_epg_useg_attribute: &ans_test_uSeg_2_cm_present
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_2
+ attribute_type: ip
+ useg_subnet: false
+ value: 11.22.33.44/24
+ check_mode: true
+ register: ans_test_uSeg_2_cm_present
+
+- name: ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, with value - normal mode
+ mso_schema_template_anp_epg_useg_attribute: &ans_test_uSeg_2_nm_present
+ <<: *ans_test_uSeg_2_cm_present
+ register: ans_test_uSeg_2_nm_present
+
+- name: ans_test_uSeg_2 present - attribute_type - ip, useg_subnet - false, with value - normal mode again
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *ans_test_uSeg_2_nm_present
+ register: ans_test_uSeg_2_nm_present_again
+
+- name: Assertions check for add ans_test_uSeg_1 and ans_test_uSeg_2 object
+ assert:
+ that:
+ - ans_test_uSeg_1 is changed
+ - ans_test_uSeg_1.current != {}
+ - ans_test_uSeg_1.current.name == "ans_test_uSeg_1"
+ - ans_test_uSeg_1.current.type == "ip"
+ - ans_test_uSeg_1.current.value == "0.0.0.0"
+ - ans_test_uSeg_1.current.fvSubnet == false
+ - ans_test_uSeg_1.current.description == "ans_test_uSeg_1"
+ - ans_test_uSeg_2_nt is not changed
+ - ans_test_uSeg_2_nt.msg == "useg_subnet is False but all of the following are missing{{':'}} value"
+ - ans_test_uSeg_2_cm_present is changed
+ - ans_test_uSeg_2_cm_present.current != {}
+ - ans_test_uSeg_2_cm_present.previous == {}
+ - ans_test_uSeg_2_cm_present.current.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_cm_present.current.type == "ip"
+ - ans_test_uSeg_2_cm_present.current.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_cm_present.current.fvSubnet == true
+ - ans_test_uSeg_2_cm_present.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_2_nm_present is changed
+ - ans_test_uSeg_2_nm_present.current != {}
+ - ans_test_uSeg_2_nm_present.previous == {}
+ - ans_test_uSeg_2_nm_present.current.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_nm_present.current.type == "ip"
+ - ans_test_uSeg_2_nm_present.current.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_nm_present.current.fvSubnet == true
+ - ans_test_uSeg_2_nm_present.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_2_nm_present_again is not changed
+ - ans_test_uSeg_2_nm_present_again.current != {}
+ - ans_test_uSeg_2_nm_present_again.previous != {}
+ - ans_test_uSeg_2_nm_present_again.current.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_nm_present_again.current.type == "ip"
+ - ans_test_uSeg_2_nm_present_again.current.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_nm_present_again.current.fvSubnet == true
+ - ans_test_uSeg_2_nm_present_again.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_2_nm_present_again.previous.name == "ans_test_uSeg_2"
+ - ans_test_uSeg_2_nm_present_again.previous.type == "ip"
+ - ans_test_uSeg_2_nm_present_again.previous.value == "11.22.33.44/24"
+ - ans_test_uSeg_2_nm_present_again.previous.fvSubnet == true
+ - ans_test_uSeg_2_nm_present_again.previous.description == "uSeg Attr object created using Ansible"
+
+- name: Invalid test - ans_test_uSeg_3 present - attribute_type - mac and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_3
+ attribute_type: mac
+ ignore_errors: true
+ register: ans_test_uSeg_3_nt
+
+- name: ans_test_uSeg_3 present - attribute_type - mac and with value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_3
+ attribute_type: mac
+ value: "aa:bb:cc:dd:ee:ff"
+ register: ans_test_uSeg_3
+
+- name: Assertions check for add ans_test_uSeg_3 object
+ assert:
+ that:
+ - ans_test_uSeg_3_nt is not changed
+ - ans_test_uSeg_3_nt.msg == "Failed due to invalid 'value' and the attribute_type is{{':'}} mac."
+ - ans_test_uSeg_3 is changed
+ - ans_test_uSeg_3.current != {}
+ - ans_test_uSeg_3.previous == {}
+ - ans_test_uSeg_3.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_3.current.name == "ans_test_uSeg_3"
+ - ans_test_uSeg_3.current.type == "mac"
+ - ans_test_uSeg_3.current.value == "aa:bb:cc:dd:ee:ff"
+
+- name: Invalid test - ans_test_uSeg_4 present - attribute_type - dns and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_4
+ attribute_type: dns
+ ignore_errors: true
+ register: ans_test_uSeg_4_nt
+
+- name: ans_test_uSeg_4 present - attribute_type - dns and with value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_4
+ attribute_type: dns
+ value: "test_dns_value"
+ register: ans_test_uSeg_4
+
+- name: Assertions check for add ans_test_uSeg_4 object
+ assert:
+ that:
+ - ans_test_uSeg_4_nt is not changed
+ - ans_test_uSeg_4_nt.msg == "Failed due to invalid 'value' and the attribute_type is{{':'}} dns."
+ - ans_test_uSeg_4 is changed
+ - ans_test_uSeg_4.current != {}
+ - ans_test_uSeg_4.previous == {}
+ - ans_test_uSeg_4.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_4.current.name == "ans_test_uSeg_4"
+ - ans_test_uSeg_4.current.type == "dns"
+ - ans_test_uSeg_4.current.value == "test_dns_value"
+
+- name: Invalid test - ans_test_uSeg_6 present - attribute_type - vm_datacenter and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ attribute_type: vm_datacenter
+ value: test_vm_datacenter_value
+ ignore_errors: true
+ register: ans_test_uSeg_6_nt
+
+- name: Invalid test - ans_test_uSeg_6 present - attribute_type - vm_datacenter, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ attribute_type: vm_datacenter
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_6_nt1
+
+- name: ans_test_uSeg_6 present - attribute_type - vm_datacenter, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ attribute_type: vm_datacenter
+ operator: equals
+ value: test_vm_datacenter_value
+ register: ans_test_uSeg_6
+
+- name: Assertions check for add ans_test_uSeg_6 object
+ assert:
+ that:
+ - ans_test_uSeg_6_nt is not changed
+ - ans_test_uSeg_6_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_datacenter."
+ - ans_test_uSeg_6_nt1 is not changed
+ - ans_test_uSeg_6_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_datacenter."
+ - ans_test_uSeg_6 is changed
+ - ans_test_uSeg_6.current != {}
+ - ans_test_uSeg_6.previous == {}
+ - ans_test_uSeg_6.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_6.current.name == "ans_test_uSeg_6"
+ - ans_test_uSeg_6.current.type == "rootContName"
+ - ans_test_uSeg_6.current.value == "test_vm_datacenter_value"
+
+- name: Invalid test - ans_test_uSeg_7 present - attribute_type - vm_hypervisor_identifier and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_7
+ attribute_type: vm_hypervisor_identifier
+ value: test_vm_hypervisor_identifier_value
+ ignore_errors: true
+ register: ans_test_uSeg_7_nt
+
+- name: Invalid test - ans_test_uSeg_7 present - attribute_type - vm_hypervisor_identifier, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_7
+ attribute_type: vm_hypervisor_identifier
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_7_nt1
+
+- name: ans_test_uSeg_7 present - attribute_type - vm_hypervisor_identifier, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_7
+ attribute_type: vm_hypervisor_identifier
+ operator: equals
+ value: test_vm_hypervisor_identifier_value
+ register: ans_test_uSeg_7
+
+- name: Assertions check for add ans_test_uSeg_7 object
+ assert:
+ that:
+ - ans_test_uSeg_7_nt is not changed
+ - ans_test_uSeg_7_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_hypervisor_identifier."
+ - ans_test_uSeg_7_nt1 is not changed
+ - ans_test_uSeg_7_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_hypervisor_identifier."
+ - ans_test_uSeg_7 is changed
+ - ans_test_uSeg_7.current != {}
+ - ans_test_uSeg_7.previous == {}
+ - ans_test_uSeg_7.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_7.current.name == "ans_test_uSeg_7"
+ - ans_test_uSeg_7.current.type == "hv"
+ - ans_test_uSeg_7.current.value == "test_vm_hypervisor_identifier_value"
+
+- name: Invalid test - ans_test_uSeg_8 present - attribute_type - vm_operating_system and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_8
+ attribute_type: vm_operating_system
+ value: test_vm_operating_system_value
+ ignore_errors: true
+ register: ans_test_uSeg_8_nt
+
+- name: Invalid test - ans_test_uSeg_8 present - attribute_type - vm_operating_system, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_8
+ attribute_type: vm_operating_system
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_8_nt1
+
+- name: ans_test_uSeg_8 present - attribute_type - vm_operating_system, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_8
+ attribute_type: vm_operating_system
+ operator: equals
+ value: test_vm_operating_system_value
+ register: ans_test_uSeg_8
+
+- name: Assertions check for add ans_test_uSeg_8 object
+ assert:
+ that:
+ - ans_test_uSeg_8_nt is not changed
+ - ans_test_uSeg_8_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_operating_system."
+ - ans_test_uSeg_8_nt1 is not changed
+ - ans_test_uSeg_8_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_operating_system."
+ - ans_test_uSeg_8 is changed
+ - ans_test_uSeg_8.current != {}
+ - ans_test_uSeg_8.previous == {}
+ - ans_test_uSeg_8.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_8.current.name == "ans_test_uSeg_8"
+ - ans_test_uSeg_8.current.type == "guest-os"
+ - ans_test_uSeg_8.current.value == "test_vm_operating_system_value"
+
+- name: Invalid test - ans_test_uSeg_9 present - attribute_type - vm_tag and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_9
+ attribute_type: vm_tag
+ value: test_vm_tag_value
+ ignore_errors: true
+ register: ans_test_uSeg_9_nt
+
+- name: Invalid test - ans_test_uSeg_9 present - attribute_type - vm_tag, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_9
+ attribute_type: vm_tag
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_9_nt1
+
+- name: ans_test_uSeg_9 present - attribute_type - vm_tag, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_9
+ attribute_type: vm_tag
+ operator: equals
+ value: test_vm_tag_value
+ register: ans_test_uSeg_9
+
+- name: Assertions check for add ans_test_uSeg_9 object
+ assert:
+ that:
+ - ans_test_uSeg_9_nt is not changed
+ - ans_test_uSeg_9_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_tag."
+ - ans_test_uSeg_9_nt1 is not changed
+ - ans_test_uSeg_9_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_tag."
+ - ans_test_uSeg_9 is changed
+ - ans_test_uSeg_9.current != {}
+ - ans_test_uSeg_9.previous == {}
+ - ans_test_uSeg_9.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_9.current.name == "ans_test_uSeg_9"
+ - ans_test_uSeg_9.current.type == "tag"
+ - ans_test_uSeg_9.current.value == "test_vm_tag_value"
+
+- name: Invalid test - ans_test_uSeg_10 present - attribute_type - vm_identifier and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_10
+ attribute_type: vm_identifier
+ value: test_vm_identifier_value
+ ignore_errors: true
+ register: ans_test_uSeg_10_nt
+
+- name: Invalid test - ans_test_uSeg_10 present - attribute_type - vm_identifier, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_10
+ attribute_type: vm_identifier
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_10_nt1
+
+- name: ans_test_uSeg_10 present - attribute_type - vm_identifier, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_10
+ attribute_type: vm_identifier
+ operator: equals
+ value: test_vm_identifier_value
+ register: ans_test_uSeg_10
+
+- name: Assertions check for add ans_test_uSeg_10 object
+ assert:
+ that:
+ - ans_test_uSeg_10_nt is not changed
+ - ans_test_uSeg_10_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_identifier."
+ - ans_test_uSeg_10_nt1 is not changed
+ - ans_test_uSeg_10_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_identifier."
+ - ans_test_uSeg_10 is changed
+ - ans_test_uSeg_10.current != {}
+ - ans_test_uSeg_10.previous == {}
+ - ans_test_uSeg_10.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_10.current.name == "ans_test_uSeg_10"
+ - ans_test_uSeg_10.current.type == "vm"
+ - ans_test_uSeg_10.current.value == "test_vm_identifier_value"
+
+- name: Invalid test - ans_test_uSeg_11 present - attribute_type - vmm_domain and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_11
+ attribute_type: vmm_domain
+ value: test_vmm_domain_value
+ ignore_errors: true
+ register: ans_test_uSeg_11_nt
+
+- name: Invalid test - ans_test_uSeg_11 present - attribute_type - vmm_domain, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_11
+ attribute_type: vmm_domain
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_11_nt1
+
+- name: ans_test_uSeg_11 present - attribute_type - vmm_domain, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_11
+ attribute_type: vmm_domain
+ operator: equals
+ value: test_vmm_domain_value
+ register: ans_test_uSeg_11
+
+- name: Assertions check for add ans_test_uSeg_11 object
+ assert:
+ that:
+ - ans_test_uSeg_11_nt is not changed
+ - ans_test_uSeg_11_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vmm_domain."
+ - ans_test_uSeg_11_nt1 is not changed
+ - ans_test_uSeg_11_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vmm_domain."
+ - ans_test_uSeg_11 is changed
+ - ans_test_uSeg_11.current != {}
+ - ans_test_uSeg_11.previous == {}
+ - ans_test_uSeg_11.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_11.current.name == "ans_test_uSeg_11"
+ - ans_test_uSeg_11.current.type == "domain"
+ - ans_test_uSeg_11.current.value == "test_vmm_domain_value"
+
+- name: Invalid test - ans_test_uSeg_12 present - attribute_type - vm_name and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_12
+ attribute_type: vm_name
+ value: test_vm_value
+ ignore_errors: true
+ register: ans_test_uSeg_12_nt
+
+- name: Invalid test - ans_test_uSeg_12 present - attribute_type - vm_name, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_12
+ attribute_type: vm_name
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_12_nt1
+
+- name: ans_test_uSeg_12 present - attribute_type - vm_name, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_12
+ attribute_type: vm_name
+ operator: equals
+ value: test_vm_value
+ register: ans_test_uSeg_12
+
+- name: Assertions check for add ans_test_uSeg_12 object
+ assert:
+ that:
+ - ans_test_uSeg_12_nt is not changed
+ - ans_test_uSeg_12_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_name."
+ - ans_test_uSeg_12_nt1 is not changed
+ - ans_test_uSeg_12_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vm_name."
+ - ans_test_uSeg_12 is changed
+ - ans_test_uSeg_12.current != {}
+ - ans_test_uSeg_12.previous == {}
+ - ans_test_uSeg_12.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_12.current.name == "ans_test_uSeg_12"
+ - ans_test_uSeg_12.current.type == "vm-name"
+ - ans_test_uSeg_12.current.value == "test_vm_value"
+
+- name: Invalid test - ans_test_uSeg_13 present - attribute_type - vnic_dn and without operator
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ attribute_type: vnic_dn
+ value: test_vnic_dn_value
+ ignore_errors: true
+ register: ans_test_uSeg_13_nt
+
+- name: Invalid test - ans_test_uSeg_13 present - attribute_type - vnic_dn, operator - equals and without value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ attribute_type: vnic_dn
+ operator: equals
+ ignore_errors: true
+ register: ans_test_uSeg_13_nt1
+
+- name: ans_test_uSeg_13 present - attribute_type - vnic_dn, operator - equals and value
+ mso_schema_template_anp_epg_useg_attribute: &ans_test_uSeg_13_present
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ attribute_type: vnic_dn
+ operator: equals
+ value: test_vnic_dn_value
+ register: ans_test_uSeg_13
+
+- name: Assertions check for add ans_test_uSeg_12 object
+ assert:
+ that:
+ - ans_test_uSeg_13_nt is not changed
+ - ans_test_uSeg_13_nt.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vnic_dn."
+ - ans_test_uSeg_13_nt1 is not changed
+ - ans_test_uSeg_13_nt1.msg == "Failed due to invalid 'value' or 'operator' and the attribute_type is{{':'}} vnic_dn."
+ - ans_test_uSeg_13 is changed
+ - ans_test_uSeg_13.current != {}
+ - ans_test_uSeg_13.previous == {}
+ - ans_test_uSeg_13.current.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_13.current.name == "ans_test_uSeg_13"
+ - ans_test_uSeg_13.current.type == "vnic"
+ - ans_test_uSeg_13.current.value == "test_vnic_dn_value"
+
+# Query Part
+- name: Invalid test - Query an uSeg Attr with name - invalid_useg_attr
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: invalid_useg_attr
+ state: query
+ register: invalid_useg_attr
+ ignore_errors: true
+
+- name: Query an uSeg Attr with name - ans_test_uSeg_1
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_6
+ state: query
+ register: query_a_useg_6
+
+- name: Query all uSeg Attrs
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ state: query
+ register: query_all_useg_objects
+
+- name: Assertions check for query uSeg Attr objects
+ assert:
+ that:
+ - invalid_useg_attr is not changed
+ - invalid_useg_attr.msg == "The uSeg Attribute{{':'}} invalid_useg_attr not found."
+ - query_a_useg_6 is not changed
+ - query_a_useg_6.current != {}
+ - query_a_useg_6.current.name == "ans_test_uSeg_6"
+ - query_a_useg_6.current.type == "rootContName"
+ - query_a_useg_6.current.value == "test_vm_datacenter_value"
+ - query_all_useg_objects is not changed
+ - query_all_useg_objects.current | length >= 12
+
+# Update Part
+- name: Update ans_test_uSeg_13 object description and value
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *ans_test_uSeg_13_present
+ description: "ans_test_uSeg_13 updated!"
+ value: test_vnic_dn_value_updated
+ register: ans_test_uSeg_13_update
+
+- name: Query an uSeg Attr with name - ans_test_uSeg_13 to check the updated changes
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_13
+ state: query
+ register: query_a_useg_object_with_name
+
+- name: Assertions check for update ans_test_uSeg_13 object
+ assert:
+ that:
+ - ans_test_uSeg_13_update is changed
+ - ans_test_uSeg_13_update.current != {}
+ - ans_test_uSeg_13_update.current.description == "ans_test_uSeg_13 updated!"
+ - ans_test_uSeg_13_update.current.name == "ans_test_uSeg_13"
+ - ans_test_uSeg_13_update.current.type == "vnic"
+ - ans_test_uSeg_13_update.current.value == "test_vnic_dn_value_updated"
+ - ans_test_uSeg_13_update.previous != {}
+ - ans_test_uSeg_13_update.previous.description == "uSeg Attr object created using Ansible"
+ - ans_test_uSeg_13_update.previous.name == "ans_test_uSeg_13"
+ - ans_test_uSeg_13_update.previous.type == "vnic"
+ - ans_test_uSeg_13_update.previous.value == "test_vnic_dn_value"
+ - query_a_useg_object_with_name is not changed
+ - query_a_useg_object_with_name.current != {}
+ - query_a_useg_object_with_name.current.description == "ans_test_uSeg_13 updated!"
+ - query_a_useg_object_with_name.current.name == "ans_test_uSeg_13"
+ - query_a_useg_object_with_name.current.type == "vnic"
+ - query_a_useg_object_with_name.current.value == "test_vnic_dn_value_updated"
+
+# Cleanup Part
+- name: ans_test_uSeg_1 absent with check mode
+ mso_schema_template_anp_epg_useg_attribute: &ans_test_uSeg_1_cm_absent
+ <<: *useg_attribute_present
+ name: ans_test_uSeg_1
+ state: absent
+ check_mode: true
+ register: ans_test_uSeg_1_cm_absent
+
+- name: ans_test_uSeg_1 absent with normal mode
+ mso_schema_template_anp_epg_useg_attribute: &ans_test_uSeg_1_nm_absent
+ <<: *ans_test_uSeg_1_cm_absent
+ register: ans_test_uSeg_1_nm_absent
+
+- name: ans_test_uSeg_1 absent with normal mode again
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *ans_test_uSeg_1_nm_absent
+ register: ans_test_uSeg_1_nm_absent_again
+
+- name: Assertions check for ans_test_uSeg_1 absent
+ assert:
+ that:
+ - ans_test_uSeg_1_cm_absent is changed
+ - ans_test_uSeg_1_cm_absent.current == {}
+ - ans_test_uSeg_1_cm_absent.previous != {}
+ - ans_test_uSeg_1_nm_absent is changed
+ - ans_test_uSeg_1_nm_absent.current == {}
+ - ans_test_uSeg_1_nm_absent.previous != {}
+ - ans_test_uSeg_1_nm_absent_again is not changed
+ - ans_test_uSeg_1_nm_absent_again.current == {}
+ - ans_test_uSeg_1_nm_absent_again.previous == {}
+
+- name: Query all uSeg Attrs - invalid template name
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ template: ans_test_template_123
+ state: query
+ ignore_errors: true
+ register: query_invalid_template
+
+- name: Query all uSeg Attrs - invalid Application Profile name
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ anp: ans_test_anp_123
+ state: query
+ ignore_errors: true
+ register: query_invalid_ap
+
+- name: Query all uSeg Attrs - invalid EPG name
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ epg: ans_test_epg_123
+ state: query
+ ignore_errors: true
+ register: query_invalid_epg
+
+- name: Invalid test - ans_test_anp_123 present under ans_test_epg_2
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ epg: ans_test_epg_2
+ name: ans_test_anp_123
+ attribute_type: mac
+ value: "AA:BB:CC:DD:EE:FF"
+ ignore_errors: true
+ register: ans_test_epg_2_nt
+
+- name: Assertions check for invalid inputs
+ assert:
+ that:
+ - query_invalid_template is not changed
+ - query_invalid_template.msg is match("Provided template 'ans_test_template_123' not matching existing template.+")
+ - query_invalid_ap is not changed
+ - query_invalid_ap.msg is match("Provided ANP 'ans_test_anp_123' not matching existing anp.+")
+ - query_invalid_epg is not changed
+ - query_invalid_epg.msg is match("Provided EPG 'ans_test_epg_123' not matching existing epg.+")
+ - ans_test_epg_2_nt is not changed
+ - ans_test_epg_2_nt.msg is match("ans_test_epg_2{{':'}} is not a valid uSeg EPG.")
+
+- name: Remove ansible_test schema to delete all uSeg Attr objects
+ mso_schema:
+ <<: *ansible_schema_absent
+ schema: ansible_test
+ state: absent
+
+# To check all uSeg Attrs removed from the machine
+- name: Query all uSeg Attrs - Cleanup Part
+ mso_schema_template_anp_epg_useg_attribute:
+ <<: *useg_attribute_present
+ state: query
+ ignore_errors: true
+ register: query_useg_absent_check
+
+- name: Assertions check for query all uSeg Attrs - Cleanup Part
+ assert:
+ that:
+ - query_useg_absent_check is not changed
+ - query_useg_absent_check.current == {}
+
+- name: Remove ansible_test tenant
+ mso_tenant:
+ <<: *ansible_tenant_present
+ state: absent
+ <<: *mso_info \ No newline at end of file
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/tasks/main.yml
index dbe1bb9e2..7e3ce378c 100644
--- a/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/tasks/main.yml
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/tasks/main.yml
@@ -38,6 +38,15 @@
- '{{ mso_schema | default("ansible_test") }}_2'
- '{{ mso_schema | default("ansible_test") }}'
+- name: Ensure tenant ansible_test exists to validate the invalid_site_mso_site
+ mso_tenant:
+ <<: *mso_info
+ tenant: ansible_test
+ users:
+ - '{{ mso_username }}'
+ state: present
+ register: ansible_test_tenant_present
+
- name: Dissociate clouds that are associated with ansible_tenant
mso_tenant_site:
<<: *mso_info
@@ -45,10 +54,22 @@
site: '{{ item }}'
state: absent
loop:
+ - 'invalid_site_{{ mso_site | default("ansible_test") }}'
- '{{ mso_site | default("ansible_test") }}'
- 'aws_{{ mso_site | default("ansible_test") }}'
- 'azure_{{ mso_site | default("ansible_test") }}'
- ignore_errors: true
+ register: tenant_site_absent_check
+ when: ansible_test_tenant_present.current != {}
+
+- name: Assertion check for the tenant site dissociation
+ assert:
+ that:
+ - tenant_site_absent_check.results.0.current == {}
+ - tenant_site_absent_check.warnings.0 == "Site 'invalid_site_ansible_test' is not a valid site name."
+ - tenant_site_absent_check.results.1.current == {}
+ - tenant_site_absent_check.results.2.current == {}
+ - tenant_site_absent_check.results.3.current == {}
+ when: ansible_test_tenant_present.current != {}
- name: Remove tenant ansible_test
mso_tenant:
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/connection.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/connection.yml
new file mode 100644
index 000000000..9adea3a75
--- /dev/null
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/connection.yml
@@ -0,0 +1,135 @@
+# Test code for the MSO modules
+# Copyright: (c) 2023, Akini Ross (@akinross) <akinross@cisco.com>
+
+# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+- name: Set vars
+ ansible.builtin.set_fact:
+ plugin_query: &plugin_query
+ state: query
+ output_level: debug
+
+- name: Set ansible_connection to ansible.netcommon.httpapi with a wrong domain
+ ansible.builtin.set_fact:
+ ansible_connection: ansible.netcommon.httpapi
+ ansible_httpapi_login_domain: wrong_domain_from_plugin
+
+- name: Reset connection
+ ansible.builtin.meta: reset_connection
+
+- name: Query mso_version with domain from ansible_httpapi_login_domain (error with wrong_domain_from_plugin)
+ cisco.mso.mso_version:
+ <<: *plugin_query
+ register: nm_query_test_domain_plugin
+ ignore_errors: true
+
+- name: Query mso_version with domain overwrite in task (error with wrong_domain_from_task)
+ cisco.mso.mso_version:
+ <<: *plugin_query
+ login_domain: wrong_domain_from_task
+ register: nm_query_wrong_domain_overwrite
+ ignore_errors: true
+
+- name: Query mso_version with domain overwrite in task (test)
+ cisco.mso.mso_version:
+ <<: *plugin_query
+ username: 'r_{{ mso_username }}'
+ login_domain: test
+ register: nm_query_login_domain_overwrite
+
+- name: Unset ansible_httpapi_login_domain
+ ansible.builtin.set_fact:
+ ansible_httpapi_login_domain:
+
+- name: Query mso_version to trigger new login
+ cisco.mso.mso_version:
+ <<: *plugin_query
+
+- name: Query mso_version again thus skipping login
+ cisco.mso.mso_version:
+ <<: *plugin_query
+ register: nm_query_skip_login
+
+- name: Query mso_version with username overwrite in task (error with wrong_username/password)
+ cisco.mso.mso_version:
+ <<: *plugin_query
+ username: wrong_username
+ password: wrong_password
+ register: nm_query_wrong_username_password_overwrite
+ ignore_errors: true
+
+- name: Query mso_version and tigger new login because of changed username and password
+ cisco.mso.mso_version: &new_plugin_query
+ <<: *plugin_query
+ register: nm_query_login_new_username_password
+
+- name: Query mso_version again and tigger new login because of changed username and password
+ cisco.mso.mso_version:
+ <<: *new_plugin_query
+ register: nm_query_login_new_username_password_again
+
+- name: Query mso_version again and overwrite timeout
+ cisco.mso.mso_version:
+ <<: *new_plugin_query
+ timeout: 10
+ register: nm_query_login_new_timeout
+
+- name: Query mso_version again and overwrite use_proxy
+ cisco.mso.mso_version:
+ <<: *new_plugin_query
+ use_proxy: False
+ register: nm_query_login_new_use_proxy_false
+
+- name: Query mso_version again and overwrite use_ssl (error)
+ cisco.mso.mso_version:
+ <<: *new_plugin_query
+ use_ssl: False
+ register: nm_query_login_new_use_ssl_false
+ ignore_errors: true
+
+- name: Query mso_version again and validate_certs (error)
+ cisco.mso.mso_version:
+ <<: *new_plugin_query
+ validate_certs: True
+ register: nm_query_login_new_validate_certs_true
+ ignore_errors: true
+
+- name: Query mso_version again and timeout on with wrong host (error)
+ cisco.mso.mso_version:
+ <<: *new_plugin_query
+ host: '{{ apic_hostname }}'
+ register: nm_query_login_new_wrong_host
+ ignore_errors: true
+
+- name: Verify httpapi plugin tests
+ ansible.builtin.assert:
+ that:
+ - nm_query_login_new_use_ssl_false.msg is search("Connection refused")
+ - nm_query_login_new_validate_certs_true.msg is search("certificate verify failed")
+ - nm_query_login_new_wrong_host.current == {}
+
+- name: Verify httpapi plugin tests
+ ansible.builtin.assert:
+ that:
+ - nm_query_test_domain_plugin.msg == "Login domain 'wrong_domain_from_plugin' is not a valid domain name."
+ - nm_query_wrong_domain_overwrite.msg == "Login domain 'wrong_domain_from_task' is not a valid domain name."
+ - nm_query_login_domain_overwrite.httpapi_logs | length == 8
+ - nm_query_login_domain_overwrite.httpapi_logs.1.1.startswith("set_connection_parameters() - resetting connection due to 'username' change")
+ - nm_query_login_domain_overwrite.httpapi_logs.2.1.startswith("set_connection_parameters() - resetting connection due to 'login_domain' change")
+ - nm_query_login_domain_overwrite.httpapi_logs.3.1 is search("'username'{{':'}} 'r_ansible_github_ci'")
+ - nm_query_login_domain_overwrite.httpapi_logs.3.1 is search("'login_domain'{{':'}} 'test'")
+ - nm_query_login_domain_overwrite.httpapi_logs.3.1 is search("'use_proxy'{{':'}} True")
+ - nm_query_login_domain_overwrite.httpapi_logs.3.1 is search("'use_ssl'{{':'}} True")
+ - nm_query_login_domain_overwrite.httpapi_logs.3.1 is search("'timeout'{{':'}} 300")
+ - nm_query_login_domain_overwrite.httpapi_logs.3.1 is search("'validate_certs'{{':'}} False")
+ - nm_query_skip_login.httpapi_logs | length == 2
+ - nm_query_skip_login.httpapi_logs.1.1.startswith("send_request() - connection.send(/api/v1/platform/version")
+ - nm_query_wrong_username_password_overwrite.msg == "Authentication failed{{':'}} Request failed{{':'}} HTTP Error 401{{':'}} Unauthorized"
+ - nm_query_login_new_username_password.httpapi_logs | length == 8
+ - nm_query_login_new_username_password.httpapi_logs.1.1.startswith("set_connection_parameters() - resetting connection due to 'username' change")
+ - nm_query_login_new_username_password.httpapi_logs.2.1.startswith("set_connection_parameters() - resetting connection due to 'password' change")
+ - nm_query_login_new_username_password_again.httpapi_logs | length == 2
+ - nm_query_login_new_username_password_again.httpapi_logs.1.1.startswith("send_request() - connection.send(/api/v1/platform/version")
+ - nm_query_login_new_timeout.httpapi_logs | length == 3
+ - nm_query_login_new_timeout.httpapi_logs.1.1 is search("'timeout'{{':'}} 10")
+ - nm_query_login_new_use_proxy_false.httpapi_logs.1.1 is search("'use_proxy'{{':'}} False")
diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/main.yml
index 4ee73eb90..fc3eb585e 100644
--- a/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/main.yml
+++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/main.yml
@@ -93,4 +93,11 @@
- query_version_global_params.current.id == cm_query_version.current.id
- query_version_global_params.current.version == cm_query_version.current.version
- query_version_global_params.current.timestamp == cm_query_version.current.timestamp
- when: ansible_connection != 'local' \ No newline at end of file
+ when: ansible_connection != 'local'
+
+# INCLUDE TEST FOR HTTPAPI CONNECTION PLUGIN
+
+- name: Run tests for httpapi connection plugin
+ when: nm_query_version.current.version is version('3.2', '<')
+ include_tasks: connection.yml
+ tags: connection