diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-18 05:52:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-18 05:52:22 +0000 |
commit | 38b7c80217c4e72b1d8988eb1e60bb6e77334114 (patch) | |
tree | 356e9fd3762877d07cde52d21e77070aeff7e789 /ansible_collections/cisco/mso | |
parent | Adding upstream version 7.7.0+dfsg. (diff) | |
download | ansible-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 '')
26 files changed, 2914 insertions, 438 deletions
diff --git a/ansible_collections/cisco/mso/.DS_Store b/ansible_collections/cisco/mso/.DS_Store Binary files differindex 9538dd02f..3406b7dd0 100644 --- a/ansible_collections/cisco/mso/.DS_Store +++ b/ansible_collections/cisco/mso/.DS_Store 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 Binary files differindex 1ffed58d7..7c7d7d98b 100644 --- a/ansible_collections/cisco/mso/plugins/.DS_Store +++ b/ansible_collections/cisco/mso/plugins/.DS_Store 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 Binary files differindex 8249f4cab..ec383e680 100644 --- a/ansible_collections/cisco/mso/tests/.DS_Store +++ b/ansible_collections/cisco/mso/tests/.DS_Store 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 |